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, 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;
+ agl_nodeset *nodeset;
+ agl_node *node;
pa_hashmap *table;
pa_assert (u);
pa_assert (type == agl_input || type == agl_output);
pa_assert (name);
- pa_assert (accept);
- pa_assert (compare);
pa_assert_se (router = u->router);
+ pa_assert_se (nodeset = u->nodeset);
if (type == agl_input)
table = router->rtgroups.input;
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) {
+ node = agl_node_create (u, NULL);
+ node->direction = agl_output;
+ node->implement = agl_device;
+ node->visible = true;
+ node->available = true;
+ node->paname = pa_xstrdup (node_desc);
+ /* add to global nodeset */
+ pa_idxset_put (nodeset->nodes, node, &node->index);
+ rtg->node = node;
+ } else {
+ rtg->node = NULL;
+ }
+
pa_hashmap_put (table, rtg->name, rtg);
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);
}
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;
}
return true;
}
+agl_rtgroup * agl_router_get_rtgroup_from_class (struct userdata *u, agl_node_type class, uint32_t zone, agl_direction type)
+{
+ agl_router *router;
+ pa_hashmap *rtable;
+ agl_rtgroup ***classmap;
+ agl_rtgroup **zonemap;
+ agl_rtgroup * rtg;
+
+ pa_assert (u);
+ pa_assert_se (router = u->router);
+ pa_assert (class >= 0 && class < router->maplen);
+ pa_assert (zone < AGL_ZONE_MAX);
+ pa_assert (type == agl_input || type == agl_output);
+
+ if (type == agl_input) {
+ rtable = router->rtgroups.input;
+ classmap = router->classmap.input;
+ } else {
+ rtable = router->rtgroups.output;
+ classmap = router->classmap.output;
+ }
+
+ zonemap = classmap[zone];
+ rtg = zonemap[class];
+
+ return rtg;
+}
+
void agl_router_assign_class_priority (struct userdata *u, agl_node_type class, int priority)
{
agl_router *router;
}
}
+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);
+
+ rtg = agl_router_get_rtgroup_from_class(u, node->type, 0, node->direction);
+
+ /* 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;
+ agl_rtgroup *rtg;
+
pa_assert (u);
pa_assert (node);
+ pa_assert_se (router = u->router);
+
+ /* we try to discover node routing group from the configuration, "Phone" for instance,
+ * see defaults in "config.c. Otherwise we just say NULL, a.k.a. default */
+ rtg = agl_router_get_rtgroup_from_class(u, node->type, 0, node->direction);
- implement_default_route (u, node, NULL, agl_utils_new_stamp ());
+ if (node->direction == agl_input) {
+ if (rtg)
+ implement_default_route (u, node, rtg->node, agl_utils_new_stamp ());
+ else
+ implement_default_route (u, node, NULL, agl_utils_new_stamp ());
+ } else {
+ if (rtg)
+ implement_default_route (u, rtg->node, node, agl_utils_new_stamp ());
+ else
+ implement_default_route (u, NULL, node, agl_utils_new_stamp ());
+ }
}
void agl_router_unregister_node (struct userdata *u, agl_node *node)
agl_node *start, agl_node *end,
uint32_t stamp)
{
- 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 {
- agl_switch_setup_link (u, end, start, false);
- }
+ if (start->direction == agl_input)
+ agl_switch_setup_link (u, start, end);
+ else
+ agl_switch_setup_link (u, end, start);
}
agl_node *find_default_route (struct userdata *u, agl_node *start, uint32_t stamp)