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
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.
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.
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,
26 pa_router *pa_router_init (struct userdata *u)
31 num_classes = agl_application_class_end;
33 router = pa_xnew0 (pa_router, 1);
34 router->rtgroups.input = pa_hashmap_new (pa_idxset_string_hash_func,
35 pa_idxset_string_compare_func);
36 router->rtgroups.output = pa_hashmap_new (pa_idxset_string_hash_func,
37 pa_idxset_string_compare_func);
38 router->maplen = num_classes;
39 router->priormap = pa_xnew0 (int, num_classes);
41 AGL_DLIST_INIT (router->nodlist);
42 AGL_DLIST_INIT (router->connlist);
47 void pa_router_done (struct userdata *u)
51 agl_connection *conn, *c;
56 if (u && (router = u->router)) {
57 AGL_DLIST_FOR_EACH_SAFE(agl_node, rtprilist, e,n, &router->nodlist)
58 AGL_DLIST_UNLINK(agl_node, rtprilist, e);
59 AGL_DLIST_FOR_EACH_SAFE(agl_connection, link, conn,c, &router->connlist) {
60 AGL_DLIST_UNLINK(agl_connection, link, conn);
64 PA_HASHMAP_FOREACH(rtg, router->rtgroups.input, state) {
65 rtgroup_destroy(u, rtg);
67 PA_HASHMAP_FOREACH(rtg, router->rtgroups.output, state) {
68 rtgroup_destroy(u, rtg);
70 pa_hashmap_free (router->rtgroups.input);
71 pa_hashmap_free (router->rtgroups.output);
73 for (i = 0; i < AGL_ZONE_MAX; i++) {
74 if ((map = router->classmap.input[i]))
76 if ((map = router->classmap.output[i]))
80 pa_xfree (router->priormap);
87 void agl_router_register_node (struct userdata *u, agl_node *node)
92 implement_default_route (u, node, NULL, pa_utils_new_stamp ());
95 void agl_router_unregister_node (struct userdata *u, agl_node *node)
100 remove_routes (u, node, NULL, pa_utils_new_stamp ());
103 agl_node *agl_router_make_prerouting (struct userdata *u, agl_node *data)
107 static bool done_prerouting;
109 agl_node *start, *end;
113 pa_assert_se (router = u->router);
114 pa_assert_se (data->implement == agl_stream);
116 //priority = node_priority (u, data);
118 done_prerouting = false;
120 stamp = pa_utils_new_stamp ();
122 //make_explicit_routes (u, stamp);
124 //pa_audiomgr_delete_default_routes(u);
126 AGL_DLIST_FOR_EACH_BACKWARDS(agl_node, rtprilist, start, &router->nodlist) {
127 //if ((start->implement == agl_device) &&
128 // (!start->loop)) /* only manage looped real devices */
131 /*if (priority >= node_priority (u, start)) {
132 target = find_default_route (u, data, stamp);
134 implement_preroute (u, data, target, stamp);
136 done_prerouting = true;
139 if (start->stamp >= stamp)
142 //end = find_default_route (u, start, stamp);
144 // implement_default_route(u, start, end, stamp);
147 if (!done_prerouting) {
148 pa_log_debug ("Prerouting failed, trying to find default route as last resort");
150 //target = find_default_route (u, data, stamp);
152 // implement_preroute (u, data, target, stamp);
158 void agl_router_make_routing (struct userdata *u)
161 static bool ongoing_routing; /* true while we are actively routing */
163 agl_node *start, *end;
166 pa_assert_se (router = u->router);
168 if (ongoing_routing) /* already routing, canceling */
170 ongoing_routing = true;
171 stamp = pa_utils_new_stamp ();
173 pa_log_debug("stamp for routing: %d", stamp);
175 // make_explicit_routes (u, stamp);
177 // pa_audiomgr_delete_default_routes (u);
179 AGL_DLIST_FOR_EACH_BACKWARDS(agl_node, rtprilist, start, &router->nodlist) {
180 //if ((start->implement == agl_device) &&
181 // (!start->loop)) /* only manage looped real devices */
184 if (start->stamp >= stamp)
187 end = find_default_route (u, start, stamp);
189 implement_default_route (u, start, end, stamp);
192 // pa_audiomgr_send_default_routes (u);
194 ongoing_routing = false;
197 void implement_default_route (struct userdata *u,
198 agl_node *start, agl_node *end,
201 if (start->direction == agl_input) {
202 agl_switch_setup_link (u, start, end, false);
203 //agl_volume_add_limiting_class(u, end, volume_class(start), stamp);
205 agl_switch_setup_link (u, end, start, false);
209 agl_node *find_default_route (struct userdata *u, agl_node *start, uint32_t stamp)
216 void remove_routes (struct userdata *u, agl_node *start, agl_node *end, uint32_t stamp)
218 if (start->direction == agl_input) {
219 agl_switch_teardown_link (u, start, end);
221 agl_switch_teardown_link (u, end, start);