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/sink.h>
28 #include <pulsecore/card.h>
29 #include <pulsecore/device-port.h>
30 #include <pulsecore/core-util.h>
37 void pa_classify_node_by_card(mir_node *node,
39 pa_card_profile *prof,
51 bus = pa_utils_get_card_bus(card);
52 form = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_FORM_FACTOR);
54 desc = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_DESCRIPTION);
57 node->type = mir_node_type_unknown;
60 if (!strcasecmp(form, "internal")) {
61 node->location = mir_external;
62 if (port && !strcasecmp(bus, "pci")) {
63 pa_classify_guess_device_node_type_and_name(node, port->name,
67 else if (!strcasecmp(form, "speaker") || !strcasecmp(form, "car")) {
68 if (node->direction == mir_output) {
69 node->location = mir_internal;
70 node->type = mir_speakers;
73 else if (!strcasecmp(form, "handset")) {
74 node->location = mir_external;
75 node->type = mir_phone;
76 node->privacy = mir_private;
78 else if (!strcasecmp(form, "headset")) {
79 node->location = mir_external;
81 if (!strcasecmp(bus,"usb")) {
82 node->type = mir_usb_headset;
84 else if (!strcasecmp(bus,"bluetooth")) {
85 if (prof && !strcmp(prof->name, "a2dp"))
86 node->type = mir_bluetooth_a2dp;
88 node->type = mir_bluetooth_sco;
91 node->type = mir_wired_headset;
95 else if (!strcasecmp(form, "headphone")) {
96 if (node->direction == mir_output) {
97 node->location = mir_external;
99 if (!strcasecmp(bus,"usb"))
100 node->type = mir_usb_headphone;
101 else if (strcasecmp(bus,"bluetooth"))
102 node->type = mir_wired_headphone;
106 else if (!strcasecmp(form, "microphone")) {
107 if (node->direction == mir_input) {
108 node->location = mir_external;
109 node->type = mir_microphone;
112 else if (!strcasecmp(form, "phone")) {
113 if (bus && !strcasecmp(bus,"bluetooth") && prof) {
114 if (!strcmp(prof->name, "a2dp"))
115 node->type = mir_bluetooth_a2dp;
116 else if (!strcmp(prof->name, "hsp"))
117 node->type = mir_bluetooth_sco;
118 else if (!strcmp(prof->name, "hfgw"))
119 node->type = mir_bluetooth_carkit;
120 else if (!strcmp(prof->name, "a2dp_source"))
121 node->type = mir_bluetooth_source;
122 else if (!strcmp(prof->name, "a2dp_sink"))
123 node->type = mir_bluetooth_sink;
125 if (node->type != mir_node_type_unknown)
126 node->location = mir_external;
131 if (port && !strcasecmp(bus, "pci")) {
132 pa_classify_guess_device_node_type_and_name(node, port->name,
135 else if (prof && !strcasecmp(bus, "bluetooth")) {
136 if (!strcmp(prof->name, "a2dp"))
137 node->type = mir_bluetooth_a2dp;
138 else if (!strcmp(prof->name, "hsp"))
139 node->type = mir_bluetooth_sco;
140 else if (!strcmp(prof->name, "hfgw"))
141 node->type = mir_bluetooth_carkit;
142 else if (!strcmp(prof->name, "a2dp_source"))
143 node->type = mir_bluetooth_source;
144 else if (!strcmp(prof->name, "a2dp_sink"))
145 node->type = mir_bluetooth_sink;
149 if (!node->amname[0]) {
150 if (node->type != mir_node_type_unknown)
151 node->amname = (char *)mir_node_type_str(node->type);
152 else if (port && port->description)
153 node->amname = port->description;
154 else if (port && port->name)
155 node->amname = port->name;
157 node->amname = node->paname;
161 if (node->direction == mir_input)
162 node->privacy = mir_privacy_unknown;
164 switch (node->type) {
168 case mir_front_speakers:
169 case mir_rear_speakers:
170 node->privacy = mir_public;
175 case mir_wired_headset:
176 case mir_wired_headphone:
177 case mir_usb_headset:
178 case mir_usb_headphone:
179 case mir_bluetooth_sco:
180 case mir_bluetooth_a2dp:
181 node->privacy = mir_private;
189 case mir_bluetooth_sink:
190 node->privacy = mir_privacy_unknown;
196 pa_bool_t pa_classify_node_by_property(mir_node *node, pa_proplist *pl)
203 static type_mapping_t map[] = {
204 {"speakers" , mir_speakers },
205 {"front-speakers", mir_front_speakers },
206 {"rear-speakers" , mir_rear_speakers },
207 {"microphone" , mir_microphone },
208 {"jack" , mir_jack },
209 {"hdmi" , mir_hdmi },
210 {"spdif" , mir_spdif },
211 { NULL , mir_node_type_unknown}
220 if ((type = pa_proplist_gets(pl, PA_PROP_NODE_TYPE))) {
221 for (i = 0; map[i].name; i++) {
222 if (pa_streq(type, map[i].name)) {
223 node->type = map[i].value;
232 /* data->direction must be set */
233 void pa_classify_guess_device_node_type_and_name(mir_node *node,
241 if (node->direction == mir_output && strcasestr(name, "headphone")) {
242 node->type = mir_wired_headphone;
243 node->amname = (char *)desc;
245 else if (strcasestr(name, "headset")) {
246 node->type = mir_wired_headset;
247 node->amname = (char *)desc;
249 else if (strcasestr(name, "line")) {
250 node->type = mir_jack;
251 node->amname = (char *)desc;
253 else if (strcasestr(name, "spdif")) {
254 node->type = mir_spdif;
255 node->amname = (char *)desc;
257 else if (strcasestr(name, "hdmi")) {
258 node->type = mir_hdmi;
259 node->amname = (char *)desc;
261 else if (node->direction == mir_input && strcasestr(name, "microphone")) {
262 node->type = mir_microphone;
263 node->amname = (char *)desc;
265 else if (node->direction == mir_output && strcasestr(name,"analog-output"))
266 node->type = mir_speakers;
267 else if (node->direction == mir_input && strcasestr(name, "analog-input"))
268 node->type = mir_jack;
270 node->type = mir_node_type_unknown;
275 mir_node_type pa_classify_guess_stream_node_type(struct userdata *u,
277 pa_nodeset_resdef **resdef)
288 if ((bin = pa_proplist_gets(pl, PA_PROP_APPLICATION_PROCESS_BINARY)) &&
289 (map = pa_nodeset_get_map_by_binary(u, bin)))
292 if ((role = pa_proplist_gets(pl, PA_PROP_MEDIA_ROLE)) &&
293 (map = pa_nodeset_get_map_by_role(u, role)))
299 return role ? mir_node_type_unknown : mir_player;
304 *resdef = map->resdef;
309 mir_node_type pa_classify_guess_application_class(mir_node *node)
315 if (node->implement == mir_stream)
318 if (node->direction == mir_output)
319 class = mir_node_type_unknown;
321 switch (node->type) {
322 default: class = mir_node_type_unknown; break;
323 case mir_bluetooth_carkit: class = mir_phone; break;
324 case mir_bluetooth_source: class = mir_player; break;
333 pa_bool_t pa_classify_multiplex_stream(mir_node *node)
335 static pa_bool_t multiplex[mir_application_class_end] = {
336 [ mir_player ] = TRUE,
344 if (node->implement == mir_stream && node->direction == mir_input) {
347 if (class > mir_application_class_begin &&
348 class < mir_application_class_end)
350 return multiplex[class];
357 const char *pa_classify_loopback_stream(mir_node *node)
359 const char *role[mir_device_class_end - mir_device_class_begin] = {
360 [ mir_bluetooth_carkit - mir_device_class_begin ] = "phone",
361 [ mir_bluetooth_source - mir_device_class_begin ] = "music" ,
368 if (node->implement == mir_device) {
371 if (class >= mir_device_class_begin && class < mir_device_class_end) {
372 return role[class - mir_device_class_begin];
382 * indent-tabs-mode: nil