2 This file is part of PulseAudio.
4 Copyright 2005-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #include <pulse/xmalloc.h>
32 #include <pulse/i18n.h>
33 #include <pulsecore/core-util.h>
34 #include <pulsecore/macro.h>
35 #include <pulsecore/bitset.h>
37 #include "channelmap.h"
39 const char *const table[PA_CHANNEL_POSITION_MAX] = {
40 [PA_CHANNEL_POSITION_MONO] = "mono",
42 [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
43 [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
44 [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
46 [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
47 [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
48 [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
50 [PA_CHANNEL_POSITION_LFE] = "lfe",
52 [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
53 [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
55 [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
56 [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right",
58 [PA_CHANNEL_POSITION_AUX0] = "aux0",
59 [PA_CHANNEL_POSITION_AUX1] = "aux1",
60 [PA_CHANNEL_POSITION_AUX2] = "aux2",
61 [PA_CHANNEL_POSITION_AUX3] = "aux3",
62 [PA_CHANNEL_POSITION_AUX4] = "aux4",
63 [PA_CHANNEL_POSITION_AUX5] = "aux5",
64 [PA_CHANNEL_POSITION_AUX6] = "aux6",
65 [PA_CHANNEL_POSITION_AUX7] = "aux7",
66 [PA_CHANNEL_POSITION_AUX8] = "aux8",
67 [PA_CHANNEL_POSITION_AUX9] = "aux9",
68 [PA_CHANNEL_POSITION_AUX10] = "aux10",
69 [PA_CHANNEL_POSITION_AUX11] = "aux11",
70 [PA_CHANNEL_POSITION_AUX12] = "aux12",
71 [PA_CHANNEL_POSITION_AUX13] = "aux13",
72 [PA_CHANNEL_POSITION_AUX14] = "aux14",
73 [PA_CHANNEL_POSITION_AUX15] = "aux15",
74 [PA_CHANNEL_POSITION_AUX16] = "aux16",
75 [PA_CHANNEL_POSITION_AUX17] = "aux17",
76 [PA_CHANNEL_POSITION_AUX18] = "aux18",
77 [PA_CHANNEL_POSITION_AUX19] = "aux19",
78 [PA_CHANNEL_POSITION_AUX20] = "aux20",
79 [PA_CHANNEL_POSITION_AUX21] = "aux21",
80 [PA_CHANNEL_POSITION_AUX22] = "aux22",
81 [PA_CHANNEL_POSITION_AUX23] = "aux23",
82 [PA_CHANNEL_POSITION_AUX24] = "aux24",
83 [PA_CHANNEL_POSITION_AUX25] = "aux25",
84 [PA_CHANNEL_POSITION_AUX26] = "aux26",
85 [PA_CHANNEL_POSITION_AUX27] = "aux27",
86 [PA_CHANNEL_POSITION_AUX28] = "aux28",
87 [PA_CHANNEL_POSITION_AUX29] = "aux29",
88 [PA_CHANNEL_POSITION_AUX30] = "aux30",
89 [PA_CHANNEL_POSITION_AUX31] = "aux31",
91 [PA_CHANNEL_POSITION_TOP_CENTER] = "top-center",
93 [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center",
94 [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "top-front-left",
95 [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "top-front-right",
97 [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center",
98 [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "top-rear-left",
99 [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right"
102 const char *const pretty_table[PA_CHANNEL_POSITION_MAX] = {
103 [PA_CHANNEL_POSITION_MONO] = N_("Mono"),
105 [PA_CHANNEL_POSITION_FRONT_CENTER] = N_("Front Center"),
106 [PA_CHANNEL_POSITION_FRONT_LEFT] = N_("Front Left"),
107 [PA_CHANNEL_POSITION_FRONT_RIGHT] = N_("Front Right"),
109 [PA_CHANNEL_POSITION_REAR_CENTER] = N_("Rear Center"),
110 [PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"),
111 [PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"),
113 [PA_CHANNEL_POSITION_LFE] = N_("Low Frequency Emmiter"),
115 [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = N_("Front Left-of-center"),
116 [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = N_("Front Right-of-center"),
118 [PA_CHANNEL_POSITION_SIDE_LEFT] = N_("Side Left"),
119 [PA_CHANNEL_POSITION_SIDE_RIGHT] = N_("Side Right"),
121 [PA_CHANNEL_POSITION_AUX0] = N_("Auxiliary 0"),
122 [PA_CHANNEL_POSITION_AUX1] = N_("Auxiliary 1"),
123 [PA_CHANNEL_POSITION_AUX2] = N_("Auxiliary 2"),
124 [PA_CHANNEL_POSITION_AUX3] = N_("Auxiliary 3"),
125 [PA_CHANNEL_POSITION_AUX4] = N_("Auxiliary 4"),
126 [PA_CHANNEL_POSITION_AUX5] = N_("Auxiliary 5"),
127 [PA_CHANNEL_POSITION_AUX6] = N_("Auxiliary 6"),
128 [PA_CHANNEL_POSITION_AUX7] = N_("Auxiliary 7"),
129 [PA_CHANNEL_POSITION_AUX8] = N_("Auxiliary 8"),
130 [PA_CHANNEL_POSITION_AUX9] = N_("Auxiliary 9"),
131 [PA_CHANNEL_POSITION_AUX10] = N_("Auxiliary 10"),
132 [PA_CHANNEL_POSITION_AUX11] = N_("Auxiliary 11"),
133 [PA_CHANNEL_POSITION_AUX12] = N_("Auxiliary 12"),
134 [PA_CHANNEL_POSITION_AUX13] = N_("Auxiliary 13"),
135 [PA_CHANNEL_POSITION_AUX14] = N_("Auxiliary 14"),
136 [PA_CHANNEL_POSITION_AUX15] = N_("Auxiliary 15"),
137 [PA_CHANNEL_POSITION_AUX16] = N_("Auxiliary 16"),
138 [PA_CHANNEL_POSITION_AUX17] = N_("Auxiliary 17"),
139 [PA_CHANNEL_POSITION_AUX18] = N_("Auxiliary 18"),
140 [PA_CHANNEL_POSITION_AUX19] = N_("Auxiliary 19"),
141 [PA_CHANNEL_POSITION_AUX20] = N_("Auxiliary 20"),
142 [PA_CHANNEL_POSITION_AUX21] = N_("Auxiliary 21"),
143 [PA_CHANNEL_POSITION_AUX22] = N_("Auxiliary 22"),
144 [PA_CHANNEL_POSITION_AUX23] = N_("Auxiliary 23"),
145 [PA_CHANNEL_POSITION_AUX24] = N_("Auxiliary 24"),
146 [PA_CHANNEL_POSITION_AUX25] = N_("Auxiliary 25"),
147 [PA_CHANNEL_POSITION_AUX26] = N_("Auxiliary 26"),
148 [PA_CHANNEL_POSITION_AUX27] = N_("Auxiliary 27"),
149 [PA_CHANNEL_POSITION_AUX28] = N_("Auxiliary 28"),
150 [PA_CHANNEL_POSITION_AUX29] = N_("Auxiliary 29"),
151 [PA_CHANNEL_POSITION_AUX30] = N_("Auxiliary 30"),
152 [PA_CHANNEL_POSITION_AUX31] = N_("Auxiliary 31"),
154 [PA_CHANNEL_POSITION_TOP_CENTER] = N_("Top Center"),
156 [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = N_("Top Front Center"),
157 [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = N_("Top Front Left"),
158 [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = N_("Top Front Right"),
160 [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = N_("Top Rear Center"),
161 [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = N_("Top Rear Left"),
162 [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = N_("Top Rear Right")
165 pa_channel_map* pa_channel_map_init(pa_channel_map *m) {
171 for (c = 0; c < PA_CHANNELS_MAX; c++)
172 m->map[c] = PA_CHANNEL_POSITION_INVALID;
177 pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) {
180 pa_channel_map_init(m);
183 m->map[0] = PA_CHANNEL_POSITION_MONO;
187 pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) {
190 pa_channel_map_init(m);
193 m->map[0] = PA_CHANNEL_POSITION_LEFT;
194 m->map[1] = PA_CHANNEL_POSITION_RIGHT;
198 pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) {
200 pa_assert(channels > 0);
201 pa_assert(channels <= PA_CHANNELS_MAX);
202 pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
204 pa_channel_map_init(m);
206 m->channels = (uint8_t) channels;
209 case PA_CHANNEL_MAP_AIFF:
211 /* This is somewhat compatible with RFC3551 */
215 m->map[0] = PA_CHANNEL_POSITION_MONO;
219 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
220 m->map[1] = PA_CHANNEL_POSITION_REAR_LEFT;
221 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
222 m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT;
223 m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
224 m->map[5] = PA_CHANNEL_POSITION_LFE;
228 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
229 m->map[3] = PA_CHANNEL_POSITION_REAR_LEFT;
230 m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
234 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
235 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
239 m->map[0] = PA_CHANNEL_POSITION_LEFT;
240 m->map[1] = PA_CHANNEL_POSITION_RIGHT;
241 m->map[2] = PA_CHANNEL_POSITION_CENTER;
245 m->map[0] = PA_CHANNEL_POSITION_LEFT;
246 m->map[1] = PA_CHANNEL_POSITION_CENTER;
247 m->map[2] = PA_CHANNEL_POSITION_RIGHT;
248 m->map[3] = PA_CHANNEL_POSITION_LFE;
255 case PA_CHANNEL_MAP_ALSA:
259 m->map[0] = PA_CHANNEL_POSITION_MONO;
263 m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
264 m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
268 m->map[5] = PA_CHANNEL_POSITION_LFE;
272 m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
276 m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
277 m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
281 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
282 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
289 case PA_CHANNEL_MAP_AUX: {
292 for (i = 0; i < channels; i++)
293 m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
298 case PA_CHANNEL_MAP_WAVEEX:
302 m->map[0] = PA_CHANNEL_POSITION_MONO;
306 m->map[15] = PA_CHANNEL_POSITION_TOP_REAR_LEFT;
307 m->map[16] = PA_CHANNEL_POSITION_TOP_REAR_CENTER;
308 m->map[17] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
312 m->map[12] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT;
313 m->map[13] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER;
314 m->map[14] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT;
318 m->map[11] = PA_CHANNEL_POSITION_TOP_CENTER;
322 m->map[9] = PA_CHANNEL_POSITION_SIDE_LEFT;
323 m->map[10] = PA_CHANNEL_POSITION_SIDE_RIGHT;
327 m->map[8] = PA_CHANNEL_POSITION_REAR_CENTER;
331 m->map[6] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
332 m->map[7] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
336 m->map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
337 m->map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
341 m->map[3] = PA_CHANNEL_POSITION_LFE;
345 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
349 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
350 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
357 case PA_CHANNEL_MAP_OSS:
361 m->map[0] = PA_CHANNEL_POSITION_MONO;
365 m->map[6] = PA_CHANNEL_POSITION_REAR_LEFT;
366 m->map[7] = PA_CHANNEL_POSITION_REAR_RIGHT;
370 m->map[4] = PA_CHANNEL_POSITION_SIDE_LEFT;
371 m->map[5] = PA_CHANNEL_POSITION_SIDE_RIGHT;
375 m->map[3] = PA_CHANNEL_POSITION_LFE;
379 m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
383 m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
384 m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
393 pa_assert_not_reached();
397 pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) {
401 pa_assert(channels > 0);
402 pa_assert(channels <= PA_CHANNELS_MAX);
403 pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
405 pa_channel_map_init(m);
407 for (c = channels; c > 0; c--) {
409 if (pa_channel_map_init_auto(m, c, def)) {
412 for (; c < channels; c++) {
414 m->map[c] = PA_CHANNEL_POSITION_AUX0 + i;
418 m->channels = (uint8_t) channels;
427 const char* pa_channel_position_to_string(pa_channel_position_t pos) {
429 if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
435 const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) {
437 if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
442 return _(pretty_table[pos]);
445 int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
451 pa_return_val_if_fail(pa_channel_map_valid(a), 0);
452 pa_return_val_if_fail(pa_channel_map_valid(b), 0);
454 if (a->channels != b->channels)
457 for (c = 0; c < a->channels; c++)
458 if (a->map[c] != b->map[c])
464 char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
466 pa_bool_t first = TRUE;
475 if (!pa_channel_map_valid(map)) {
476 pa_snprintf(s, l, _("(invalid)"));
482 for (channel = 0; channel < map->channels && l > 1; channel++) {
483 l -= pa_snprintf(e, l, "%s%s",
485 pa_channel_position_to_string(map->map[channel]));
494 pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
502 pa_channel_map_init(&map);
504 /* We don't need to match against the well known channel mapping
505 * "mono" here explicitly, because that can be understood as
506 * listing with one channel called "mono". */
508 if (pa_streq(s, "stereo")) {
510 map.map[0] = PA_CHANNEL_POSITION_LEFT;
511 map.map[1] = PA_CHANNEL_POSITION_RIGHT;
513 } else if (pa_streq(s, "surround-40")) {
515 map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
516 map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
517 map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
518 map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
520 } else if (pa_streq(s, "surround-41")) {
522 map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
523 map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
524 map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
525 map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
526 map.map[4] = PA_CHANNEL_POSITION_LFE;
528 } else if (pa_streq(s, "surround-50")) {
530 map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
531 map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
532 map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
533 map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
534 map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
536 } else if (pa_streq(s, "surround-51")) {
538 map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
539 map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
540 map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
541 map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
542 map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
543 map.map[5] = PA_CHANNEL_POSITION_LFE;
545 } else if (pa_streq(s, "surround-71")) {
547 map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
548 map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
549 map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
550 map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
551 map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
552 map.map[5] = PA_CHANNEL_POSITION_LFE;
553 map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
554 map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
561 while ((p = pa_split(s, ",", &state))) {
563 if (map.channels >= PA_CHANNELS_MAX) {
568 /* Some special aliases */
569 if (pa_streq(p, "left"))
570 map.map[map.channels++] = PA_CHANNEL_POSITION_LEFT;
571 else if (pa_streq(p, "right"))
572 map.map[map.channels++] = PA_CHANNEL_POSITION_RIGHT;
573 else if (pa_streq(p, "center"))
574 map.map[map.channels++] = PA_CHANNEL_POSITION_CENTER;
575 else if (pa_streq(p, "subwoofer"))
576 map.map[map.channels++] = PA_CHANNEL_POSITION_SUBWOOFER;
578 pa_channel_position_t i;
580 for (i = 0; i < PA_CHANNEL_POSITION_MAX; i++)
581 if (strcmp(p, table[i]) == 0) {
582 map.map[map.channels++] = i;
586 if (i >= PA_CHANNEL_POSITION_MAX) {
597 if (!pa_channel_map_valid(&map))
604 int pa_channel_map_valid(const pa_channel_map *map) {
609 if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
612 for (c = 0; c < map->channels; c++)
613 if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
619 int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
623 pa_return_val_if_fail(pa_channel_map_valid(map), 0);
624 pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
626 return map->channels == ss->channels;
629 int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) {
630 pa_bitset_t in_a[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)];
636 pa_return_val_if_fail(pa_channel_map_valid(a), 0);
637 pa_return_val_if_fail(pa_channel_map_valid(b), 0);
639 memset(in_a, 0, sizeof(in_a));
641 for (i = 0; i < a->channels; i++)
642 pa_bitset_set(in_a, a->map[i], TRUE);
644 for (i = 0; i < b->channels; i++)
645 if (!pa_bitset_get(in_a, b->map[i]))
651 int pa_channel_map_can_balance(const pa_channel_map *map) {
653 pa_bool_t left = FALSE, right = FALSE;
657 pa_return_val_if_fail(pa_channel_map_valid(map), 0);
659 for (c = 0; c < map->channels; c++) {
661 switch (map->map[c]) {
662 case PA_CHANNEL_POSITION_LEFT:
663 case PA_CHANNEL_POSITION_REAR_LEFT:
664 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
665 case PA_CHANNEL_POSITION_SIDE_LEFT:
666 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
667 case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
671 case PA_CHANNEL_POSITION_RIGHT:
672 case PA_CHANNEL_POSITION_REAR_RIGHT:
673 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
674 case PA_CHANNEL_POSITION_SIDE_RIGHT:
675 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
676 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
691 int pa_channel_map_can_fade(const pa_channel_map *map) {
693 pa_bool_t front = FALSE, rear = FALSE;
697 pa_return_val_if_fail(pa_channel_map_valid(map), 0);
699 for (c = 0; c < map->channels; c++) {
701 switch (map->map[c]) {
702 case PA_CHANNEL_POSITION_FRONT_LEFT:
703 case PA_CHANNEL_POSITION_FRONT_RIGHT:
704 case PA_CHANNEL_POSITION_FRONT_CENTER:
705 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
706 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
707 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
708 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
709 case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:
713 case PA_CHANNEL_POSITION_REAR_LEFT:
714 case PA_CHANNEL_POSITION_REAR_RIGHT:
715 case PA_CHANNEL_POSITION_REAR_CENTER:
716 case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
717 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
718 case PA_CHANNEL_POSITION_TOP_REAR_CENTER:
733 const char* pa_channel_map_to_name(const pa_channel_map *map) {
734 pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)];
739 pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
741 memset(in_map, 0, sizeof(in_map));
743 for (c = 0; c < map->channels; c++)
744 pa_bitset_set(in_map, map->map[c], TRUE);
746 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
747 PA_CHANNEL_POSITION_MONO, -1))
750 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
751 PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1))
754 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
755 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
756 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1))
757 return "surround-40";
759 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
760 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
761 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
762 PA_CHANNEL_POSITION_LFE, -1))
763 return "surround-41";
765 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
766 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
767 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
768 PA_CHANNEL_POSITION_FRONT_CENTER, -1))
769 return "surround-50";
771 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
772 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
773 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
774 PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1))
775 return "surround-51";
777 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
778 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
779 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
780 PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
781 PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1))
782 return "surround-71";
787 const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
788 pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)];
793 pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
795 memset(in_map, 0, sizeof(in_map));
797 for (c = 0; c < map->channels; c++)
798 pa_bitset_set(in_map, map->map[c], TRUE);
802 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
803 PA_CHANNEL_POSITION_MONO, -1))
806 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
807 PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1))
810 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
811 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
812 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1))
813 return _("Surround 4.0");
815 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
816 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
817 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
818 PA_CHANNEL_POSITION_LFE, -1))
819 return _("Surround 4.1");
821 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
822 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
823 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
824 PA_CHANNEL_POSITION_FRONT_CENTER, -1))
825 return _("Surround 5.0");
827 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
828 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
829 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
830 PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1))
831 return _("Surround 5.1");
833 if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
834 PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT,
835 PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT,
836 PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE,
837 PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1))
838 return _("Surround 7.1");
843 int pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t p) {
846 pa_return_val_if_fail(pa_channel_map_valid(map), 0);
847 pa_return_val_if_fail(p < PA_CHANNEL_POSITION_MAX, 0);
849 for (c = 0; c < map->channels; c++)
850 if (map->map[c] == p)