[pulseaudio-discuss] [RFC 2/3] bluetooth: Automatically loopback sinks

Frédéric Dalleau frederic.dalleau at linux.intel.com
Mon Jan 16 10:33:45 PST 2012


---
 src/modules/bluetooth/module-bluetooth-device.c |   62 +++++++++++++++++++++++
 1 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 1d84437..14c5a7f 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -155,6 +155,7 @@ struct userdata {
     pa_card *card;
     pa_sink *sink;
     pa_source *source;
+    uint32_t sink_loop;
     uint32_t source_loop;
 
     pa_thread_mq thread_mq;
@@ -255,9 +256,66 @@ static int loopback_source(struct userdata *u) {
     return 0;
 }
 
+static int loopback_sink(struct userdata *u) {
+    pa_source *defsource;
+    pa_sink *defsink;
+    const char *s;
+    pa_module *m = NULL;
+    char *args;
+
+    pa_assert(u->core);
+    pa_assert(u->sink);
+    pa_assert(u->sink_loop == PA_IDXSET_INVALID);
+
+    /* Don't want to run during startup or shutdown */
+    if (u->core->state != PA_CORE_RUNNING)
+        return -1;
+
+    /* Don't switch to any internal devices */
+    if ((s = pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_BUS))) {
+        if (pa_streq(s, "pci"))
+            return -1;
+        else if (pa_streq(s, "isa"))
+            return -1;
+    }
+
+    /* Do not loopback default source over default sink */
+    defsink = pa_namereg_get_default_sink(u->core);
+    if (defsink == u->sink)
+        return -1;
+
+    /* Find suitable source to loopback */
+    defsource = pa_namereg_get_default_source(u->core);
+    if (!defsource)
+        defsource = defsink->monitor_source;
+
+    if (!defsource) {
+        pa_log_debug("Cannot find suitable source for loopback to %s", u->sink->name);
+        return -1;
+    }
+
+    /* Load module-loopback with default source */
+    args = pa_sprintf_malloc("source=\"%s\" sink=\"%s\" source_dont_move=\"true\"", defsource->name, u->sink->name);
+    m = pa_module_load(u->core, "module-loopback", args);
+
+    if (m) {
+        u->sink_loop = m->index;
+    } else {
+        pa_log_debug("Failed to loopback sink %s with args '%s'", u->sink->name, args);
+        pa_xfree(args);
+    }
+
+    return 0;
+}
+
 static void loopback_stop(struct userdata *u) {
     pa_assert(u->core);
 
+    if (u->sink_loop != PA_IDXSET_INVALID) {
+        pa_module_unload_by_index(u->core, u->sink_loop, TRUE);
+        u->sink_loop = PA_IDXSET_INVALID;
+    }
+
     if (u->source_loop != PA_IDXSET_INVALID) {
         pa_module_unload_by_index(u->core, u->source_loop, TRUE);
         u->source_loop = PA_IDXSET_INVALID;
@@ -2625,6 +2683,9 @@ static int start_thread(struct userdata *u) {
         pa_sink_set_rtpoll(u->sink, u->rtpoll);
         pa_sink_put(u->sink);
 
+        if (u->auto_loopback)
+            loopback_sink(u);
+
         if (u->sink->set_volume)
             u->sink->set_volume(u->sink);
     }
@@ -2981,6 +3042,7 @@ int pa__init(pa_module* m) {
     u->stream_fd = -1;
     u->sample_spec = m->core->default_sample_spec;
     u->modargs = ma;
+    u->sink_loop = PA_IDXSET_INVALID;
     u->source_loop = PA_IDXSET_INVALID;
 
     if (pa_modargs_get_value(ma, "sco_sink", NULL) &&
-- 
1.7.5.4



More information about the pulseaudio-discuss mailing list