diff options
author | Manuel Bachmann <manuel.bachmann@iot.bzh> | 2016-07-06 10:16:36 +0200 |
---|---|---|
committer | Yannick Gicquel <yannick.gicquel@iot.bzh> | 2016-10-11 17:09:07 +0200 |
commit | 2478974dfde05063cbf0233e3d3c434ca2f46c7c (patch) | |
tree | 86395f3b4c2c35261e051c237d7ae17f9ca3994a | |
parent | f259ec53101a3754cd2da24a369ea48bb1947e62 (diff) |
Map labels to classes, map routing groups to audio adapters
Change-Id: I563aa146eba8de594900c02b44f19f526a5cdc0e
Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
-rw-r--r-- | classify.c | 9 | ||||
-rw-r--r-- | config.c | 22 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | node.c | 2 | ||||
-rw-r--r-- | router.c | 42 | ||||
-rw-r--r-- | router.h | 5 | ||||
-rw-r--r-- | switch.c | 10 | ||||
-rw-r--r-- | utils.c | 20 | ||||
-rw-r--r-- | utils.h | 1 |
9 files changed, 89 insertions, 23 deletions
@@ -23,19 +23,28 @@ #include <pulsecore/core-util.h> /* required for "pa_streq" */ #include "classify.h" +#include "node.h" agl_node_type agl_classify_guess_stream_node_type (struct userdata *u, pa_proplist *pl) { + agl_nodeset *ns; + agl_nodeset_map *map; agl_node_type type; const char *role; pa_assert (u); pa_assert (pl); + pa_assert_se (ns = u->nodeset); role = pa_proplist_gets (pl, PA_PROP_MEDIA_ROLE); if (!role) type = agl_node_type_unknown; + + /* ask the configuration, see defaults in "config.c" */ + else if (map = pa_hashmap_get (ns->roles, role)) + type = map->type; + /* configuration did not match, here are some sensible defaults */ else if (pa_streq (role, "radio")) type = agl_radio; else if (pa_streq (role, "music")) @@ -22,6 +22,8 @@ #include "config.h" #include "zone.h" +bool use_default_configuration (struct userdata *); + const char *agl_config_file_get_path (const char *dir, const char *file, char *buf, size_t len) { pa_assert (file); @@ -48,7 +50,7 @@ bool agl_config_parse_file (struct userdata *u, const char *path) if (!success) { pa_log_info ("applying builtin default configuration"); - //success = use_default_configuration (u); + success = use_default_configuration (u); } return success; @@ -75,20 +77,21 @@ static zone_def zones[] = { static rtgroup_def rtgroups[] = { { agl_input, - "phone", + "Phone", + "PhoneCard", agl_router_phone_accept, agl_router_phone_compare }, - { 0, NULL, NULL, NULL } + { 0, NULL, NULL, NULL, NULL } }; static classmap_def classmap[] = { - { agl_phone, 0, agl_output, "phone" }, - { agl_player, 0, agl_output, "default" }, - { agl_radio, 0, agl_output, "default" }, - { agl_navigator,0, agl_output, "default" }, - { agl_event, 0, agl_output, "default" }, + { agl_phone, 0, agl_input, "Phone" }, + { agl_player, 0, agl_input, "default" }, + { agl_radio, 0, agl_input, "default" }, + { agl_navigator,0, agl_input, "default" }, + { agl_event, 0, agl_input, "default" }, { agl_node_type_unknown, 0, agl_direction_unknown, NULL } }; @@ -124,7 +127,8 @@ bool use_default_configuration (struct userdata *u) agl_zoneset_add_zone (u, z->name, (uint32_t)(z - zones)); for (r = rtgroups; r->name; r++) - agl_router_create_rtgroup (u, r->type, r->name, r->accept, r->compare); + agl_router_create_rtgroup (u, r->type, r->name, r->node_desc, + r->accept, r->compare); for (c = classmap; c->rtgroup; c++) agl_router_assign_class_to_rtgroup (u, c->class, c->zone, @@ -34,6 +34,7 @@ typedef struct { typedef struct { agl_direction type; /* agl_input/agl_output */ const char *name; + const char *node_desc; agl_rtgroup_accept_t accept; agl_rtgroup_compare_t compare; } rtgroup_def; @@ -149,7 +149,7 @@ const char *agl_node_type_str (agl_node_type type) case agl_alert: return "Alert"; case agl_event: return "Event"; case agl_system: return "System"; - default: return "<user defined>"; + default: return "default"; } } @@ -109,18 +109,19 @@ int agl_router_phone_compare (struct userdata *u, agl_rtgroup *rtg, agl_node *n1 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_compare_t compare) { 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; @@ -133,6 +134,21 @@ agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type, rtg->accept = accept; rtg->compare = compare; 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); @@ -247,10 +263,28 @@ void agl_router_assign_class_priority (struct userdata *u, agl_node_type class, 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); - implement_default_route (u, node, NULL, agl_utils_new_stamp ()); + /* 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 */ + if (node->direction == agl_input) { + rtg = pa_hashmap_get (router->rtgroups.input, agl_node_type_str (node->type)); + 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 { + rtg = pa_hashmap_get (router->rtgroups.output, agl_node_type_str (node->type)); + 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) @@ -32,8 +32,9 @@ typedef bool (*agl_rtgroup_accept_t)(struct userdata *, agl_rtgroup *, agl_node typedef int (*agl_rtgroup_compare_t)(struct userdata *, agl_rtgroup *, agl_node *, agl_node *); struct agl_rtgroup { - char *name; /**< name of the rtgroup */ + char *name; /**< name of the rtgroup */ agl_dlist entries; /**< listhead of ordered rtentries */ + agl_node *node; /**< final node */ agl_rtgroup_accept_t accept; /**< function pointer, whether to accept a node or not */ agl_rtgroup_compare_t compare; /**< function pointer, comparision for ordering */ }; @@ -75,7 +76,7 @@ bool agl_router_phone_accept (struct userdata *, agl_rtgroup *, agl_node *); int agl_router_default_compare (struct userdata *, agl_rtgroup *, agl_node *, agl_node *); int agl_router_phone_compare (struct userdata *, agl_rtgroup *, agl_node *, agl_node *); -agl_rtgroup *agl_router_create_rtgroup (struct userdata *, agl_direction, const char *, agl_rtgroup_accept_t, agl_rtgroup_compare_t); +agl_rtgroup *agl_router_create_rtgroup (struct userdata *, agl_direction, const char *, const char *, agl_rtgroup_accept_t, agl_rtgroup_compare_t); void agl_router_destroy_rtgroup (struct userdata *, agl_direction, const char *); bool agl_router_assign_class_to_rtgroup (struct userdata *, agl_node_type, uint32_t, agl_direction, const char *); void agl_router_assign_class_priority (struct userdata *, agl_node_type, int); @@ -103,15 +103,13 @@ bool agl_switch_setup_link (struct userdata *u, agl_node *from, agl_node *to, bo /* DEVICE DESTINATION */ case agl_device: - /* IF THERE IS NO SOURCE : DEFAULT OUTPUT PREROUTE */ - /* if (!from) - return setup_device_output(u, to) != NULL; - else { */ switch (from->implement) { /* STREAM TO DEVICE : OK */ case agl_stream: - //if (!setup_default_stream2dev_link (u, from, to)) - // return false; + sink = agl_utils_get_alsa_sink (u, to->paname); + source = agl_utils_get_null_source (u, from->nullsink); + + from->loopnode = agl_loopnode_create (u, AGL_LOOPNODE_SINK, from->index, source->index, sink->index); break; /* DEVICE TO DEVICE : OK */ case agl_device: @@ -196,13 +196,31 @@ pa_sink *agl_utils_get_primary_alsa_sink (struct userdata *u) pa_assert_se ((core = u->core)); PA_IDXSET_FOREACH(sink, core->sinks, idx) { - if (sink->name && strstr (sink->name, "alsa_output")) + if (sink->name && strstr (sink->name, "alsa_output") && strstr (sink->name, "pci")) return sink; } return NULL; } +pa_sink *agl_utils_get_alsa_sink (struct userdata *u, const char *name) +{ + pa_core *core; + pa_sink *sink; + int idx; + + pa_assert (u); + pa_assert_se ((core = u->core)); + + PA_IDXSET_FOREACH(sink, core->sinks, idx) { + if (sink->name && strstr (sink->name, "alsa_output") + && strstr (sink->name, name)) + return sink; + } + + return NULL; +} + void agl_utils_init_stamp (void) { stamp = 0; @@ -41,6 +41,7 @@ const char *agl_utils_get_source_name (pa_source *); const char *agl_utils_get_sink_input_name (pa_sink_input *); const char *agl_utils_get_source_output_name (pa_source_output *); pa_sink *agl_utils_get_primary_alsa_sink (struct userdata *); +pa_sink *agl_utils_get_alsa_sink (struct userdata *, const char *); void agl_utils_init_stamp (void); uint32_t agl_utils_new_stamp (void); uint32_t agl_utils_get_stamp (void); |