[PATCH] alsa-ucm: setting default active port based on jacks state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Felipe F. Tonello" <eu@xxxxxxxxxxxxxxxxx>

This fixes a bug when switching profiles under ALSA UCM. If a jack, hence a
port, was previsouly active, when PA performed a profile switch, the jack
would continue to be available but not active.

This patche ensures that it activates a port if a jack is previously connected.

Signed-off-by: Felipe F. Tonello <eu at felipetonello.com>
---
 src/modules/alsa/alsa-sink.c   |  5 +++--
 src/modules/alsa/alsa-source.c |  5 +++--
 src/modules/alsa/alsa-ucm.c    | 34 ++++++++++++++++++++++++++++++++++
 src/modules/alsa/alsa-ucm.h    |  3 +++
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index f910d19..7560b94 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -2281,9 +2281,10 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
-    if (u->ucm_context)
+    if (u->ucm_context) {
         pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card);
-    else if (u->mixer_path_set)
+        pa_alsa_ucm_set_active_port(u->ucm_context, data.ports, &data.active_port);
+    } else if (u->mixer_path_set)
         pa_alsa_add_ports(&data, u->mixer_path_set, card);
 
     u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE | PA_SINK_LATENCY | (u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0) |
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index faf8965..71079d5 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1980,9 +1980,10 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         goto fail;
     }
 
-    if (u->ucm_context)
+    if (u->ucm_context) {
         pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card);
-    else if (u->mixer_path_set)
+        pa_alsa_ucm_set_active_port(u->ucm_context, data.ports, &data.active_port);
+    } else if (u->mixer_path_set)
         pa_alsa_add_ports(&data, u->mixer_path_set, card);
 
     u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0));
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 7f6b9f1..38a80d9 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -969,6 +969,40 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, co
     return ret;
 }
 
+int pa_alsa_ucm_set_active_port(pa_alsa_ucm_mapping_context *context,
+                                pa_hashmap *ports,
+                                char **active_port /* OUT */) {
+    pa_alsa_ucm_config *ucm;
+    pa_alsa_jack *j;
+    pa_device_port *port = NULL;
+    int ret = -1;
+
+    pa_assert(context && context->ucm);
+
+    ucm = context->ucm;
+
+    if (ports)
+        PA_LLIST_FOREACH(j, ucm->jacks) {
+            if ((port = pa_hashmap_get(ports, j->name)))
+                if (j->plugged_in)
+                    break;
+            port = NULL;
+        }
+
+    if (port) {
+        if (!*active_port)
+            *active_port = strdup(port->name);
+        else {
+            /* This case should be rare case, but still */
+            *active_port = realloc(*active_port, (strlen(port->name) * sizeof(char)) + 1);
+            strcpy(*active_port, port->name);
+        }
+        ret = 0;
+    }
+
+    return ret;
+}
+
 int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink) {
     int i;
     int ret = 0;
diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
index c31e5b1..32e1d64 100644
--- a/src/modules/alsa/alsa-ucm.h
+++ b/src/modules/alsa/alsa-ucm.h
@@ -105,6 +105,9 @@ void pa_alsa_ucm_add_ports_combination(
         pa_hashmap *ports,
         pa_card_profile *cp,
         pa_core *core);
+int pa_alsa_ucm_set_active_port(pa_alsa_ucm_mapping_context *context,
+                                pa_hashmap *ports,
+                                char **active_port /* OUT */);
 int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink);
 
 void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
-- 
1.8.3.1



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux