2 * module-murphy-ivi -- PulseAudio module for providing audio routing support
3 * Copyright (c) 2012, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
24 #include <pulsecore/pulsecore-config.h>
26 #include <pulse/def.h>
27 #include <pulsecore/thread.h>
28 #include <pulsecore/strlist.h>
29 #include <pulsecore/time-smoother.h>
30 #include <pulsecore/sink.h>
31 #include <pulsecore/sink-input.h>
39 pa_loopback *pa_loopback_init(void)
41 pa_loopback *loopback = pa_xnew0(pa_loopback, 1);
47 void pa_loopback_done(pa_loopback *loopback, pa_core *core)
49 pa_loopnode *loop, *n;
51 PA_LLIST_FOREACH_SAFE(loop,n, loopback->loopnodes) {
52 pa_module_unload_by_index(core, loop->module_index, FALSE);
58 pa_loopnode *pa_loopback_create(pa_loopback *loopback,
61 uint32_t source_index,
63 const char *media_role)
65 static char *modnam = "module-loopback";
71 pa_sink_input *sink_input;
72 pa_source_output *source_output;
78 if (!(source = pa_idxset_get_by_index(core->sources, source_index))) {
79 pa_log_debug("can't find source (index %u) for loopback",source_index);
83 if (!(sink = pa_idxset_get_by_index(core->sinks, sink_index))) {
84 pa_log_debug("can't find the primary sink (index %u) for loopback",
92 snprintf(args, sizeof(args), "source=\"%s\" sink=\"%s\" "
93 "sink_input_properties=\"%s=%s %s=%u\" "
94 "source_output_properties=\"%s=%s %s=%u\"",
95 source->name, sink->name,
96 PA_PROP_MEDIA_ROLE, media_role,
97 PA_PROP_NODE_INDEX, node_index,
98 PA_PROP_MEDIA_ROLE, media_role,
99 PA_PROP_NODE_INDEX, node_index);
101 pa_log_debug("loading %s %s", modnam, args);
103 if (!(module = pa_module_load(core, modnam, args))) {
104 pa_log("failed to load module '%s %s'. can't loopback", modnam, args);
108 PA_IDXSET_FOREACH(sink_input, core->sink_inputs, idx) {
109 if (sink_input->module == module)
113 PA_IDXSET_FOREACH(source_output, core->source_outputs, idx) {
114 if (source_output->module == module)
118 if (!sink_input || !source_output) {
120 pa_log("can't find output stream of loopback module (index %u)",
123 if (!source_output) {
124 pa_log("can't find input stream of loopback module (index %u)",
127 pa_module_unload(core, module, FALSE);
131 pa_assert(sink_input->index != PA_IDXSET_INVALID);
132 pa_assert(source_output->index != PA_IDXSET_INVALID);
134 loop = pa_xnew0(pa_loopnode, 1);
135 loop->module_index = module->index;
136 loop->node_index = node_index;
137 loop->sink_input_index = sink_input->index;
138 loop->source_output_index = source_output->index;
140 PA_LLIST_PREPEND(pa_loopnode, loopback->loopnodes, loop);
142 pa_log_debug("loopback succesfully loaded. Module index %u",module->index);
148 void pa_loopback_destroy(pa_loopback *loopback,
156 PA_LLIST_REMOVE(pa_loopnode, loopback->loopnodes, loop);
157 pa_module_unload_by_index(core, loop->module_index, FALSE);
162 uint32_t pa_loopback_get_sink_index(pa_core *core, pa_loopnode *loop)
164 pa_sink_input *sink_input;
170 sink_input = pa_idxset_get_by_index(core->sink_inputs,
171 loop->sink_input_index);
173 if (sink_input && (sink = sink_input->sink))
176 return PA_IDXSET_INVALID;
179 int pa_loopback_print(pa_loopnode *loop, char *buf, int len)
189 p += snprintf(p, e-p, "<not set>");
191 p += snprintf(p, e-p, "module %u, sink_input %u",
192 loop->module_index, loop->sink_input_index);
202 * indent-tabs-mode: nil