[v2,2/2] alsa-mixer: set different strings to name and alsa-name for jack and element

Submitted by Hui Wang on Jan. 14, 2019, 4:24 a.m.

Details

Message ID 20190114042414.1234-3-hui.wang@canonical.com
State New
Series "Handle two Headphone Jacks with the same name"
Headers show

Commit Message

Hui Wang Jan. 14, 2019, 4:24 a.m.
It is possible that we set more than one jacks or elements with the same name
and different index in a {path}.conf, the current code will only generate
one pa_alsa_jack or pa_alsa_element for them regardless of the difference
of index number.

To fix it, we change the rule of naming an element or a jack, let us use
the element as an example, if the index of this element is 0, we don't
set index for it in the {path}.conf and set the element name to xxxx
as before, if the index number is 1, we should set the "index = 1" for
this element in the {path}.conf and set the element name to xxxx@1, then
in the alsa-mixer.c, the "xxxx@1" will be set to the element->name, and
the "xxxx" will be set to the element->alsa_name, we generated the new
element based on the element->name, then this issue is fixed.

Signed-off-by: Hui Wang <hui.wang@canonical.com>
---
 src/modules/alsa/alsa-mixer.c                 | 40 +++++++++++++++----
 src/modules/alsa/alsa-mixer.h                 |  4 +-
 .../mixer/paths/analog-output.conf.common     |  3 +-
 3 files changed, 37 insertions(+), 10 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index e32ec5cd7..b4933e07f 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -100,6 +100,8 @@  static inline int vgfix_get_playback_dB_range(snd_mixer_elem_t *a, long *b, long
 
 #endif
 
+#define SEC_NAME_INDEX_DELIMITER "@"
+
 static int setting_select(pa_alsa_setting *s, snd_mixer_t *m);
 
 struct description_map {
@@ -109,13 +111,17 @@  struct description_map {
 
 pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name) {
     pa_alsa_jack *jack;
+    char *tmp_name;
+    const char *split_state = NULL;
 
     pa_assert(name);
 
     jack = pa_xnew0(pa_alsa_jack, 1);
     jack->path = path;
     jack->name = pa_xstrdup(name);
-    jack->alsa_name = pa_sprintf_malloc("%s Jack", name);
+    tmp_name = pa_split(name, SEC_NAME_INDEX_DELIMITER, &split_state);
+    jack->alsa_name = pa_sprintf_malloc("%s Jack", tmp_name);
+    pa_xfree(tmp_name);
     jack->state_unplugged = PA_AVAILABLE_NO;
     jack->state_plugged = PA_AVAILABLE_YES;
     jack->ucm_devices = pa_dynarray_new(NULL);
@@ -657,6 +663,7 @@  static void element_free(pa_alsa_element *e) {
     if (e->db_fix)
         decibel_fix_free(e->db_fix);
 
+    pa_xfree(e->name);
     pa_xfree(e->alsa_name);
     pa_xfree(e);
 }
@@ -1820,6 +1827,8 @@  static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
 
     if (j->append_pcm_to_name) {
         char *new_name;
+        char *tmp_name;
+        const char *split_state = NULL;
 
         if (!mapping) {
             /* This could also be an assertion, because this should never
@@ -1831,7 +1840,9 @@  static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
             return -1;
         }
 
-        new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index);
+        tmp_name = pa_split(j->name, SEC_NAME_INDEX_DELIMITER, &split_state);
+        new_name = pa_sprintf_malloc("%s,pcm=%i Jack", tmp_name, mapping->hw_device_index);
+        pa_xfree(tmp_name);
         pa_xfree(j->alsa_name);
         j->alsa_name = new_name;
         j->append_pcm_to_name = false;
@@ -1855,6 +1866,8 @@  static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
 
 static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool prefixed) {
     pa_alsa_element *e;
+    char *tmp_name;
+    const char *split_state = NULL;
 
     pa_assert(p);
     pa_assert(section);
@@ -1870,16 +1883,19 @@  static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool p
     if (strchr(section, ':'))
         return NULL;
 
-    if (p->last_element && pa_streq(p->last_element->alsa_name, section))
+    if (p->last_element && pa_streq(p->last_element->name, section))
         return p->last_element;
 
     PA_LLIST_FOREACH(e, p->elements)
-        if (pa_streq(e->alsa_name, section))
+        if (pa_streq(e->name, section))
             goto finish;
 
     e = pa_xnew0(pa_alsa_element, 1);
     e->path = p;
-    e->alsa_name = pa_xstrdup(section);
+    e->name = pa_xstrdup(section);
+    tmp_name = pa_split(section, SEC_NAME_INDEX_DELIMITER, &split_state);
+    e->alsa_name = pa_xstrdup(tmp_name);
+    pa_xfree(tmp_name);
     e->direction = p->direction;
     e->volume_limit = -1;
 
@@ -2692,6 +2708,8 @@  fail:
 pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction) {
     pa_alsa_path *p;
     pa_alsa_element *e;
+    char *tmp_name;
+    const char *split_state = NULL;
 
     pa_assert(element);
 
@@ -2702,7 +2720,10 @@  pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t d
 
     e = pa_xnew0(pa_alsa_element, 1);
     e->path = p;
-    e->alsa_name = pa_xstrdup(element);
+    e->name = pa_xstrdup(element);
+    tmp_name = pa_split(element, SEC_NAME_INDEX_DELIMITER, &split_state);
+    e->alsa_name = pa_xstrdup(tmp_name);
+    pa_xfree(tmp_name);
     e->direction = direction;
     e->volume_limit = -1;
 
@@ -3188,13 +3209,18 @@  pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
         /* Mark all other passed elements for require-absent */
         for (je = en; *je; je++) {
             pa_alsa_element *e;
+	    char *tmp_name;
+	    const char *split_state = NULL;
 
             if (je == ie)
                 continue;
 
             e = pa_xnew0(pa_alsa_element, 1);
             e->path = p;
-            e->alsa_name = pa_xstrdup(*je);
+            e->name = pa_xstrdup(*je);
+            tmp_name = pa_split(*je, SEC_NAME_INDEX_DELIMITER, &split_state);
+            e->alsa_name = pa_xstrdup(tmp_name);
+            pa_xfree(tmp_name);
             e->direction = direction;
             e->required_absent = PA_ALSA_REQUIRED_ANY;
             e->volume_limit = -1;
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 5a8ed03b6..a6d9fce98 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -122,8 +122,8 @@  struct pa_alsa_option {
 struct pa_alsa_element {
     pa_alsa_path *path;
     PA_LLIST_FIELDS(pa_alsa_element);
-
-    char *alsa_name;
+    char *name; /* E g "Headphone@1" if the index is 1*/
+    char *alsa_name; /* E g "Headphone" */
     uint32_t index;
     pa_alsa_direction_t direction;
 
diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common
index 8730ab5a4..a9bc67d76 100644
--- a/src/modules/alsa/mixer/paths/analog-output.conf.common
+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common
@@ -88,7 +88,7 @@ 
 ; [Element ...]                          # For each element that we shall control
 ; index = <the index number>             # If the index number of this Element is not 0, we need to set the correct index number here,
 ;                                        # if it is 0, don't need to set it here
-;
+;                                        # If the index is set to 1 2 ..., the name of this Element should add @1 @2 ... as the suffix [Element xxx@1]
 ; required = ignore | switch | volume | enumeration | any     # If set, require this element to be of this kind and available,
 ;                                                             # otherwise don't consider this path valid for the card
 ; required-any = ignore | switch | volume | enumeration | any # If set, at least one of the elements or jacks with required-any in this
@@ -125,6 +125,7 @@ 
 ;                                      # The name 'Jack Foo' must match ALSA's 'Foo Jack' control.
 ; index = <the index number>           # If the index number of this Jack is not 0, we need to set the correct index number here,
 ;                                      # if it is 0, don't need to set it here
+;                                      # If the index is set to 1 2 ..., the name of this Jack should add @1 @2 ... as the suffix [Jack xxx@1]
 ; required = ignore | any              # If not set to ignore, make the path invalid if this jack control is not present.
 ; required-absent = ignore | any       # If not set to ignore, make the path invalid if this jack control is present.
 ; required-any = ignore | any          # If not set to ignore, make the path invalid if no jack controls and no elements with