diff options
author | Lennart Poettering <lennart@poettering.net> | 2009-01-08 01:03:42 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-01-08 01:03:42 +0100 |
commit | c2450501af82d1c9d1994e4f4ce80d506d3c90ae (patch) | |
tree | dc443a4862811e03663aa92b2f0ffb45b26b2f58 /src/modules | |
parent | e67bc1d752f768efb556b57aff8be4e1d82b173b (diff) |
Prefer mixer controls with volumes over switches
When we look for a mixer control prefer controls that have both volume
and a mute switch over those that have only a volume switch over those
that only have a mute switch.
Originally pointed out by Adel Gadllah.
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/alsa-util.c | 80 | ||||
-rw-r--r-- | src/modules/alsa-util.h | 2 | ||||
-rw-r--r-- | src/modules/module-alsa-sink.c | 2 | ||||
-rw-r--r-- | src/modules/module-alsa-source.c | 2 |
4 files changed, 75 insertions, 11 deletions
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 75b84c40..ff3af19d 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -760,8 +760,32 @@ int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) { return 0; } -snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback) { - snd_mixer_elem_t *elem; +static pa_bool_t elem_has_volume(snd_mixer_elem_t *elem, pa_bool_t playback) { + pa_assert(elem); + + if (playback && snd_mixer_selem_has_playback_volume(elem)) + return TRUE; + + if (!playback && snd_mixer_selem_has_capture_volume(elem)) + return TRUE; + + return FALSE; +} + +static pa_bool_t elem_has_switch(snd_mixer_elem_t *elem, pa_bool_t playback) { + pa_assert(elem); + + if (playback && snd_mixer_selem_has_playback_switch(elem)) + return TRUE; + + if (!playback && snd_mixer_selem_has_capture_switch(elem)) + return TRUE; + + return FALSE; +} + +snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback) { + snd_mixer_elem_t *elem = NULL, *fallback_elem = NULL; snd_mixer_selem_id_t *sid = NULL; snd_mixer_selem_id_alloca(&sid); @@ -771,17 +795,57 @@ snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const snd_mixer_selem_id_set_name(sid, name); - if (!(elem = snd_mixer_find_selem(mixer, sid))) { - pa_log_info("Cannot find mixer control \"%s\".", snd_mixer_selem_id_get_name(sid)); + if ((elem = snd_mixer_find_selem(mixer, sid))) { + + if (elem_has_volume(elem, playback) && + elem_has_switch(elem, playback)) + goto success; + + if (!elem_has_volume(elem, playback) && + !elem_has_switch(elem, playback)) + elem = NULL; + } + + pa_log_info("Cannot find mixer control \"%s\" or mixer control is no combination of switch/volume.", snd_mixer_selem_id_get_name(sid)); + + if (fallback) { + snd_mixer_selem_id_set_name(sid, fallback); + + if ((fallback_elem = snd_mixer_find_selem(mixer, sid))) { + + if (elem_has_volume(fallback_elem, playback) && + elem_has_switch(fallback_elem, playback)) { + elem = fallback_elem; + goto success; + } + + if (!elem_has_volume(fallback_elem, playback) && + !elem_has_switch(fallback_elem, playback)) + fallback_elem = NULL; + } + + pa_log_warn("Cannot find fallback mixer control \"%s\" or mixer control is no combination of switch/volume.", snd_mixer_selem_id_get_name(sid)); + } + + if (elem && fallback_elem) { - if (fallback) { - snd_mixer_selem_id_set_name(sid, fallback); + /* Hmm, so we have both elements, but neither has both mute + * and volume. Let's prefer the one with the volume */ - if (!(elem = snd_mixer_find_selem(mixer, sid))) - pa_log_warn("Cannot find fallback mixer control \"%s\".", snd_mixer_selem_id_get_name(sid)); + if (elem_has_volume(elem, playback)) + goto success; + + if (elem_has_volume(fallback_elem, playback)) { + elem = fallback_elem; + goto success; } } + if (!elem && fallback_elem) + elem = fallback_elem; + +success: + if (elem) pa_log_info("Using mixer control \"%s\".", snd_mixer_selem_id_get_name(sid)); diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index aaa01c78..95bb983a 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -52,7 +52,7 @@ int pa_alsa_set_hw_params( int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min); int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev); -snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback); +snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback); snd_pcm_t *pa_alsa_open_by_device_id( const char *dev_id, diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 6dea172f..95a8c972 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -1409,7 +1409,7 @@ int pa__init(pa_module*m) { } if (found) - if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM"))) + if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM", TRUE))) found = FALSE; if (!found) { diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index f796ef14..b6c6ed1a 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -1236,7 +1236,7 @@ int pa__init(pa_module*m) { } if (found) - if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic"))) + if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic", FALSE))) found = FALSE; if (!found) { |