summaryrefslogtreecommitdiffstats
path: root/router.c
diff options
context:
space:
mode:
authorManuel Bachmann <manuel.bachmann@iot.bzh>2016-07-07 17:29:08 +0200
committerYannick Gicquel <yannick.gicquel@iot.bzh>2016-10-11 17:09:07 +0200
commitcc70e0ae30920ca835bf011f8040afb6fea43f45 (patch)
treec4d503c5a556bee69842f38b28e85a182c70bfb8 /router.c
parent2478974dfde05063cbf0233e3d3c434ca2f46c7c (diff)
Implement routing groups and volume ramp up/down
Change-Id: I0e9d3b8b8be4d124907214c165617d86be6906fc Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
Diffstat (limited to 'router.c')
-rw-r--r--router.c102
1 files changed, 91 insertions, 11 deletions
diff --git a/router.c b/router.c
index e47a3d3..4ef0180 100644
--- a/router.c
+++ b/router.c
@@ -97,19 +97,26 @@ bool agl_router_phone_accept (struct userdata *u, agl_rtgroup *rtg, agl_node *no
return true;
}
-int agl_router_default_compare (struct userdata *u, agl_rtgroup *rtg, agl_node *n1, agl_node *n2)
+int agl_router_default_effect (struct userdata *u, agl_rtgroup *rtg, agl_node *node, bool new)
{
/* TODO */
return 1;
}
-int agl_router_phone_compare (struct userdata *u, agl_rtgroup *rtg, agl_node *n1, agl_node *n2)
+int agl_router_phone_effect (struct userdata *u, agl_rtgroup *rtg, agl_node *node, bool new)
{
- /* TODO */
+ pa_assert (u);
+ pa_assert (node);
+
+ if (new)
+ agl_utils_volume_ramp (u, node->nullsink, false);
+ else
+ agl_utils_volume_ramp (u, node->nullsink, true);
+
return 1;
}
-agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type, const char *name, const char *node_desc, agl_rtgroup_accept_t accept, agl_rtgroup_compare_t compare)
+agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type, const char *name, const char *node_desc, agl_rtgroup_accept_t accept, agl_rtgroup_effect_t effect)
{
agl_router *router;
agl_rtgroup *rtg;
@@ -132,7 +139,7 @@ agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type,
rtg = pa_xnew0 (agl_rtgroup, 1);
rtg->name = pa_xstrdup (name);
rtg->accept = accept;
- rtg->compare = compare;
+ rtg->effect = effect;
AGL_DLIST_INIT(rtg->entries);
/* associate an agl_output node for an agl_input routing group */
if (type == agl_input) {
@@ -194,7 +201,7 @@ bool agl_router_assign_class_to_rtgroup (struct userdata *u, agl_node_type class
agl_zone *rzone;
pa_assert (u);
- pa_assert (zone < AGL_ZONE_MAX);
+ pa_assert (zone < AGL_ZONE_MAX);
pa_assert (type == agl_input || type == agl_output);
pa_assert (name);
pa_assert_se (router = u->router);
@@ -225,7 +232,7 @@ bool agl_router_assign_class_to_rtgroup (struct userdata *u, agl_node_type class
}
zonemap = classmap[zone];
- if (!zonemap) { /* THIS LOOKS LIKE A HACK TO IGNORE THE ERROR... */
+ if (!zonemap) {
zonemap = pa_xnew0 (agl_rtgroup *, router->maplen);
classmap[zone] = zonemap;
}
@@ -261,6 +268,81 @@ void agl_router_assign_class_priority (struct userdata *u, agl_node_type class,
}
}
+int agl_router_get_node_priority (struct userdata *u, agl_node *node)
+{
+ agl_router *router;
+ int class;
+
+ pa_assert (u);
+ pa_assert (node);
+ pa_assert_se (router = u->router);
+
+ class = node->type;
+
+ if (class < 0 || class >= (int)router->maplen)
+ return 0;
+
+ return router->priormap[class];
+}
+
+bool agl_router_apply_node_priority_effect (struct userdata *u, agl_node *node, bool new)
+{
+ agl_router *router;
+ agl_rtgroup *rtg;
+ agl_nodeset *nodeset;
+ agl_node *n;
+ pa_sink *sink;
+ int priority;
+ uint32_t index;
+
+ pa_assert (u);
+ pa_assert (node);
+ pa_assert_se (router = u->router);
+ pa_assert_se (nodeset = u->nodeset);
+
+ /* do we have a routing group associated with this node ? It may have a custom effect */
+ if (node->direction == agl_input)
+ rtg = pa_hashmap_get (router->rtgroups.input, agl_node_type_str (node->type));
+ else
+ rtg = pa_hashmap_get (router->rtgroups.output, agl_node_type_str (node->type));
+
+ /* now let us compare priorities, and apply effect if needed */
+ /* "new" case */
+ if (new) {
+ priority = agl_router_get_node_priority (u, node);
+ PA_IDXSET_FOREACH(n, nodeset->nodes, index) {
+ if (n->nullsink && (priority > agl_router_get_node_priority (u, n))) {
+ sink = agl_utils_get_null_sink (u, n->nullsink);
+ if (sink) {
+ /* do we have a custom effect ? otherwise, just mute it */
+ if (rtg && rtg->effect)
+ rtg->effect (u, rtg, n, new);
+ else
+ pa_sink_set_mute (sink, new, false);
+ }
+ }
+ }
+ } else {
+ /* "old" case */
+ if (!agl_node_has_highest_priority (u, node))
+ return true;
+ PA_IDXSET_FOREACH(n, nodeset->nodes, index) {
+ if (n->nullsink) {
+ sink = agl_utils_get_null_sink (u, n->nullsink);
+ if (sink) {
+ /* do we have a custom effect ? otherwise, just unmute it */
+ if (rtg && rtg->effect)
+ rtg->effect (u, rtg, n, new);
+ else
+ pa_sink_set_mute (sink, new, false);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
void agl_router_register_node (struct userdata *u, agl_node *node)
{
agl_router *router;
@@ -393,12 +475,10 @@ void implement_default_route (struct userdata *u,
agl_node *start, agl_node *end,
uint32_t stamp)
{
- if (start->direction == agl_input) {
+ if (start->direction == agl_input)
agl_switch_setup_link (u, start, end, false);
- //agl_volume_add_limiting_class(u, end, volume_class(start), stamp);
- } else {
+ else
agl_switch_setup_link (u, end, start, false);
- }
}
agl_node *find_default_route (struct userdata *u, agl_node *start, uint32_t stamp)