5316cf1db1e8cf8a1d3445191fa37d00a5ad3c97
[profile/ivi/pulseaudio-module-murphy-ivi.git] / murphy / utils.c
1 /*
2  * module-murphy-ivi -- PulseAudio module for providing audio routing support
3  * Copyright (c) 2012, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU Lesser General Public License,
7  * version 2.1, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
17  * MA 02110-1301 USA.
18  *
19  */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/stat.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <limits.h>
29
30 #include <sys/types.h>
31 #include <sys/socket.h>
32
33 #include <pulsecore/pulsecore-config.h>
34
35 #include <pulsecore/core-util.h>
36 #include <pulsecore/card.h>
37 #include <pulsecore/sink.h>
38 #include <pulsecore/source.h>
39 #include <pulsecore/sink-input.h>
40
41 #include "userdata.h"
42 #include "utils.h"
43 #include "node.h"
44
45 #ifndef DEFAULT_CONFIG_DIR
46 #define DEFAULT_CONFIG_DIR "/etc/pulse"
47 #endif
48
49 #define DEFAULT_NULL_SINK_NAME "null.mir"
50
51 struct pa_null_sink {
52     char      *name;
53     uint32_t   module_index;
54     uint32_t   sink_index;
55 };
56
57
58 static uint32_t stamp;
59
60 static char *sink_input_name(pa_proplist *);
61
62
63 pa_null_sink *pa_utils_create_null_sink(struct userdata *u, const char *name)
64 {
65     pa_core      *core;
66     pa_module    *module;
67     pa_null_sink *ns;
68     pa_sink      *sink;
69     pa_sink      *s;
70     uint32_t      idx;
71     char          args[256];
72
73     pa_assert(u);
74     pa_assert_se((core = u->core));
75
76
77     if (!name)
78         name = DEFAULT_NULL_SINK_NAME;
79
80
81     snprintf(args, sizeof(args), "sink_name=\"%s\" channels=2", name);
82     module = pa_module_load(core, "module-null-sink", args);
83     sink = NULL;
84
85     if (!module)
86         pa_log("failed to load null sink '%s'", name);
87     else {
88         PA_IDXSET_FOREACH(s, core->sinks, idx) {
89             if (s->module && s->module == module) {
90                 sink = s;
91                 pa_log_info("mir null sink is '%s'", name);
92                 break;
93             }
94         }
95     }
96
97     ns = pa_xnew0(pa_null_sink, 1);
98     ns->name = pa_xstrdup(name);
99     ns->module_index = module ? module->index : PA_IDXSET_INVALID;
100     ns->sink_index = sink ? sink->index : PA_IDXSET_INVALID;
101
102     return ns;
103 }
104
105 void pa_utils_destroy_null_sink(struct userdata *u)
106 {
107     pa_core      *core;
108     pa_module    *module;
109     pa_null_sink *ns;
110
111     if (u && (ns = u->nullsink) && (core = u->core)) {
112         if ((module = pa_idxset_get_by_index(core->modules,ns->module_index))){
113             pa_log_info("unloading null sink '%s'", ns->name);
114             pa_module_unload(core, module, FALSE);
115         }
116
117         pa_xfree(ns->name);
118         pa_xfree(ns);
119     }
120 }
121
122 pa_sink *pa_utils_get_null_sink(struct userdata *u)
123 {
124     pa_core *core;
125     pa_null_sink *ns;
126     
127     pa_assert(u);
128     pa_assert_se((core = u->core));
129     pa_assert_se((ns = u->nullsink));
130
131     return pa_idxset_get_by_index(core->sinks, ns->sink_index);
132 }
133
134 pa_source *pa_utils_get_null_source(struct userdata *u)
135 {
136     pa_sink *ns = pa_utils_get_null_sink(u);
137
138     return ns ? ns->monitor_source : NULL;
139 }
140
141
142
143 char *pa_utils_get_card_name(pa_card *card)
144 {
145     return (card && card->name) ? card->name : "<unknown>";
146 }
147
148 char *pa_utils_get_sink_name(pa_sink *sink)
149 {
150     return (sink && sink->name) ? sink->name : "<unknown>";
151 }
152
153 char *pa_utils_get_source_name(pa_source *source)
154 {
155     return (source && source->name) ? source->name : "<unknown>";
156 }
157
158 char *pa_utils_get_sink_input_name(pa_sink_input *sinp)
159 {
160     char *name;
161
162     if (sinp && (name = sink_input_name(sinp->proplist)))
163         return name;
164     
165     return "<unknown>";
166 }
167
168 char *pa_utils_get_sink_input_name_from_data(pa_sink_input_new_data *data)
169 {
170     char *name;
171
172     if (data && (name = sink_input_name(data->proplist)))
173         return name;
174     
175     return "<unknown>";
176 }
177
178
179 void pa_utils_set_stream_routing_properties(pa_proplist *pl,
180                                             int          styp,
181                                             pa_sink     *sink)
182 {
183     const char    *clnam;
184     const char    *method;
185     char           clid[32];
186
187     pa_assert(pl);
188     pa_assert(styp >= 0);
189     
190     snprintf(clid, sizeof(clid), "%d", styp);
191     clnam  = mir_node_type_str(styp);
192     method = sink ? PA_ROUTING_EXPLICIT : PA_ROUTING_DEFAULT;
193
194     if (pa_proplist_sets(pl, PA_PROP_ROUTING_CLASS_NAME, clnam ) < 0 ||
195         pa_proplist_sets(pl, PA_PROP_ROUTING_CLASS_ID  , clid  ) < 0 ||
196         pa_proplist_sets(pl, PA_PROP_ROUTING_METHOD    , method) < 0  )
197     {
198         pa_log("failed to set some property on sink-input");
199     }
200 }
201
202 void pa_utils_set_stream_routing_method_property(pa_proplist *pl,
203                                                  pa_bool_t explicit)
204 {
205     const char *method = explicit ? PA_ROUTING_EXPLICIT : PA_ROUTING_DEFAULT;
206
207     pa_assert(pl);
208     
209     if (pa_proplist_sets(pl, PA_PROP_ROUTING_METHOD, method) < 0) {
210         pa_log("failed to set routing method property on sink-input");
211     }
212 }
213
214 pa_bool_t pa_utils_stream_has_default_route(pa_proplist *pl)
215 {
216     const char *method;
217
218     pa_assert(pl);
219
220     method = pa_proplist_gets(pl, PA_PROP_ROUTING_METHOD);
221
222     if (method && pa_streq(method, PA_ROUTING_DEFAULT))
223         return TRUE;
224
225     return FALSE;
226 }
227
228 int pa_utils_get_stream_class(pa_proplist *pl)
229 {
230     const char *clid_str;
231     char *e;
232     unsigned long int clid = 0;
233
234     pa_assert(pl);
235
236     if ((clid_str = pa_proplist_gets(pl, PA_PROP_ROUTING_CLASS_ID))) {
237         clid = strtoul(clid_str, &e, 10);
238
239         if (*e)
240             clid = 0;
241     }
242
243     return (int)clid;
244 }
245
246 mir_node *pa_utils_get_node_from_stream(struct userdata *u,pa_sink_input *sinp)
247 {
248     mir_node *node;
249     const char *index_str;
250     uint32_t index = PA_IDXSET_INVALID;
251     char *e;
252
253     pa_assert(u);
254     pa_assert(sinp);
255
256     if ((index_str = pa_proplist_gets(sinp->proplist, PA_PROP_NODE_INDEX))) {
257         index = strtoul(index_str, &e, 10);
258         if (e != index_str && *e == '\0') {
259             if ((node = mir_node_find_by_index(u, index)))
260                 return node;
261
262             pa_log_debug("can't find find node for sink-input.%u",sinp->index);
263         }
264     }
265
266     return NULL;
267 }
268
269 static char *sink_input_name(pa_proplist *pl)
270 {
271     const char  *appnam;
272     const char  *binnam;
273
274     if ((appnam = pa_proplist_gets(pl, PA_PROP_APPLICATION_NAME)))
275         return (char *)appnam;
276
277     if ((binnam = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY)))
278         return (char *)binnam;
279
280     return NULL;
281 }
282
283
284 const char *pa_utils_file_path(const char *file, char *buf, size_t len)
285 {
286     pa_assert(file);
287     pa_assert(buf);
288     pa_assert(len > 0);
289
290     snprintf(buf, len, "%s/%s", DEFAULT_CONFIG_DIR, file);
291
292     return buf;
293 }
294
295
296 uint32_t pa_utils_new_stamp(void)
297 {
298     return ++stamp;
299 }
300
301 uint32_t pa_utils_get_stamp(void)
302 {
303     return stamp;
304 }
305
306
307
308
309 /*
310  * Local Variables:
311  * c-basic-offset: 4
312  * indent-tabs-mode: nil
313  * End:
314  *
315  */
316
317