node: fixup default string for agl_player nodes.
[staging/agl-audio-plugin.git] / loopback.c
1 /*
2  * module-agl-audio -- PulseAudio module for providing audio routing support
3  * (forked from "module-murphy-ivi" - https://github.com/otcshare )
4  * Copyright (c) 2012, Intel Corporation.
5  * Copyright (c) 2016, IoT.bzh
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU Lesser General Public License,
9  * version 2.1, as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
19  * MA 02110-1301 USA.
20  *
21  */
22 #include "loopback.h"
23 #include "utils.h"
24 #include "list.h"
25
26 agl_loopback *agl_loopback_init (void)
27 {
28         agl_loopback *loopback = pa_xnew0 (agl_loopback, 1);
29
30         return loopback;
31 }
32
33 void agl_loopback_done (struct userdata *u, agl_loopback *loopback)
34 {
35         agl_loopnode *loop, *n;
36         pa_core *core;
37
38         pa_assert_se (core = u->core);
39
40         PA_LLIST_FOREACH_SAFE(loop, n, loopback->loopnodes) {
41                 pa_module_unload_by_index (core, loop->module_index, false);
42     }
43 }
44
45 agl_loopnode *agl_loopnode_create (struct userdata *u, agl_loopnode_type type,
46                                    uint32_t node_index, uint32_t source_index, uint32_t sink_index)
47 {
48         pa_core *core;
49         pa_module *module;
50         pa_source *source;
51         pa_sink *sink;
52         const char *sonam;
53         const char *sinam;
54         pa_source_output *sout;
55         pa_sink_input *sinp;
56         agl_loopnode *loopnode;
57         int idx;
58         char args[256];
59
60         pa_assert (u);
61         pa_assert_se (core = u->core);
62
63         source = pa_idxset_get_by_index (core->sources, source_index);
64         sink = pa_idxset_get_by_index (core->sinks, sink_index);
65         sonam = agl_utils_get_source_name (source);
66         sinam = agl_utils_get_sink_name (sink);
67
68         snprintf (args, sizeof(args), "source=\"%s\" sink=\"%s\"", sonam, sinam);
69         module = pa_module_load (core, "module-loopback", args);
70
71         if (!module) {
72                 pa_log ("failed to load loopback for source '%s' & sink '%s'", sonam, sinam);
73                 return NULL;
74         }
75
76          /* find the sink_input/source_output couple generated but the module we just loaded */
77         PA_IDXSET_FOREACH(sout, core->source_outputs, idx) {
78                 if (sout->module && sout->module == module)
79                         break;
80                 sout = NULL;
81         }
82         PA_IDXSET_FOREACH(sinp, core->sink_inputs, idx) {
83                 if (sinp->module && sinp->module == module)
84                         break;
85                 sinp = NULL;
86         }
87         if (!sout || !sinp) {
88                 pa_module_unload (module, false);
89                 return NULL;
90         }
91
92         loopnode = pa_xnew0 (agl_loopnode, 1);
93         loopnode->module_index = module->index;
94         loopnode->source_output_index = sout->index;
95         loopnode->sink_input_index = sinp->index;
96
97         return loopnode;
98 }
99
100 void agl_loopnode_destroy (struct userdata *u, agl_loopnode *loopnode)
101 {
102         pa_core      *core;
103         pa_module    *module;
104
105         if (u && (core = u->core)) {
106                 if ((module = pa_idxset_get_by_index (core->modules, loopnode->module_index))){
107                         pa_log_info ("unloading loopback");
108                         pa_module_unload (module, false);
109                 }
110                 pa_xfree (loopnode);
111         }
112 }