From 6c2aef81c4182695487fabbd19c5c0a84409b49f Mon Sep 17 00:00:00 2001 From: Manuel Bachmann Date: Thu, 9 Jun 2016 18:22:08 +0200 Subject: Initial commit Change-Id: Ic974941bdd30309b4adb72b7a05959332750210b Signed-off-by: Manuel Bachmann --- utils.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 utils.c (limited to 'utils.c') diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..dc9c756 --- /dev/null +++ b/utils.c @@ -0,0 +1,277 @@ +/* + * module-agl-audio -- PulseAudio module for providing audio routing support + * (forked from "module-murphy-ivi" - https://github.com/otcshare ) + * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2016, IoT.bzh + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, + * MA 02110-1301 USA. + * + */ +#include "userdata.h" +#include "utils.h" +#include "node.h" + +#define DEFAULT_NULL_SINK_NAME "null.agl" + +#ifndef PA_PROP_PROCESS_ENVIRONMENT +#define PA_PROP_PROCESS_ENVIRONMENT "application.process.environment" +#endif +#define PA_ZONE_NAME_DEFAULT "driver" +#define PA_PROP_ZONE_NAME "zone.name" +#define PA_PROP_ENV_ZONE PA_PROP_PROCESS_ENVIRONMENT ".AUDIO_ZONE" + +#define PA_PROP_ROUTING_CLASS_NAME "routing.class.name" +#define PA_PROP_ROUTING_CLASS_ID "routing.class.id" +#define PA_PROP_ROUTING_METHOD "routing.method" + +static uint32_t stamp; + +struct pa_null_sink { + char *name; + uint32_t module_index; + uint32_t sink_index; +}; + +pa_null_sink *pa_utils_create_null_sink (struct userdata *u, const char *name) +{ + pa_core *core; + pa_module *module; + pa_null_sink *ns; + pa_sink *s, *sink; + uint32_t idx; + char args[256]; + + pa_assert (u); + pa_assert_se (core = u->core); + + if (!name) + name = DEFAULT_NULL_SINK_NAME; /* default is "null.agl" */ + + snprintf (args, sizeof(args), "sink_name=\"%s.%d\" channels=2", name, pa_utils_new_stamp ()); + module = pa_module_load (core, "module-null-sink", args); + sink = NULL; + + if (!module) { + pa_log ("failed to load null sink '%s'", name); + return NULL; + } else { + PA_IDXSET_FOREACH(s, core->sinks, idx) { + if (s->module && s->module == module) { + sink = s; + pa_log_info("created agl null sink named '%s'", name); + break; + } + } + } + + ns = pa_xnew0 (pa_null_sink, 1); + ns->name = pa_xstrdup (name); + ns->module_index = module ? module->index : PA_IDXSET_INVALID; + ns->sink_index = sink ? sink->index : PA_IDXSET_INVALID; + + return ns; +} + +void pa_utils_destroy_null_sink (struct userdata *u, pa_null_sink *ns) +{ + pa_core *core; + pa_module *module; + + if (u && (core = u->core)) { + if ((module = pa_idxset_get_by_index (core->modules, ns->module_index))){ + pa_log_info ("unloading null sink '%s'", ns->name); + pa_module_unload (core, module, false); + } + + pa_xfree (ns->name); + pa_xfree (ns); + } +} + +pa_sink *pa_utils_get_null_sink (struct userdata *u, struct pa_null_sink *ns) +{ + pa_core *core; + pa_sink *sink; + + pa_assert (u); + pa_assert_se ((core = u->core)); + + return pa_idxset_get_by_index (core->sinks, ns->sink_index); +} + +pa_source *pa_utils_get_null_source (struct userdata *u, struct pa_null_sink *ns) +{ + pa_sink *sink; + + sink = pa_utils_get_null_sink (u, ns); + + return sink ? sink->monitor_source : NULL; +} + + +const char *pa_utils_get_card_name (pa_card *card) +{ + return (card && card->name) ? card->name : ""; +} + +const char *pa_utils_get_card_bus (pa_card *card) +{ + const char *bus = NULL; + const char *name; + + if (card && !(bus = pa_proplist_gets (card->proplist,PA_PROP_DEVICE_BUS))) { + name = pa_utils_get_card_name (card); + if (!strncmp (name, "alsa_card.", 10)) { + if (!strncmp (name + 10, "pci-", 4)) + bus = "pci"; + else if (!strncmp (name + 10, "platform-", 9)) + bus = "platform"; + else if (!strncmp (name + 10, "usb-", 4)) + bus = "usb"; + } + } + + return (char *)bus; +} + +const char *pa_utils_get_sink_name (pa_sink *sink) +{ + return (sink && sink->name) ? sink->name : ""; +} + +const char *pa_utils_get_source_name (pa_source *source) +{ + return (source && source->name) ? source->name : ""; +} + +const char *pa_utils_get_sink_input_name (pa_sink_input *sinp) +{ + char *name = NULL; + + if (sinp && sinp->proplist) { + name = (char *)pa_proplist_gets (sinp->proplist, PA_PROP_APPLICATION_NAME); + if (!name) + name = (char *)pa_proplist_gets (sinp->proplist, PA_PROP_APPLICATION_PROCESS_BINARY); + if (!name) + name = ""; + } + + return (const char *)name; +} + +const char *pa_utils_get_source_output_name (pa_source_output *sout) +{ + char *name = NULL; + + if (sout && sout->proplist) { + name = (char *)pa_proplist_gets (sout->proplist, PA_PROP_APPLICATION_NAME); + if (!name) + name = (char *)pa_proplist_gets (sout->proplist, PA_PROP_APPLICATION_PROCESS_BINARY); + if (!name) + name = ""; + } + + return (const char *)name; +} + +pa_sink *pa_utils_get_primary_alsa_sink (struct userdata *u) +{ + 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")) + return sink; + } + + return NULL; +} + +void pa_utils_init_stamp (void) +{ + stamp = 0; +} + +uint32_t pa_utils_new_stamp (void) +{ + return ++stamp; +} + +uint32_t pa_utils_get_stamp (void) +{ + return stamp; +} + + + +char *pa_utils_get_zone (pa_proplist *pl, pa_proplist *client_props) +{ + const char *zone; + + pa_assert (pl); + + /* grab the "zone.name" PA_PROP environment variable ; + * otherwise just fall back to default "driver" zone */ + zone = pa_proplist_gets (pl, PA_PROP_ZONE_NAME); + if (!zone) { + if (!client_props || !(zone = pa_proplist_gets (client_props, PA_PROP_ENV_ZONE))) + zone = PA_ZONE_NAME_DEFAULT; + } + + return (char *)zone; +} + +bool pa_utils_set_stream_routing_properties (pa_proplist *pl, int styp, void *target) +{ + const char *clnam; /* will become "agl_player" e.g. */ + char clid[32]; /* will become "1" e.g. */ + const char *method; /* will become "default" (it target is NULL) or "explicit" */ + + pa_assert (pl); + pa_assert (styp >= 0); /* type different from "agl_node_type_unknown" */ + + clnam = agl_node_type_str (styp); + snprintf (clid, sizeof(clid), "%d", styp); + method = target ? "explicit" : "default"; + + if (pa_proplist_sets (pl, PA_PROP_ROUTING_CLASS_NAME, clnam ) < 0 || + pa_proplist_sets (pl, PA_PROP_ROUTING_CLASS_ID , clid ) < 0 || + pa_proplist_sets (pl, PA_PROP_ROUTING_METHOD , method) < 0) + { + pa_log ("failed to set some stream property"); + return false; + } + + return true; +} + +bool pa_utils_unset_stream_routing_properties (pa_proplist *pl) +{ + pa_assert (pl); + + if (pa_proplist_unset (pl, PA_PROP_ROUTING_CLASS_NAME) < 0 || + pa_proplist_unset (pl, PA_PROP_ROUTING_CLASS_ID ) < 0 || + pa_proplist_unset (pl, PA_PROP_ROUTING_METHOD ) < 0) + { + pa_log ("failed to unset some stream property"); + return false; + } + + return true; +} -- cgit 1.2.3-korg