mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
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.
This commit is contained in:
parent
e67bc1d752
commit
c2450501af
4 changed files with 75 additions and 11 deletions
|
|
@ -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 (!(elem = snd_mixer_find_selem(mixer, sid)))
|
||||
pa_log_warn("Cannot find fallback mixer control \"%s\".", snd_mixer_selem_id_get_name(sid));
|
||||
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) {
|
||||
|
||||
/* Hmm, so we have both elements, but neither has both mute
|
||||
* and volume. Let's prefer the one with the volume */
|
||||
|
||||
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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue