alsactl init - CTL{values}, CTL{enums} and default "guess method" initialization

Implemented CTL{values)=value to set all values at once.
Implemented CTL{enums} to match against strings in enum list.
Added 'default' (guess method) initialization configuration.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2008-08-18 15:01:44 +02:00
parent 0c02a4e3d2
commit 9a748178d1
5 changed files with 212 additions and 17 deletions

View file

@ -257,6 +257,12 @@
<para>Enumerated value - number of text items</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>enums</option></term>
<listitem>
<para>Enumerated value - list of text names stored between '|' character</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>value</option></term>
<listitem>
@ -394,6 +400,16 @@
next key on line).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>CTL{values}</option></term>
<listitem>
<para>Value is set (written) also to soundcard's control
device (all control values are set to specified value) and
RESULT key is set to errno code. The result of
set operation is always true (it means continue with
next key on line).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>ENV{<replaceable>key</replaceable>}</option></term>

View file

@ -7,6 +7,7 @@ CONFIG{sysfs_device}="/class/sound/controlC$cardinfo{card}/device"
# test for extra commands
ENV{CMD}=="help", INCLUDE="help", GOTO="00main_end"
ENV{CMD}=="info", INCLUDE="info", GOTO="00main_end"
ENV{CMD}=="default", INCLUDE="default", GOTO="00main_end"
ENV{CMD}=="test", INCLUDE="test", GOTO="00main_end"
ENV{CMD}=="*", ERROR="Unknown command '$env{CMD}'\n", GOTO="00main_end"
@ -17,7 +18,8 @@ ENV{CMD}=="*", ERROR="Unknown command '$env{CMD}'\n", GOTO="00main_end"
# 2) if RESULT=="skip", skip ALSA standard configuration files
# 3) do ALSA standard configuration
# 4) look for postinit subdirectory and parse all files in it
# 5) if RESULT!="true", print an error message and return with exit code 99
# 5) if RESULT!="true", initialize hardware using a guess method,
# print an error message and return with exit code 99
# 6) return with exit code 0 (success)
#
@ -33,7 +35,8 @@ LABEL="init_end"
ACCESS=="postinit", INCLUDE="postinit"
RESULT=="true", GOTO="00_mainend"
ERROR="Unknown hardware: \"$cardinfo{driver}\" \"$cardinfo{mixername}\" \"$cardinfo{components}\" \"$attr{subsystem_vendor}\" \"$attr{subsystem_device}\"\n"
ERROR="Hardware is left uninitialized\n"
ERROR="Hardware is initialized using a guess method\n"
INCLUDE="default"
EXIT="99"
#

145
alsactl/init/default Normal file
View file

@ -0,0 +1,145 @@
#
# Default ALSA volume levels and setting when initialization database fails.
#
# Basic rules are:
# - keep volumes at minimal level, but sound should be hearable
# - enable just main speakers for playback and main microphone for recording
#
# **************************************************************************
# playback
# **************************************************************************
ENV{volume}:="-20dB"
CTL{reset}="mixer"
CTL{name}="Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Master Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Master Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Master Digital Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Master Digital Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Front Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Front Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Headphone Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Headphone Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Speaker Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Speaker Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="PC Speaker Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="PC Speaker Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="PCM Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="PCM Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="PCM Playback Volume",CTL{index}="1",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="PCM Playback Switch",CTL{index}="1",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="DAC Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="DAC Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Synth Playback Volume",,PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Synth Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Wave Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="100%"
CTL{name}="Wave Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Music Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="100%"
CTL{name}="Music Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="CD Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="CD Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Mono Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Mono Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="Master Mono Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Master Mono Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{reset}="mixer"
CTL{name}="AC97 Playback Volume",PROGRAM=="__ctl_search", \
CTL{values}="100%"
CTL{name}="AC97 Playback Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
#
# Powermacs
#
CTL{reset}="mixer"
CTL{name}="DRC Range",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
# **************************************************************************
# capture
# **************************************************************************
ENV{volume}:="20dB"
CTL{reset}="mixer"
CTL{name}="Capture Volume",PROGRAM=="__ctl_search", \
CTL{values}="$env{volume}",RESULT!="0",CTL{values}="75%"
CTL{name}="Capture Switch",PROGRAM=="__ctl_search", \
CTL{values}="on"
CTL{name}="Input Source",PROGRAM=="__ctl_search", \
CTL{enums}=="*|Internal Mic|*",CTL{values}="Internal Mic", \
GOTO="end_input_source"
CTL{name}="Input Source",PROGRAM=="__ctl_search", \
CTL{enums}=="*|Mic|*",CTL{values}="Mic"
LABEL="end_input_source"
CTL{name}="Internal Mic Boost",PROGRAM=="__ctl_search", \
CTL{values}="on"

View file

@ -58,7 +58,6 @@ PRINT=" CTL{device}=\"$ctl{device}\"\n"
PRINT=" CTL{subdevice}=\"$ctl{subdevice}\"\n"
PRINT=" CTL{name}=\"$ctl{name}\"\n"
PRINT=" CTL{index}=\"$ctl{index}\"\n"
LABEL="skip_switch_search"
PRINT="First ten elements:\n"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 0", GOTO="skip_first_ten_search"
@ -118,7 +117,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 3", GOTO="skip_first_ten_search"
PRINT=" Element #3:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -138,7 +136,6 @@ PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{step}=\"$ctl{step}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 4", GOTO="skip_first_ten_search"
PRINT=" Element #4:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -158,7 +155,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 5", GOTO="skip_first_ten_search"
PRINT=" Element #5:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -178,7 +174,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 6", GOTO="skip_first_ten_search"
PRINT=" Element #6:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -198,7 +193,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 7", GOTO="skip_first_ten_search"
PRINT=" Element #7:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -218,7 +212,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 8", GOTO="skip_first_ten_search"
PRINT=" Element #8:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -238,7 +231,6 @@ PRINT=" CTL{dBmin}=\"$ctl{dBmin}\"\n"
PRINT=" CTL{dBmax}=\"$ctl{dBmax}\"\n"
PRINT=" CTL{items}=\"$ctl{items}\"\n"
PRINT=" CTL{value}=\"$ctl{value}\"\n"
LABEL="skip_first_ten_search"
CTL{search}="mixer", CTL{name}="*", PROGRAM!="__ctl_search 9", GOTO="skip_first_ten_search"
PRINT=" Element #9:\n"
PRINT=" CTL{numid}=\"$ctl{numid}\"\n"
@ -270,7 +262,9 @@ PRINT="Elements write test #2:\n", \
PRINT=" result=$result\n"
PRINT="Elements write test #3:\n", \
CTL{search}="mixer", CTL{name}="Front Playback Volume Error", \
PROGRAM="__ctl_search", CTL{value}="32,32", \
PRINT=" result=$result\n"
PROGRAM="__ctl_search"
PRINT=" result=$result\n"
#CTL{reset}="mixer", CTL{name}="Input Source", PRINT="***$ctl{enums}\n"
PRINT="\nAll tests done..\n"

View file

@ -335,7 +335,7 @@ static const char *get_ctl_value(struct space *space)
#define convert_prange1(val, min, max) \
ceil((val) * ((max) - (min)) * 0.01 + (min))
static int set_ctl_value(struct space *space, const char *value)
static int set_ctl_value(struct space *space, const char *value, int all)
{
snd_ctl_elem_type_t type;
unsigned int idx, idx2, count, items;
@ -358,6 +358,8 @@ static int set_ctl_value(struct space *space, const char *value)
strncasecmp(value, "on", 2) == 0 ||
strncasecmp(value, "1", 1) == 0;
snd_ctl_elem_value_set_boolean(space->ctl_value, idx, val);
if (all)
continue;
pos = strchr(value, ',');
value = pos ? pos + 1 : value + strlen(value) - 1;
}
@ -398,6 +400,8 @@ static int set_ctl_value(struct space *space, const char *value)
} else {
snd_ctl_elem_value_set_integer(space->ctl_value, idx, strtol(value, NULL, 0));
}
if (all)
continue;
value = pos ? pos + 1 : value + strlen(value) - 1;
}
break;
@ -406,6 +410,8 @@ static int set_ctl_value(struct space *space, const char *value)
while (*value == ' ')
value++;
snd_ctl_elem_value_set_integer64(space->ctl_value, idx, strtoll(value, NULL, 0));
if (all)
continue;
pos = strchr(value, ',');
value = pos ? pos + 1 : value + strlen(value) - 1;
}
@ -440,6 +446,8 @@ static int set_ctl_value(struct space *space, const char *value)
return -EINVAL;
}
}
if (all)
continue;
value = pos ? pos + 1 : value + strlen(value) - 1;
}
break;
@ -478,7 +486,7 @@ static const char *elemid_get(struct space *space, const char *attr)
{
long long val;
snd_ctl_elem_type_t type;
static char res[32];
static char res[256];
if (strncasecmp(attr, "numid", 5) == 0) {
val = snd_ctl_elem_id_get_numid(space->ctl_id);
@ -617,6 +625,27 @@ dbvalue:
val = max;
goto dbvalue;
}
if (strncasecmp(attr, "enums", 5) == 0) {
unsigned int idx, items;
snd_hctl_elem_t *elem;
if (check_id_changed(space, 1))
return NULL;
if (snd_ctl_elem_info_get_type(space->ctl_info) != SND_CTL_ELEM_TYPE_ENUMERATED)
goto empty;
items = snd_ctl_elem_info_get_items(space->ctl_info);
strcpy(res, "|");
for (idx = 0; idx < items; idx++) {
snd_ctl_elem_info_set_item(space->ctl_info, idx);
elem = snd_hctl_find_elem(space->ctl_handle, space->ctl_id);
if (elem == NULL)
break;
if (snd_hctl_elem_info(elem, space->ctl_info) < 0)
break;
strlcat(res, snd_ctl_elem_info_get_item_name(space->ctl_info), sizeof(res));
strlcat(res, "|", sizeof(res));
}
return res;
}
Perror(space, "unknown ctl{} attribute '%s'", attr);
return NULL;
value:
@ -684,13 +713,14 @@ static int elemid_set(struct space *space, const char *attr, const char *value)
fcn = snd_ctl_elem_id_set_index;
goto value;
}
if (strncasecmp(attr, "value", 5) == 0) {
if (strncasecmp(attr, "values", 6) == 0 ||
strncasecmp(attr, "value", 5) == 0) {
err = check_id_changed(space, 1);
if (err < 0) {
Perror(space, "control element not found");
return err;
}
err = set_ctl_value(space, value);
err = set_ctl_value(space, value, strncasecmp(attr, "values", 6) == 0);
if (err < 0) {
space->ctl_id_changed |= 2;
} else {
@ -1244,7 +1274,7 @@ static int parse_line(struct space *space, char *line, size_t linesize)
err = get_key(&linepos, &key, &op, &value);
if (err < 0)
break;
goto invalid;
if (strncasecmp(key, "LABEL", 5) == 0) {
if (op != KEY_OP_ASSIGN) {
@ -1392,6 +1422,13 @@ static int parse_line(struct space *space, char *line, size_t linesize)
dbg("env: '%s' '%s'", attr, temp);
if (!do_match(key, op, value, temp))
break;
} else if (op == KEY_OP_ASSIGN ||
op == KEY_OP_ASSIGN_FINAL) {
strlcpy(result, value, sizeof(result));
apply_format(space, result, sizeof(result));
dbg("env set: '%s' '%s'", attr, result);
if (setenv(attr, result, op == KEY_OP_ASSIGN_FINAL))
break;
} else {
Perror(space, "invalid ENV{} operation");
goto invalid;