Tanu, Does this look right for the left over bits.... I appreciate it may actually make sense to do David's off+zero -> constant thing as it would keep some of the comparison bit much simpler, but this is an optimisation we can do after 1.0 is out :) In the mean time: diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 20e6194..9470ecf 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2911,9 +2911,10 @@ static pa_bool_t enumeration_is_subset(pa_alsa_option *a_options, pa_alsa_option /** * Compares two elements to see if a is a subset of b */ -static pa_bool_t element_is_subset(pa_alsa_element *a, pa_alsa_element *b) { +static pa_bool_t element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_t *m) { pa_assert(a); pa_assert(b); + pa_assert(m); /* General rules: * Every state is a subset of itself (with caveats for volume_limits and options) @@ -2938,10 +2939,29 @@ static pa_bool_t element_is_subset(pa_alsa_element *a, pa_alsa_element *b) { if (a->volume_use == PA_ALSA_VOLUME_CONSTANT) a_limit = a->constant_volume; else if (a->volume_use == PA_ALSA_VOLUME_ZERO) { - /* (tk) This is wrong.a_limit should be what - snd_mixer_selem_ask_playback_dB_vol() returns, or if a->db_fix is set, - then what decibel_fix_get_step() returns. */ - a_limit = a->min_volume; + long dB = 0; + + if (a->db_fix) { + int rounding = (a->direction == PA_ALSA_DIRECTION_OUTPUT ? +1 : -1); + a_limit = decibel_fix_get_step(a->db_fix, &dB, rounding); + } else { + snd_mixer_selem_id_t *sid; + snd_mixer_elem_t *me; + + SELEM_INIT(sid, a->alsa_name); + if (!(me = snd_mixer_find_selem(m, sid))) { + pa_log_warn("Element %s seems to have disappeared.", a->alsa_name); + return FALSE; + } + + if (a->direction == PA_ALSA_DIRECTION_OUTPUT) { + if (snd_mixer_selem_ask_playback_dB_vol(me, dB, +1, &a_limit) < 0) + return FALSE; + } else { + if (snd_mixer_selem_ask_capture_dB_vol(me, dB, -1, &a_limit) < 0) + return FALSE; + } + } } else if (a->volume_use == PA_ALSA_VOLUME_OFF) a_limit = a->min_volume; else if (a->volume_use == PA_ALSA_VOLUME_MERGE) @@ -2988,9 +3008,12 @@ static pa_bool_t element_is_subset(pa_alsa_element *a, pa_alsa_element *b) { return TRUE; } -static void path_set_condense(pa_alsa_path_set *ps) { +static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) { pa_alsa_path *p, *np; + pa_assert(ps); + pa_assert(m); + /* If we only have one path, then don't bother */ if (!ps->paths || !ps->paths->next) return; @@ -3012,7 +3035,7 @@ static void path_set_condense(pa_alsa_path_set *ps) { while (is_subset) { if (pa_streq(ea->alsa_name, eb->alsa_name)) { - if (element_is_subset(ea, eb)) { + if (element_is_subset(ea, eb, m)) { ea = ea->next; eb = eb->next; if ((ea && !eb) || (!ea && eb)) @@ -3094,7 +3117,7 @@ void pa_alsa_path_set_probe(pa_alsa_path_set *ps, snd_mixer_t *m, pa_bool_t igno pa_log_debug("Found mixer paths (before tidying):"); pa_alsa_path_set_dump(ps); - path_set_condense(ps); + path_set_condense(ps, m); path_set_make_paths_unique(ps); ps->probed = TRUE; -- Colin Guthrie gmane(at)colin.guthr.ie http://colin.guthr.ie/ Day Job: Tribalogic Limited [http://www.tribalogic.net/] Open Source: Mageia Contributor [http://www.mageia.org/] PulseAudio Hacker [http://www.pulseaudio.org/] Trac Hacker [http://trac.edgewall.org/]