On 2011-07-02 19:27, Colin Guthrie wrote: > In order to try and avoid 'spamming' the user with port choices, > attempt to detect and remove any redundant paths in a path set. Hi Colin and thanks for working on this! > This should solve a problem case with some USB Headsets which result in > two paths both using the 'Speaker' element when no 'Master' element exists > (and even in this case, one of those two paths wouldn't really work > anyway due to not actually having h/w volume control due to the absense > of 'Master') Ehm, are you sure this is working? "Analog output" does not control "Speaker" whereas "Analog speaker" does, so how can they turn out to be equal in the code below? > --- > src/modules/alsa/alsa-mixer.c | 46 +++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 46 insertions(+), 0 deletions(-) > > diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c > index abd3bf2..ea5a49d 100644 > --- a/src/modules/alsa/alsa-mixer.c > +++ b/src/modules/alsa/alsa-mixer.c > @@ -2873,6 +2873,51 @@ void pa_alsa_path_set_dump(pa_alsa_path_set *ps) { > pa_alsa_path_dump(p); > } > > +static void path_set_condense(pa_alsa_path_set *ps) { > + pa_alsa_path *p1, *np1, *p2, *np2; > + > + for (p1 = ps->paths; p1; p1 = np1) { > + np1 = p1->next; > + > + for (p2 = p1->next; p2; p2 = np2) { > + pa_alsa_element *e1, *e2; > + pa_bool_t same = TRUE; > + > + np2 = p2->next; > + > + /* Compare the elements of each set... */ > + pa_assert_se(e1 = p1->elements); > + pa_assert_se(e2 = p2->elements); > + > + while (same) { > + if (pa_streq(e1->alsa_name, e2->alsa_name)&& e1->switch_use == e2->switch_use) { > + e1 = e1->next; > + e2 = e2->next; > + if ((e1&& !e2) || (!e1&& e2)) > + same = FALSE; > + else if (!e1&& !e2) > + break; > + } else > + same = FALSE; > + } > + > + if (same) { > + pa_alsa_path *remove_path, *keep_path; > + if (p1->priority>= p2->priority) { > + keep_path = p1; > + remove_path = p2; > + } else { > + keep_path = p2; > + remove_path = p1; > + } > + pa_log_debug("Removing redundant path '%s' as it contains the same elements as '%s' which has higher priority.", remove_path->name, keep_path->name); > + PA_LLIST_REMOVE(pa_alsa_path, ps->paths, remove_path); > + pa_alsa_path_free(remove_path); > + } > + } > + } > +} > + > static void path_set_make_paths_unique(pa_alsa_path_set *ps) { > pa_alsa_path *p, *q; > > @@ -2928,6 +2973,7 @@ void pa_alsa_path_set_probe(pa_alsa_path_set *ps, snd_mixer_t *m, pa_bool_t igno > } > } > > + path_set_condense(ps); > path_set_make_paths_unique(ps); > ps->probed = TRUE; > } -- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic