alsa-mixer: support up to 8 channels per mixer element
authorJaroslav Kysela <perex@perex.cz>
Mon, 4 May 2020 11:04:28 +0000 (13:04 +0200)
committerArun Raghavan <arun@arunraghavan.net>
Tue, 13 Oct 2020 10:27:59 +0000 (10:27 +0000)
We have at least one USB hardware which supports the 8
channels in one mixer element:

  https://github.com/alsa-project/alsa-ucm-conf/pull/25

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/modules/alsa/alsa-mixer.c
src/modules/alsa/alsa-mixer.h

index aa9a57331a6a1df76aadc67fd231ec5a347de84d..0de19846faa64d84437918d8dbebdeb438657fc9 100644 (file)
@@ -1794,16 +1794,16 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
         alsa_id_str(buf, sizeof(buf), &e->alsa_id);
         pa_log_warn("Volume element %s with no channels?", buf);
         return false;
-    } else if (e->n_channels > 2) {
+    } else if (e->n_channels > 8) {
         /* FIXME: In some places code like this is used:
          *
          *     e->masks[alsa_channel_ids[p]][e->n_channels-1]
          *
          * The definition of e->masks is
          *
-         *     pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][2];
+         *     pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][8];
          *
-         * Since the array size is fixed at 2, we obviously
+         * Since the array size is fixed at 8, we obviously
          * don't support elements with more than two
          * channels... */
         alsa_id_str(buf, sizeof(buf), &e->alsa_id);
@@ -2463,7 +2463,7 @@ static pa_channel_position_mask_t parse_mask(const char *m) {
 static int element_parse_override_map(pa_config_parser_state *state) {
     pa_alsa_path *p;
     pa_alsa_element *e;
-    const char *split_state = NULL;
+    const char *split_state = NULL, *s;
     unsigned i = 0;
     char *n;
 
@@ -2489,12 +2489,18 @@ static int element_parse_override_map(pa_config_parser_state *state) {
             }
         }
 
-        if (pa_streq(state->lvalue, "override-map.1"))
-            e->masks[i++][0] = m;
-        else
-            e->masks[i++][1] = m;
+        s = strstr(state->lvalue, ".");
+        if (s) {
+            int idx;
+            pa_atoi(s + 1, &idx);
+            if (idx >= 1 && idx <= 8) {
+                e->masks[i++][idx-1] = m;
+            } else {
+                pa_log("[%s:%u] Override map index '%s' invalid in '%s'", state->filename, state->lineno, state->lvalue, state->section);                
+            }
+        }
 
-        /* Later on we might add override-map.3 and so on here ... */
+        /* Later on we might add override-map.9 and so on here ... */
 
         pa_xfree(n);
     }
index 905e3128b889713ab94171c255c614b2580e0094..250660caff76323d4342b8cf590f4008b85d0060 100644 (file)
@@ -160,7 +160,7 @@ struct pa_alsa_element {
     long volume_limit; /* -1 for no configured limit */
     double min_dB, max_dB;
 
-    pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][2];
+    pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][8];
     unsigned n_channels;
 
     pa_channel_position_mask_t merged_mask;