From dc9dc70fcc1b06788d08b5e7997c9053a13cbce2 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 26 Nov 2019 10:54:15 +0100 Subject: [PATCH] alsa-ucm: use the correct mixer identifiers as first The mixer identifiers should be used for snd_mixer_selem API. Use them as first, then try to fallback to the raw control identifiers. Signed-off-by: Jaroslav Kysela --- src/modules/alsa/alsa-ucm.c | 78 ++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c index a812b52f449e..65ec6941e8de 100644 --- a/src/modules/alsa/alsa-ucm.c +++ b/src/modules/alsa/alsa-ucm.c @@ -200,6 +200,50 @@ static void ucm_add_devices_to_idxset( } } +/* Get the volume identifier */ +static char *ucm_get_mixer_id( + pa_alsa_ucm_device *device, + const char *mprop, + const char *cprop, + const char *cid) +{ +#if SND_LIB_VERSION >= 0x10201 + snd_ctl_elem_id_t *ctl; + int err; +#endif + const char *value; + char *value2; + int index; + + value = pa_proplist_gets(device->proplist, mprop); + if (value) + return pa_xstrdup(value); + value = pa_proplist_gets(device->proplist, cprop); + if (value == NULL) + return NULL; +#if SND_LIB_VERSION >= 0x10201 + snd_ctl_elem_id_alloca(&ctl); + err = snd_use_case_parse_ctl_elem_id(ctl, cid, value); + if (err < 0) + return NULL; + value = snd_ctl_elem_id_get_name(ctl); + index = snd_ctl_elem_id_get_index(ctl); +#else +#warning "Upgrade to alsa-lib 1.2.1!" + index = 0; +#endif + if (!(value2 = pa_str_strip_suffix(value, " Playback Volume"))) + if (!(value2 = pa_str_strip_suffix(value, " Capture Volume"))) + if (!(value2 = pa_str_strip_suffix(value, " Volume"))) + value2 = pa_xstrdup(value); + if (index > 0) { + char *mix = pa_sprintf_malloc("'%s',%d", value2, index); + pa_xfree(value2); + return mix; + } + return value2; +} + /* Create a property list for this ucm device */ static int ucm_get_device_property( pa_alsa_ucm_device *device, @@ -296,17 +340,12 @@ static int ucm_get_device_property( pa_log_debug("UCM playback priority %s for device %s error", value, device_name); } - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_VOLUME); - if (value) { - /* Try to get the simple control name, and failing that, just use the name as is */ - char *selem; - - if (!(selem = pa_str_strip_suffix(value, " Playback Volume"))) - if (!(selem = pa_str_strip_suffix(value, " Volume"))) - selem = pa_xstrdup(value); - - pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); - } + value = ucm_get_mixer_id(device, + PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM, + PA_ALSA_PROP_UCM_PLAYBACK_VOLUME, + "PlaybackVolume"); + if (value) + pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); } if (device->capture_channels) { /* source device */ @@ -329,17 +368,12 @@ static int ucm_get_device_property( pa_log_debug("UCM capture priority %s for device %s error", value, device_name); } - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_VOLUME); - if (value) { - /* Try to get the simple control name, and failing that, just use the name as is */ - char *selem; - - if (!(selem = pa_str_strip_suffix(value, " Capture Volume"))) - if (!(selem = pa_str_strip_suffix(value, " Volume"))) - selem = pa_xstrdup(value); - - pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); - } + value = ucm_get_mixer_id(device, + PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM, + PA_ALSA_PROP_UCM_CAPTURE_VOLUME, + "CaptureVolume"); + if (value) + pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); } if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) { -- 2.16.4