2 * module-murphy-ivi -- PulseAudio module for providing audio routing support
3 * Copyright (c) 2012, Intel Corporation.
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.
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.
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,
25 #include <pulsecore/pulsecore-config.h>
27 #include <pulsecore/card.h>
28 #include <pulsecore/device-port.h>
29 #include <pulsecore/core-util.h>
36 void pa_classify_node_by_card(mir_node *node,
38 pa_card_profile *prof,
50 bus = pa_utils_get_card_bus(card);
51 form = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_FORM_FACTOR);
53 desc = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_DESCRIPTION);
56 node->type = mir_node_type_unknown;
59 if (!strcasecmp(form, "internal")) {
60 node->location = mir_external;
61 if (port && !strcasecmp(bus, "pci")) {
62 pa_classify_guess_device_node_type_and_name(node, port->name,
66 else if (!strcasecmp(form, "speaker") || !strcasecmp(form, "car")) {
67 if (node->direction == mir_output) {
68 node->location = mir_internal;
69 node->type = mir_speakers;
72 else if (!strcasecmp(form, "handset")) {
73 node->location = mir_external;
74 node->type = mir_phone;
75 node->privacy = mir_private;
77 else if (!strcasecmp(form, "headset")) {
78 node->location = mir_external;
80 if (!strcasecmp(bus,"usb")) {
81 node->type = mir_usb_headset;
83 else if (!strcasecmp(bus,"bluetooth")) {
84 if (prof && !strcmp(prof->name, "a2dp"))
85 node->type = mir_bluetooth_a2dp;
87 node->type = mir_bluetooth_sco;
90 node->type = mir_wired_headset;
94 else if (!strcasecmp(form, "headphone")) {
95 if (node->direction == mir_output) {
96 node->location = mir_external;
98 if (!strcasecmp(bus,"usb"))
99 node->type = mir_usb_headphone;
100 else if (strcasecmp(bus,"bluetooth"))
101 node->type = mir_wired_headphone;
105 else if (!strcasecmp(form, "microphone")) {
106 if (node->direction == mir_input) {
107 node->location = mir_external;
108 node->type = mir_microphone;
113 if (port && !strcasecmp(bus, "pci")) {
114 pa_classify_guess_device_node_type_and_name(node, port->name,
117 else if (prof && !strcasecmp(bus, "bluetooth")) {
118 if (!strcmp(prof->name, "a2dp"))
119 node->type = mir_bluetooth_a2dp;
120 else if (!strcmp(prof->name, "hsp"))
121 node->type = mir_bluetooth_sco;
122 else if (!strcmp(prof->name, "hfgw"))
123 node->type = mir_bluetooth_carkit;
124 else if (!strcmp(prof->name, "a2dp_source"))
125 node->type = mir_bluetooth_source;
126 else if (!strcmp(prof->name, "a2dp_sink"))
127 node->type = mir_bluetooth_sink;
131 if (!node->amname[0]) {
132 if (node->type != mir_node_type_unknown)
133 node->amname = (char *)mir_node_type_str(node->type);
134 else if (port && port->description)
135 node->amname = port->description;
136 else if (port && port->name)
137 node->amname = port->name;
139 node->amname = node->paname;
143 if (node->direction == mir_input)
144 node->privacy = mir_privacy_unknown;
146 switch (node->type) {
150 case mir_front_speakers:
151 case mir_rear_speakers:
152 node->privacy = mir_public;
157 case mir_wired_headset:
158 case mir_wired_headphone:
159 case mir_usb_headset:
160 case mir_usb_headphone:
161 case mir_bluetooth_sco:
162 case mir_bluetooth_a2dp:
163 node->privacy = mir_private;
171 case mir_bluetooth_sink:
172 node->privacy = mir_privacy_unknown;
178 pa_bool_t pa_classify_node_by_property(mir_node *node, pa_proplist *pl)
185 static type_mapping_t map[] = {
186 {"speakers" , mir_speakers },
187 {"front-speakers", mir_front_speakers },
188 {"rear-speakers" , mir_rear_speakers },
189 {"microphone" , mir_microphone },
190 {"jack" , mir_jack },
191 {"hdmi" , mir_hdmi },
192 {"spdif" , mir_spdif },
193 { NULL , mir_node_type_unknown}
202 if ((type = pa_proplist_gets(pl, PA_PROP_NODE_TYPE))) {
203 for (i = 0; map[i].name; i++) {
204 if (pa_streq(type, map[i].name)) {
205 node->type = map[i].value;
214 /* data->direction must be set */
215 void pa_classify_guess_device_node_type_and_name(mir_node *node,
223 if (node->direction == mir_output && strcasestr(name, "headphone")) {
224 node->type = mir_wired_headphone;
225 node->amname = (char *)desc;
227 else if (strcasestr(name, "headset")) {
228 node->type = mir_wired_headset;
229 node->amname = (char *)desc;
231 else if (strcasestr(name, "line")) {
232 node->type = mir_jack;
233 node->amname = (char *)desc;
235 else if (strcasestr(name, "spdif")) {
236 node->type = mir_spdif;
237 node->amname = (char *)desc;
239 else if (strcasestr(name, "hdmi")) {
240 node->type = mir_hdmi;
241 node->amname = (char *)desc;
243 else if (node->direction == mir_input && strcasestr(name, "microphone")) {
244 node->type = mir_microphone;
245 node->amname = (char *)desc;
247 else if (node->direction == mir_output && strcasestr(name,"analog-output"))
248 node->type = mir_speakers;
249 else if (node->direction == mir_input && strcasestr(name, "analog-input"))
250 node->type = mir_jack;
252 node->type = mir_node_type_unknown;
257 mir_node_type pa_classify_guess_stream_node_type(pa_proplist *pl)
264 static map_t role_map[] = {
265 {"video" , mir_player },
266 {"music" , mir_player },
267 {"game" , mir_game },
268 {"event" , mir_event },
269 {"navigator", mir_navigator },
270 {"phone" , mir_phone },
271 {"carkit" , mir_phone },
272 {"animation", mir_browser },
273 {"test" , mir_player },
274 {"ringtone" , mir_alert },
275 {"alarm" , mir_alert },
276 {"camera" , mir_camera },
277 {"system" , mir_system },
278 {NULL, mir_node_type_unknown}
281 static map_t bin_map[] = {
282 {"rhytmbox" , mir_player },
283 {"firefox" , mir_browser},
284 {"chrome" , mir_browser},
285 {"sound-juicer", mir_player },
286 {NULL, mir_node_type_unknown}
290 mir_node_type rtype, btype;
297 rtype = btype = mir_node_type_unknown;
299 role = pa_proplist_gets(pl, PA_PROP_MEDIA_ROLE);
300 bin = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY);
303 for (m = role_map; m->id; m++) {
304 if (pa_streq(role, m->id))
310 if (rtype != mir_node_type_unknown && rtype != mir_player)
314 for (m = bin_map; m->id; m++) {
315 if (pa_streq(bin, m->id))
321 if (btype == mir_node_type_unknown)
327 mir_node_type pa_classify_guess_application_class(mir_node *node)
333 if (node->implement == mir_stream)
336 if (node->direction == mir_output)
337 class = mir_node_type_unknown;
339 switch (node->type) {
340 default: class = mir_node_type_unknown; break;
341 case mir_bluetooth_carkit: class = mir_phone; break;
342 case mir_bluetooth_source: class = mir_player; break;
351 pa_bool_t pa_classify_multiplex_stream(mir_node *node)
353 static pa_bool_t multiplex[mir_application_class_end] = {
354 [ mir_player ] = TRUE,
356 [ mir_browser ] = TRUE,
363 if (node->implement == mir_stream && node->direction == mir_input) {
366 if (class > mir_application_class_begin &&
367 class < mir_application_class_end)
369 return multiplex[class];
376 const char *pa_classify_loopback_stream(mir_node *node)
378 const char *role[mir_device_class_end - mir_device_class_begin] = {
379 [ mir_bluetooth_carkit - mir_device_class_begin ] = "phone",
380 [ mir_bluetooth_source - mir_device_class_begin ] = "music" ,
387 if (node->implement == mir_device) {
390 if (class >= mir_device_class_begin && class < mir_device_class_end) {
391 return role[class - mir_device_class_begin];
401 * indent-tabs-mode: nil