summaryrefslogtreecommitdiffstats
path: root/loopback.c
diff options
context:
space:
mode:
Diffstat (limited to 'loopback.c')
-rw-r--r--loopback.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/loopback.c b/loopback.c
new file mode 100644
index 0000000..5b07ef7
--- /dev/null
+++ b/loopback.c
@@ -0,0 +1,112 @@
+/*
+ * module-agl-audio -- PulseAudio module for providing audio routing support
+ * (forked from "module-murphy-ivi" - https://github.com/otcshare )
+ * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2016, IoT.bzh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ */
+#include "loopback.h"
+#include "utils.h"
+#include "list.h"
+
+pa_loopback *pa_loopback_init (void)
+{
+ pa_loopback *loopback = pa_xnew0 (pa_loopback, 1);
+
+ return loopback;
+}
+
+void pa_loopback_done (struct userdata *u, pa_loopback *loopback)
+{
+ pa_loopnode *loop, *n;
+ pa_core *core;
+
+ pa_assert_se (core = u->core);
+
+ PA_LLIST_FOREACH_SAFE(loop, n, loopback->loopnodes) {
+ pa_module_unload_by_index(core, loop->module_index, false);
+ }
+}
+
+pa_loopnode *pa_loopnode_create (struct userdata *u, pa_loopnode_type type,
+ uint32_t node_index, uint32_t source_index, uint32_t sink_index)
+{
+ pa_core *core;
+ pa_module *module;
+ pa_source *source;
+ pa_sink *sink;
+ const char *sonam;
+ const char *sinam;
+ pa_source_output *sout;
+ pa_sink_input *sinp;
+ pa_loopnode *loopnode;
+ int idx;
+ char args[256];
+
+ pa_assert (u);
+ pa_assert_se (core = u->core);
+
+ source = pa_idxset_get_by_index (core->sources, source_index);
+ sonam = pa_utils_get_source_name (source);
+ sink = pa_idxset_get_by_index (core->sinks, sink_index);
+ sinam = pa_utils_get_sink_name (sink);
+
+ snprintf (args, sizeof(args), "source=\"%s\" sink=\"%s\"", sonam, sinam);
+ module = pa_module_load (core, "module-loopback", args);
+
+ if (!module) {
+ pa_log ("failed to load loopback for source '%s' & sink '%s'", sonam, sinam);
+ return NULL;
+ }
+
+ /* find the sink_input/source_output couple generated but the module we just loaded */
+ PA_IDXSET_FOREACH(sout, core->source_outputs, idx) {
+ if (sout->module && sout->module == module)
+ break;
+ sout = NULL;
+ }
+ PA_IDXSET_FOREACH(sinp, core->sink_inputs, idx) {
+ if (sinp->module && sinp->module == module)
+ break;
+ sinp = NULL;
+ }
+ if (!sout || !sinp) {
+ pa_module_unload (core, module, false);
+ return NULL;
+ }
+
+ loopnode = pa_xnew0 (pa_loopnode, 1);
+ loopnode->module_index = module->index;
+ loopnode->source_output_index = sout->index;
+ loopnode->sink_input_index = sinp->index;
+
+ return loopnode;
+}
+
+void pa_loopnode_destroy (struct userdata *u, pa_loopnode *loopnode)
+{
+ pa_core *core;
+ pa_module *module;
+
+ if (u && (core = u->core)) {
+ if ((module = pa_idxset_get_by_index (core->modules, loopnode->module_index))){
+ pa_log_info ("unloading loopback");
+ pa_module_unload (core, module, false);
+ }
+ pa_xfree (loopnode);
+ }
+}