From 6c53f8707637c7808c9d1e5bcfaca5d9ea72c9ab Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Apr 01 2005 22:25:04 +0000 Subject: change the alsa dev.d script that runs on udev add events to a program that: a) runs alsactl restore if there is a saved config b) unmutes playback channels if there isn't #132575 --- diff --git a/alsa-utils.spec b/alsa-utils.spec index 72d123f..aa0e4ea 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -1,12 +1,12 @@ Summary: Advanced Linux Sound Architecture (ALSA) utilities Name: alsa-utils Version: 1.0.8 -Release: 3 +Release: 4 License: GPL Group: Applications/Multimedia URL: http://www.alsa-project.org/ Source: ftp://ftp.alsa-project.org/pub/utils/alsa-utils-%{version}%{?prever}.tar.bz2 -Source2: alsa.dev +Source2: salsa.c #Source3: xinit-alsa-launch.sh #Patch1: alsa-utils-1.0.7-alsa-launch.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -28,6 +28,7 @@ Architecture (ALSA). autoreconf -f -i %configure CFLAGS="$RPM_OPT_FLAGS" --sbindir=/sbin %{__make} %{?_smp_mflags} +%{__cc} $RPM_OPT_FLAGS -o salsa %{SOURCE2} -lasound %install %{__rm} -rf ${RPM_BUILD_ROOT} @@ -40,7 +41,7 @@ mkdir -p $RPM_BUILD_ROOT/%{_sbindir} ln -s ../../sbin/alsactl $RPM_BUILD_ROOT/%{_sbindir}/alsactl mkdir -p -m755 $RPM_BUILD_ROOT/etc/dev.d/sound -install -m 755 %{SOURCE2} $RPM_BUILD_ROOT/etc/dev.d/sound/alsa.dev +install -m 755 salsa $RPM_BUILD_ROOT/etc/dev.d/sound/alsa.dev %clean %{__rm} -rf $RPM_BUILD_ROOT @@ -59,6 +60,11 @@ install -m 755 %{SOURCE2} $RPM_BUILD_ROOT/etc/dev.d/sound/alsa.dev %changelog +* Fri Apr 1 2005 Bill Nottingham 1.0.8-4 +- replace the dev.d script with a program that calls alsactl to + restore the volume if there is a saved config, and just unmutes + the playback channels if there isn't one (#132575) + * Mon Mar 7 2005 Martin Stransky - rebuilt diff --git a/salsa.c b/salsa.c new file mode 100644 index 0000000..dd764ca --- /dev/null +++ b/salsa.c @@ -0,0 +1,147 @@ + +#include +#include +#include + +#include + +#define ALSA_CONFIG_PATH "/etc/asound.state" + +int get_card_number() +{ + char *devname, *action; + + action = getenv("ACTION"); + if (!action || strcmp(action,"add")) + return -1; + devname = getenv("DEVNAME"); + if (!devname) + return -1; + if (!strncmp(devname,"/dev/snd/controlC",17)) + return atoi(devname+17); + if (!strncmp(devname,"/dev/snd/pcmC",13)) + return atoi(devname+13); + return -1; +} + +int has_config(int index) +{ + int rc = 0; + snd_config_t *config, *control; + snd_input_t *in; + snd_ctl_t *handle; + snd_ctl_card_info_t *info; + const char *id; + char path[32]; + + rc = snd_config_top(&config); + if (rc < 0) + goto out; + rc = snd_input_stdio_open(&in, ALSA_CONFIG_PATH, "r"); + if (rc >= 0) { + rc = snd_config_load(config, in); + snd_input_close(in); + if (rc < 0) + goto out; + } + sprintf(path, "hw:%d", index); + rc = snd_ctl_open(&handle, path, 0); + if (rc < 0) + goto out; + snd_ctl_card_info_alloca(&info); + rc = snd_ctl_card_info(handle, info); + if (rc < 0) + goto out_close; + id = snd_ctl_card_info_get_id(info); + rc = snd_config_searchv(config, &control, "state", id, "control", 0); +out_close: + snd_ctl_close(handle); +out: + return !rc; + +} + +int run_alsactl(int index) +{ + char *args[] = { "/sbin/alsactl", "restore", NULL, NULL }; + char num[10]; + + sprintf(num,"%d",index); + args[2] = num; + execv(args[0],args); + return 1; +} + +int frob_mixer(int index) +{ + int rc = 0; + char card[32]; + snd_mixer_t *handle; + snd_mixer_selem_id_t *sid; + snd_mixer_elem_t *elem; + snd_mixer_selem_id_alloca(&sid); + + sprintf(card,"hw:%d",index); + if ((rc = snd_mixer_open(&handle, 0)) < 0) { + return rc; + } + if ((rc = snd_mixer_attach(handle, card)) < 0) { + goto out; + } + if ((rc = snd_mixer_selem_register(handle, NULL, NULL)) < 0) { + goto out; + } + rc = snd_mixer_load(handle); + if (rc < 0) { + goto out; + } + for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) { + long pmin, pmax; + int c; + + snd_mixer_selem_get_id(elem, sid); + snd_mixer_selem_get_playback_volume_range(elem, &pmin, &pmax); + for (c = 0; c < SND_MIXER_SCHN_LAST; c++) { + if (snd_mixer_selem_has_capture_channel(elem, c)) { + if (snd_mixer_selem_has_capture_volume(elem)) + snd_mixer_selem_set_capture_volume(elem, c, 0); + if (!strcmp(snd_mixer_selem_id_get_name(sid),"CD")) { + if (snd_mixer_selem_has_capture_switch(elem)) + snd_mixer_selem_set_capture_switch(elem, c, 1); + } else { + if (snd_mixer_selem_has_capture_switch(elem)) + snd_mixer_selem_set_capture_switch(elem, c, 0); + if (snd_mixer_selem_has_playback_switch(elem)) + snd_mixer_selem_set_playback_switch(elem, c, 0); + if (snd_mixer_selem_has_playback_volume(elem)) + snd_mixer_selem_set_playback_volume(elem, c, 0); + } + } + if (snd_mixer_selem_has_playback_channel(elem, c)) { + if (!snd_mixer_selem_has_capture_channel(elem, c) || + !strcmp(snd_mixer_selem_id_get_name(sid),"CD")) { + if (snd_mixer_selem_has_playback_switch(elem)) + snd_mixer_selem_set_playback_switch(elem, c, 1); + if (snd_mixer_selem_has_playback_volume(elem)) + snd_mixer_selem_set_playback_volume(elem, c, pmin + (pmax - pmin) * 0.75); + } + } + } + } +out: + snd_mixer_close(handle); + return rc; +} + +int main(int argc, char **argv) +{ + int i; + + i = get_card_number(); + if (i < 0) + return 0; + if (has_config(i)) + return run_alsactl(i); + else + return frob_mixer(i); +}