153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2005-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB 653a5a1b3Sopenharmony_ci 753a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 853a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 953a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 1053a5a1b3Sopenharmony_ci or (at your option) any later version. 1153a5a1b3Sopenharmony_ci 1253a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1353a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1453a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1553a5a1b3Sopenharmony_ci General Public License for more details. 1653a5a1b3Sopenharmony_ci 1753a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1853a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1953a5a1b3Sopenharmony_ci***/ 2053a5a1b3Sopenharmony_ci 2153a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2253a5a1b3Sopenharmony_ci#include <config.h> 2353a5a1b3Sopenharmony_ci#endif 2453a5a1b3Sopenharmony_ci 2553a5a1b3Sopenharmony_ci#include <stdlib.h> 2653a5a1b3Sopenharmony_ci#include <stdio.h> 2753a5a1b3Sopenharmony_ci#include <string.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 3053a5a1b3Sopenharmony_ci 3153a5a1b3Sopenharmony_ci#include <pulsecore/i18n.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/bitset.h> 3553a5a1b3Sopenharmony_ci#include <pulsecore/sample-util.h> 3653a5a1b3Sopenharmony_ci 3753a5a1b3Sopenharmony_ci#include "channelmap.h" 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_cistatic const char *const table[PA_CHANNEL_POSITION_MAX] = { 4053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_MONO] = "mono", 4153a5a1b3Sopenharmony_ci 4253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center", 4353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left", 4453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right", 4553a5a1b3Sopenharmony_ci 4653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center", 4753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left", 4853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right", 4953a5a1b3Sopenharmony_ci 5053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_LFE] = "lfe", 5153a5a1b3Sopenharmony_ci 5253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center", 5353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center", 5453a5a1b3Sopenharmony_ci 5553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left", 5653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right", 5753a5a1b3Sopenharmony_ci 5853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX0] = "aux0", 5953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX1] = "aux1", 6053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX2] = "aux2", 6153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX3] = "aux3", 6253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX4] = "aux4", 6353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX5] = "aux5", 6453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX6] = "aux6", 6553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX7] = "aux7", 6653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX8] = "aux8", 6753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX9] = "aux9", 6853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX10] = "aux10", 6953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX11] = "aux11", 7053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX12] = "aux12", 7153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX13] = "aux13", 7253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX14] = "aux14", 7353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX15] = "aux15", 7453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX16] = "aux16", 7553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX17] = "aux17", 7653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX18] = "aux18", 7753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX19] = "aux19", 7853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX20] = "aux20", 7953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX21] = "aux21", 8053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX22] = "aux22", 8153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX23] = "aux23", 8253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX24] = "aux24", 8353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX25] = "aux25", 8453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX26] = "aux26", 8553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX27] = "aux27", 8653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX28] = "aux28", 8753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX29] = "aux29", 8853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX30] = "aux30", 8953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX31] = "aux31", 9053a5a1b3Sopenharmony_ci 9153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_CENTER] = "top-center", 9253a5a1b3Sopenharmony_ci 9353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center", 9453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "top-front-left", 9553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "top-front-right", 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center", 9853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "top-rear-left", 9953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right" 10053a5a1b3Sopenharmony_ci}; 10153a5a1b3Sopenharmony_ci 10253a5a1b3Sopenharmony_cistatic const char *const pretty_table[PA_CHANNEL_POSITION_MAX] = { 10353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_MONO] = N_("Mono"), 10453a5a1b3Sopenharmony_ci 10553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_CENTER] = N_("Front Center"), 10653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_LEFT] = N_("Front Left"), 10753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_RIGHT] = N_("Front Right"), 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_CENTER] = N_("Rear Center"), 11053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"), 11153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"), 11253a5a1b3Sopenharmony_ci 11353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_LFE] = N_("Subwoofer"), 11453a5a1b3Sopenharmony_ci 11553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = N_("Front Left-of-center"), 11653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = N_("Front Right-of-center"), 11753a5a1b3Sopenharmony_ci 11853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_SIDE_LEFT] = N_("Side Left"), 11953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_SIDE_RIGHT] = N_("Side Right"), 12053a5a1b3Sopenharmony_ci 12153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX0] = N_("Auxiliary 0"), 12253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX1] = N_("Auxiliary 1"), 12353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX2] = N_("Auxiliary 2"), 12453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX3] = N_("Auxiliary 3"), 12553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX4] = N_("Auxiliary 4"), 12653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX5] = N_("Auxiliary 5"), 12753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX6] = N_("Auxiliary 6"), 12853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX7] = N_("Auxiliary 7"), 12953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX8] = N_("Auxiliary 8"), 13053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX9] = N_("Auxiliary 9"), 13153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX10] = N_("Auxiliary 10"), 13253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX11] = N_("Auxiliary 11"), 13353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX12] = N_("Auxiliary 12"), 13453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX13] = N_("Auxiliary 13"), 13553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX14] = N_("Auxiliary 14"), 13653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX15] = N_("Auxiliary 15"), 13753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX16] = N_("Auxiliary 16"), 13853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX17] = N_("Auxiliary 17"), 13953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX18] = N_("Auxiliary 18"), 14053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX19] = N_("Auxiliary 19"), 14153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX20] = N_("Auxiliary 20"), 14253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX21] = N_("Auxiliary 21"), 14353a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX22] = N_("Auxiliary 22"), 14453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX23] = N_("Auxiliary 23"), 14553a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX24] = N_("Auxiliary 24"), 14653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX25] = N_("Auxiliary 25"), 14753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX26] = N_("Auxiliary 26"), 14853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX27] = N_("Auxiliary 27"), 14953a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX28] = N_("Auxiliary 28"), 15053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX29] = N_("Auxiliary 29"), 15153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX30] = N_("Auxiliary 30"), 15253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_AUX31] = N_("Auxiliary 31"), 15353a5a1b3Sopenharmony_ci 15453a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_CENTER] = N_("Top Center"), 15553a5a1b3Sopenharmony_ci 15653a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = N_("Top Front Center"), 15753a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = N_("Top Front Left"), 15853a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = N_("Top Front Right"), 15953a5a1b3Sopenharmony_ci 16053a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = N_("Top Rear Center"), 16153a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = N_("Top Rear Left"), 16253a5a1b3Sopenharmony_ci [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = N_("Top Rear Right") 16353a5a1b3Sopenharmony_ci}; 16453a5a1b3Sopenharmony_ci 16553a5a1b3Sopenharmony_cipa_channel_map* pa_channel_map_init(pa_channel_map *m) { 16653a5a1b3Sopenharmony_ci unsigned c; 16753a5a1b3Sopenharmony_ci pa_assert(m); 16853a5a1b3Sopenharmony_ci 16953a5a1b3Sopenharmony_ci m->channels = 0; 17053a5a1b3Sopenharmony_ci 17153a5a1b3Sopenharmony_ci for (c = 0; c < PA_CHANNELS_MAX; c++) 17253a5a1b3Sopenharmony_ci m->map[c] = PA_CHANNEL_POSITION_INVALID; 17353a5a1b3Sopenharmony_ci 17453a5a1b3Sopenharmony_ci return m; 17553a5a1b3Sopenharmony_ci} 17653a5a1b3Sopenharmony_ci 17753a5a1b3Sopenharmony_cipa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) { 17853a5a1b3Sopenharmony_ci pa_assert(m); 17953a5a1b3Sopenharmony_ci 18053a5a1b3Sopenharmony_ci pa_channel_map_init(m); 18153a5a1b3Sopenharmony_ci 18253a5a1b3Sopenharmony_ci m->channels = 1; 18353a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_MONO; 18453a5a1b3Sopenharmony_ci return m; 18553a5a1b3Sopenharmony_ci} 18653a5a1b3Sopenharmony_ci 18753a5a1b3Sopenharmony_cipa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) { 18853a5a1b3Sopenharmony_ci pa_assert(m); 18953a5a1b3Sopenharmony_ci 19053a5a1b3Sopenharmony_ci pa_channel_map_init(m); 19153a5a1b3Sopenharmony_ci 19253a5a1b3Sopenharmony_ci m->channels = 2; 19353a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_LEFT; 19453a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_RIGHT; 19553a5a1b3Sopenharmony_ci return m; 19653a5a1b3Sopenharmony_ci} 19753a5a1b3Sopenharmony_ci 19853a5a1b3Sopenharmony_cipa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) { 19953a5a1b3Sopenharmony_ci pa_assert(m); 20053a5a1b3Sopenharmony_ci pa_assert(pa_channels_valid(channels)); 20153a5a1b3Sopenharmony_ci pa_assert(def < PA_CHANNEL_MAP_DEF_MAX); 20253a5a1b3Sopenharmony_ci 20353a5a1b3Sopenharmony_ci pa_channel_map_init(m); 20453a5a1b3Sopenharmony_ci 20553a5a1b3Sopenharmony_ci m->channels = (uint8_t) channels; 20653a5a1b3Sopenharmony_ci 20753a5a1b3Sopenharmony_ci switch (def) { 20853a5a1b3Sopenharmony_ci case PA_CHANNEL_MAP_AIFF: 20953a5a1b3Sopenharmony_ci 21053a5a1b3Sopenharmony_ci /* This is somewhat compatible with RFC3551 */ 21153a5a1b3Sopenharmony_ci 21253a5a1b3Sopenharmony_ci switch (channels) { 21353a5a1b3Sopenharmony_ci case 1: 21453a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_MONO; 21553a5a1b3Sopenharmony_ci return m; 21653a5a1b3Sopenharmony_ci 21753a5a1b3Sopenharmony_ci case 6: 21853a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 21953a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; 22053a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; 22153a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT; 22253a5a1b3Sopenharmony_ci m->map[4] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; 22353a5a1b3Sopenharmony_ci m->map[5] = PA_CHANNEL_POSITION_REAR_CENTER; 22453a5a1b3Sopenharmony_ci return m; 22553a5a1b3Sopenharmony_ci 22653a5a1b3Sopenharmony_ci case 5: 22753a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; 22853a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_REAR_LEFT; 22953a5a1b3Sopenharmony_ci m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT; 23053a5a1b3Sopenharmony_ci /* Fall through */ 23153a5a1b3Sopenharmony_ci 23253a5a1b3Sopenharmony_ci case 2: 23353a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 23453a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 23553a5a1b3Sopenharmony_ci return m; 23653a5a1b3Sopenharmony_ci 23753a5a1b3Sopenharmony_ci case 3: 23853a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_LEFT; 23953a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_RIGHT; 24053a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_CENTER; 24153a5a1b3Sopenharmony_ci return m; 24253a5a1b3Sopenharmony_ci 24353a5a1b3Sopenharmony_ci case 4: 24453a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_LEFT; 24553a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_CENTER; 24653a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_RIGHT; 24753a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_REAR_CENTER; 24853a5a1b3Sopenharmony_ci return m; 24953a5a1b3Sopenharmony_ci 25053a5a1b3Sopenharmony_ci default: 25153a5a1b3Sopenharmony_ci return NULL; 25253a5a1b3Sopenharmony_ci } 25353a5a1b3Sopenharmony_ci 25453a5a1b3Sopenharmony_ci case PA_CHANNEL_MAP_ALSA: 25553a5a1b3Sopenharmony_ci 25653a5a1b3Sopenharmony_ci switch (channels) { 25753a5a1b3Sopenharmony_ci case 1: 25853a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_MONO; 25953a5a1b3Sopenharmony_ci return m; 26053a5a1b3Sopenharmony_ci 26153a5a1b3Sopenharmony_ci case 8: 26253a5a1b3Sopenharmony_ci m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT; 26353a5a1b3Sopenharmony_ci m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT; 26453a5a1b3Sopenharmony_ci /* Fall through */ 26553a5a1b3Sopenharmony_ci 26653a5a1b3Sopenharmony_ci case 6: 26753a5a1b3Sopenharmony_ci m->map[5] = PA_CHANNEL_POSITION_LFE; 26853a5a1b3Sopenharmony_ci /* Fall through */ 26953a5a1b3Sopenharmony_ci 27053a5a1b3Sopenharmony_ci case 5: 27153a5a1b3Sopenharmony_ci m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; 27253a5a1b3Sopenharmony_ci /* Fall through */ 27353a5a1b3Sopenharmony_ci 27453a5a1b3Sopenharmony_ci case 4: 27553a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 27653a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 27753a5a1b3Sopenharmony_ci /* Fall through */ 27853a5a1b3Sopenharmony_ci 27953a5a1b3Sopenharmony_ci case 2: 28053a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 28153a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 28253a5a1b3Sopenharmony_ci return m; 28353a5a1b3Sopenharmony_ci 28453a5a1b3Sopenharmony_ci default: 28553a5a1b3Sopenharmony_ci return NULL; 28653a5a1b3Sopenharmony_ci } 28753a5a1b3Sopenharmony_ci 28853a5a1b3Sopenharmony_ci case PA_CHANNEL_MAP_AUX: { 28953a5a1b3Sopenharmony_ci unsigned i; 29053a5a1b3Sopenharmony_ci 29153a5a1b3Sopenharmony_ci for (i = 0; i < channels; i++) 29253a5a1b3Sopenharmony_ci m->map[i] = PA_CHANNEL_POSITION_AUX0 + i; 29353a5a1b3Sopenharmony_ci 29453a5a1b3Sopenharmony_ci return m; 29553a5a1b3Sopenharmony_ci } 29653a5a1b3Sopenharmony_ci 29753a5a1b3Sopenharmony_ci case PA_CHANNEL_MAP_WAVEEX: 29853a5a1b3Sopenharmony_ci 29953a5a1b3Sopenharmony_ci /* following: https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn653308(v=vs.85) */ 30053a5a1b3Sopenharmony_ci switch (channels) { 30153a5a1b3Sopenharmony_ci case 1: 30253a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_MONO; 30353a5a1b3Sopenharmony_ci return m; 30453a5a1b3Sopenharmony_ci 30553a5a1b3Sopenharmony_ci case 18: 30653a5a1b3Sopenharmony_ci m->map[15] = PA_CHANNEL_POSITION_TOP_REAR_LEFT; 30753a5a1b3Sopenharmony_ci m->map[16] = PA_CHANNEL_POSITION_TOP_REAR_CENTER; 30853a5a1b3Sopenharmony_ci m->map[17] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT; 30953a5a1b3Sopenharmony_ci /* Fall through */ 31053a5a1b3Sopenharmony_ci 31153a5a1b3Sopenharmony_ci case 15: 31253a5a1b3Sopenharmony_ci m->map[12] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT; 31353a5a1b3Sopenharmony_ci m->map[13] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER; 31453a5a1b3Sopenharmony_ci m->map[14] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT; 31553a5a1b3Sopenharmony_ci /* Fall through */ 31653a5a1b3Sopenharmony_ci 31753a5a1b3Sopenharmony_ci case 12: 31853a5a1b3Sopenharmony_ci m->map[11] = PA_CHANNEL_POSITION_TOP_CENTER; 31953a5a1b3Sopenharmony_ci /* Fall through */ 32053a5a1b3Sopenharmony_ci 32153a5a1b3Sopenharmony_ci case 11: 32253a5a1b3Sopenharmony_ci m->map[9] = PA_CHANNEL_POSITION_SIDE_LEFT; 32353a5a1b3Sopenharmony_ci m->map[10] = PA_CHANNEL_POSITION_SIDE_RIGHT; 32453a5a1b3Sopenharmony_ci /* Fall through */ 32553a5a1b3Sopenharmony_ci 32653a5a1b3Sopenharmony_ci case 9: 32753a5a1b3Sopenharmony_ci m->map[8] = PA_CHANNEL_POSITION_REAR_CENTER; 32853a5a1b3Sopenharmony_ci /* Fall through */ 32953a5a1b3Sopenharmony_ci 33053a5a1b3Sopenharmony_ci case 8: 33153a5a1b3Sopenharmony_ci m->map[6] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER; 33253a5a1b3Sopenharmony_ci m->map[7] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; 33353a5a1b3Sopenharmony_ci /* Fall through */ 33453a5a1b3Sopenharmony_ci 33553a5a1b3Sopenharmony_ci case 6: 33653a5a1b3Sopenharmony_ci m->map[4] = PA_CHANNEL_POSITION_REAR_LEFT; 33753a5a1b3Sopenharmony_ci m->map[5] = PA_CHANNEL_POSITION_REAR_RIGHT; 33853a5a1b3Sopenharmony_ci /* Fall through */ 33953a5a1b3Sopenharmony_ci 34053a5a1b3Sopenharmony_ci case 4: 34153a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_LFE; 34253a5a1b3Sopenharmony_ci /* Fall through */ 34353a5a1b3Sopenharmony_ci 34453a5a1b3Sopenharmony_ci case 3: 34553a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; 34653a5a1b3Sopenharmony_ci /* Fall through */ 34753a5a1b3Sopenharmony_ci 34853a5a1b3Sopenharmony_ci case 2: 34953a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 35053a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 35153a5a1b3Sopenharmony_ci return m; 35253a5a1b3Sopenharmony_ci 35353a5a1b3Sopenharmony_ci default: 35453a5a1b3Sopenharmony_ci return NULL; 35553a5a1b3Sopenharmony_ci } 35653a5a1b3Sopenharmony_ci 35753a5a1b3Sopenharmony_ci case PA_CHANNEL_MAP_OSS: 35853a5a1b3Sopenharmony_ci 35953a5a1b3Sopenharmony_ci switch (channels) { 36053a5a1b3Sopenharmony_ci case 1: 36153a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_MONO; 36253a5a1b3Sopenharmony_ci return m; 36353a5a1b3Sopenharmony_ci 36453a5a1b3Sopenharmony_ci case 8: 36553a5a1b3Sopenharmony_ci m->map[6] = PA_CHANNEL_POSITION_REAR_LEFT; 36653a5a1b3Sopenharmony_ci m->map[7] = PA_CHANNEL_POSITION_REAR_RIGHT; 36753a5a1b3Sopenharmony_ci /* Fall through */ 36853a5a1b3Sopenharmony_ci 36953a5a1b3Sopenharmony_ci case 6: 37053a5a1b3Sopenharmony_ci m->map[4] = PA_CHANNEL_POSITION_SIDE_LEFT; 37153a5a1b3Sopenharmony_ci m->map[5] = PA_CHANNEL_POSITION_SIDE_RIGHT; 37253a5a1b3Sopenharmony_ci /* Fall through */ 37353a5a1b3Sopenharmony_ci 37453a5a1b3Sopenharmony_ci case 4: 37553a5a1b3Sopenharmony_ci m->map[3] = PA_CHANNEL_POSITION_LFE; 37653a5a1b3Sopenharmony_ci /* Fall through */ 37753a5a1b3Sopenharmony_ci 37853a5a1b3Sopenharmony_ci case 3: 37953a5a1b3Sopenharmony_ci m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; 38053a5a1b3Sopenharmony_ci /* Fall through */ 38153a5a1b3Sopenharmony_ci 38253a5a1b3Sopenharmony_ci case 2: 38353a5a1b3Sopenharmony_ci m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 38453a5a1b3Sopenharmony_ci m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 38553a5a1b3Sopenharmony_ci return m; 38653a5a1b3Sopenharmony_ci 38753a5a1b3Sopenharmony_ci default: 38853a5a1b3Sopenharmony_ci return NULL; 38953a5a1b3Sopenharmony_ci } 39053a5a1b3Sopenharmony_ci 39153a5a1b3Sopenharmony_ci default: 39253a5a1b3Sopenharmony_ci pa_assert_not_reached(); 39353a5a1b3Sopenharmony_ci } 39453a5a1b3Sopenharmony_ci} 39553a5a1b3Sopenharmony_ci 39653a5a1b3Sopenharmony_cipa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) { 39753a5a1b3Sopenharmony_ci unsigned c; 39853a5a1b3Sopenharmony_ci 39953a5a1b3Sopenharmony_ci pa_assert(m); 40053a5a1b3Sopenharmony_ci pa_assert(pa_channels_valid(channels)); 40153a5a1b3Sopenharmony_ci pa_assert(def < PA_CHANNEL_MAP_DEF_MAX); 40253a5a1b3Sopenharmony_ci 40353a5a1b3Sopenharmony_ci pa_channel_map_init(m); 40453a5a1b3Sopenharmony_ci 40553a5a1b3Sopenharmony_ci for (c = channels; c > 0; c--) { 40653a5a1b3Sopenharmony_ci 40753a5a1b3Sopenharmony_ci if (pa_channel_map_init_auto(m, c, def)) { 40853a5a1b3Sopenharmony_ci unsigned i = 0; 40953a5a1b3Sopenharmony_ci 41053a5a1b3Sopenharmony_ci for (; c < channels; c++) { 41153a5a1b3Sopenharmony_ci 41253a5a1b3Sopenharmony_ci m->map[c] = PA_CHANNEL_POSITION_AUX0 + i; 41353a5a1b3Sopenharmony_ci i++; 41453a5a1b3Sopenharmony_ci } 41553a5a1b3Sopenharmony_ci 41653a5a1b3Sopenharmony_ci m->channels = (uint8_t) channels; 41753a5a1b3Sopenharmony_ci 41853a5a1b3Sopenharmony_ci return m; 41953a5a1b3Sopenharmony_ci } 42053a5a1b3Sopenharmony_ci } 42153a5a1b3Sopenharmony_ci 42253a5a1b3Sopenharmony_ci return NULL; 42353a5a1b3Sopenharmony_ci} 42453a5a1b3Sopenharmony_ci 42553a5a1b3Sopenharmony_ciconst char* pa_channel_position_to_string(pa_channel_position_t pos) { 42653a5a1b3Sopenharmony_ci 42753a5a1b3Sopenharmony_ci if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX) 42853a5a1b3Sopenharmony_ci return NULL; 42953a5a1b3Sopenharmony_ci 43053a5a1b3Sopenharmony_ci return table[pos]; 43153a5a1b3Sopenharmony_ci} 43253a5a1b3Sopenharmony_ci 43353a5a1b3Sopenharmony_ciconst char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) { 43453a5a1b3Sopenharmony_ci 43553a5a1b3Sopenharmony_ci if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX) 43653a5a1b3Sopenharmony_ci return NULL; 43753a5a1b3Sopenharmony_ci 43853a5a1b3Sopenharmony_ci pa_init_i18n(); 43953a5a1b3Sopenharmony_ci 44053a5a1b3Sopenharmony_ci return _(pretty_table[pos]); 44153a5a1b3Sopenharmony_ci} 44253a5a1b3Sopenharmony_ci 44353a5a1b3Sopenharmony_ciint pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { 44453a5a1b3Sopenharmony_ci unsigned c; 44553a5a1b3Sopenharmony_ci 44653a5a1b3Sopenharmony_ci pa_assert(a); 44753a5a1b3Sopenharmony_ci pa_assert(b); 44853a5a1b3Sopenharmony_ci 44953a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(a), 0); 45053a5a1b3Sopenharmony_ci 45153a5a1b3Sopenharmony_ci if (PA_UNLIKELY(a == b)) 45253a5a1b3Sopenharmony_ci return 1; 45353a5a1b3Sopenharmony_ci 45453a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(b), 0); 45553a5a1b3Sopenharmony_ci 45653a5a1b3Sopenharmony_ci if (a->channels != b->channels) 45753a5a1b3Sopenharmony_ci return 0; 45853a5a1b3Sopenharmony_ci 45953a5a1b3Sopenharmony_ci for (c = 0; c < a->channels; c++) 46053a5a1b3Sopenharmony_ci if (a->map[c] != b->map[c]) 46153a5a1b3Sopenharmony_ci return 0; 46253a5a1b3Sopenharmony_ci 46353a5a1b3Sopenharmony_ci return 1; 46453a5a1b3Sopenharmony_ci} 46553a5a1b3Sopenharmony_ci 46653a5a1b3Sopenharmony_cichar* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { 46753a5a1b3Sopenharmony_ci unsigned channel; 46853a5a1b3Sopenharmony_ci bool first = true; 46953a5a1b3Sopenharmony_ci char *e; 47053a5a1b3Sopenharmony_ci 47153a5a1b3Sopenharmony_ci pa_assert(s); 47253a5a1b3Sopenharmony_ci pa_assert(l > 0); 47353a5a1b3Sopenharmony_ci pa_assert(map); 47453a5a1b3Sopenharmony_ci 47553a5a1b3Sopenharmony_ci pa_init_i18n(); 47653a5a1b3Sopenharmony_ci 47753a5a1b3Sopenharmony_ci if (!pa_channel_map_valid(map)) { 47853a5a1b3Sopenharmony_ci pa_snprintf(s, l, _("(invalid)")); 47953a5a1b3Sopenharmony_ci return s; 48053a5a1b3Sopenharmony_ci } 48153a5a1b3Sopenharmony_ci 48253a5a1b3Sopenharmony_ci *(e = s) = 0; 48353a5a1b3Sopenharmony_ci 48453a5a1b3Sopenharmony_ci for (channel = 0; channel < map->channels && l > 1; channel++) { 48553a5a1b3Sopenharmony_ci l -= pa_snprintf(e, l, "%s%s", 48653a5a1b3Sopenharmony_ci first ? "" : ",", 48753a5a1b3Sopenharmony_ci pa_channel_position_to_string(map->map[channel])); 48853a5a1b3Sopenharmony_ci 48953a5a1b3Sopenharmony_ci e = strchr(e, 0); 49053a5a1b3Sopenharmony_ci first = false; 49153a5a1b3Sopenharmony_ci } 49253a5a1b3Sopenharmony_ci 49353a5a1b3Sopenharmony_ci return s; 49453a5a1b3Sopenharmony_ci} 49553a5a1b3Sopenharmony_ci 49653a5a1b3Sopenharmony_cipa_channel_position_t pa_channel_position_from_string(const char *p) { 49753a5a1b3Sopenharmony_ci pa_channel_position_t i; 49853a5a1b3Sopenharmony_ci pa_assert(p); 49953a5a1b3Sopenharmony_ci 50053a5a1b3Sopenharmony_ci /* Some special aliases */ 50153a5a1b3Sopenharmony_ci if (pa_streq(p, "left")) 50253a5a1b3Sopenharmony_ci return PA_CHANNEL_POSITION_LEFT; 50353a5a1b3Sopenharmony_ci else if (pa_streq(p, "right")) 50453a5a1b3Sopenharmony_ci return PA_CHANNEL_POSITION_RIGHT; 50553a5a1b3Sopenharmony_ci else if (pa_streq(p, "center")) 50653a5a1b3Sopenharmony_ci return PA_CHANNEL_POSITION_CENTER; 50753a5a1b3Sopenharmony_ci else if (pa_streq(p, "subwoofer")) 50853a5a1b3Sopenharmony_ci return PA_CHANNEL_POSITION_SUBWOOFER; 50953a5a1b3Sopenharmony_ci 51053a5a1b3Sopenharmony_ci for (i = 0; i < PA_CHANNEL_POSITION_MAX; i++) 51153a5a1b3Sopenharmony_ci if (pa_streq(p, table[i])) 51253a5a1b3Sopenharmony_ci return i; 51353a5a1b3Sopenharmony_ci 51453a5a1b3Sopenharmony_ci return PA_CHANNEL_POSITION_INVALID; 51553a5a1b3Sopenharmony_ci} 51653a5a1b3Sopenharmony_ci 51753a5a1b3Sopenharmony_cipa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { 51853a5a1b3Sopenharmony_ci const char *state; 51953a5a1b3Sopenharmony_ci pa_channel_map map; 52053a5a1b3Sopenharmony_ci char *p; 52153a5a1b3Sopenharmony_ci 52253a5a1b3Sopenharmony_ci pa_assert(rmap); 52353a5a1b3Sopenharmony_ci pa_assert(s); 52453a5a1b3Sopenharmony_ci 52553a5a1b3Sopenharmony_ci pa_channel_map_init(&map); 52653a5a1b3Sopenharmony_ci 52753a5a1b3Sopenharmony_ci /* We don't need to match against the well known channel mapping 52853a5a1b3Sopenharmony_ci * "mono" here explicitly, because that can be understood as 52953a5a1b3Sopenharmony_ci * listing with one channel called "mono". */ 53053a5a1b3Sopenharmony_ci 53153a5a1b3Sopenharmony_ci if (pa_streq(s, "stereo")) { 53253a5a1b3Sopenharmony_ci map.channels = 2; 53353a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_LEFT; 53453a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_RIGHT; 53553a5a1b3Sopenharmony_ci goto finish; 53653a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-21")) { 53753a5a1b3Sopenharmony_ci map.channels = 3; 53853a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 53953a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 54053a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_LFE; 54153a5a1b3Sopenharmony_ci goto finish; 54253a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-40")) { 54353a5a1b3Sopenharmony_ci map.channels = 4; 54453a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 54553a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 54653a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 54753a5a1b3Sopenharmony_ci map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 54853a5a1b3Sopenharmony_ci goto finish; 54953a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-41")) { 55053a5a1b3Sopenharmony_ci map.channels = 5; 55153a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 55253a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 55353a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 55453a5a1b3Sopenharmony_ci map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 55553a5a1b3Sopenharmony_ci map.map[4] = PA_CHANNEL_POSITION_LFE; 55653a5a1b3Sopenharmony_ci goto finish; 55753a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-50")) { 55853a5a1b3Sopenharmony_ci map.channels = 5; 55953a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 56053a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 56153a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 56253a5a1b3Sopenharmony_ci map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 56353a5a1b3Sopenharmony_ci map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; 56453a5a1b3Sopenharmony_ci goto finish; 56553a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-51")) { 56653a5a1b3Sopenharmony_ci map.channels = 6; 56753a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 56853a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 56953a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 57053a5a1b3Sopenharmony_ci map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 57153a5a1b3Sopenharmony_ci map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; 57253a5a1b3Sopenharmony_ci map.map[5] = PA_CHANNEL_POSITION_LFE; 57353a5a1b3Sopenharmony_ci goto finish; 57453a5a1b3Sopenharmony_ci } else if (pa_streq(s, "surround-71")) { 57553a5a1b3Sopenharmony_ci map.channels = 8; 57653a5a1b3Sopenharmony_ci map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; 57753a5a1b3Sopenharmony_ci map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; 57853a5a1b3Sopenharmony_ci map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; 57953a5a1b3Sopenharmony_ci map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; 58053a5a1b3Sopenharmony_ci map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; 58153a5a1b3Sopenharmony_ci map.map[5] = PA_CHANNEL_POSITION_LFE; 58253a5a1b3Sopenharmony_ci map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT; 58353a5a1b3Sopenharmony_ci map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT; 58453a5a1b3Sopenharmony_ci goto finish; 58553a5a1b3Sopenharmony_ci } 58653a5a1b3Sopenharmony_ci 58753a5a1b3Sopenharmony_ci state = NULL; 58853a5a1b3Sopenharmony_ci map.channels = 0; 58953a5a1b3Sopenharmony_ci 59053a5a1b3Sopenharmony_ci while ((p = pa_split(s, ",", &state))) { 59153a5a1b3Sopenharmony_ci pa_channel_position_t f; 59253a5a1b3Sopenharmony_ci 59353a5a1b3Sopenharmony_ci if (map.channels >= PA_CHANNELS_MAX) { 59453a5a1b3Sopenharmony_ci pa_xfree(p); 59553a5a1b3Sopenharmony_ci return NULL; 59653a5a1b3Sopenharmony_ci } 59753a5a1b3Sopenharmony_ci 59853a5a1b3Sopenharmony_ci if ((f = pa_channel_position_from_string(p)) == PA_CHANNEL_POSITION_INVALID) { 59953a5a1b3Sopenharmony_ci pa_xfree(p); 60053a5a1b3Sopenharmony_ci return NULL; 60153a5a1b3Sopenharmony_ci } 60253a5a1b3Sopenharmony_ci 60353a5a1b3Sopenharmony_ci map.map[map.channels++] = f; 60453a5a1b3Sopenharmony_ci pa_xfree(p); 60553a5a1b3Sopenharmony_ci } 60653a5a1b3Sopenharmony_ci 60753a5a1b3Sopenharmony_cifinish: 60853a5a1b3Sopenharmony_ci 60953a5a1b3Sopenharmony_ci if (!pa_channel_map_valid(&map)) 61053a5a1b3Sopenharmony_ci return NULL; 61153a5a1b3Sopenharmony_ci 61253a5a1b3Sopenharmony_ci *rmap = map; 61353a5a1b3Sopenharmony_ci return rmap; 61453a5a1b3Sopenharmony_ci} 61553a5a1b3Sopenharmony_ci 61653a5a1b3Sopenharmony_ciint pa_channel_map_valid(const pa_channel_map *map) { 61753a5a1b3Sopenharmony_ci unsigned c; 61853a5a1b3Sopenharmony_ci 61953a5a1b3Sopenharmony_ci pa_assert(map); 62053a5a1b3Sopenharmony_ci 62153a5a1b3Sopenharmony_ci if (!pa_channels_valid(map->channels)) 62253a5a1b3Sopenharmony_ci return 0; 62353a5a1b3Sopenharmony_ci 62453a5a1b3Sopenharmony_ci for (c = 0; c < map->channels; c++) 62553a5a1b3Sopenharmony_ci if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX) 62653a5a1b3Sopenharmony_ci return 0; 62753a5a1b3Sopenharmony_ci 62853a5a1b3Sopenharmony_ci return 1; 62953a5a1b3Sopenharmony_ci} 63053a5a1b3Sopenharmony_ci 63153a5a1b3Sopenharmony_ciint pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) { 63253a5a1b3Sopenharmony_ci pa_assert(map); 63353a5a1b3Sopenharmony_ci pa_assert(ss); 63453a5a1b3Sopenharmony_ci 63553a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 63653a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_sample_spec_valid(ss), 0); 63753a5a1b3Sopenharmony_ci 63853a5a1b3Sopenharmony_ci return map->channels == ss->channels; 63953a5a1b3Sopenharmony_ci} 64053a5a1b3Sopenharmony_ci 64153a5a1b3Sopenharmony_ciint pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) { 64253a5a1b3Sopenharmony_ci pa_channel_position_mask_t am, bm; 64353a5a1b3Sopenharmony_ci 64453a5a1b3Sopenharmony_ci pa_assert(a); 64553a5a1b3Sopenharmony_ci pa_assert(b); 64653a5a1b3Sopenharmony_ci 64753a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(a), 0); 64853a5a1b3Sopenharmony_ci 64953a5a1b3Sopenharmony_ci if (PA_UNLIKELY(a == b)) 65053a5a1b3Sopenharmony_ci return 1; 65153a5a1b3Sopenharmony_ci 65253a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(b), 0); 65353a5a1b3Sopenharmony_ci 65453a5a1b3Sopenharmony_ci am = pa_channel_map_mask(a); 65553a5a1b3Sopenharmony_ci bm = pa_channel_map_mask(b); 65653a5a1b3Sopenharmony_ci 65753a5a1b3Sopenharmony_ci return (bm & am) == bm; 65853a5a1b3Sopenharmony_ci} 65953a5a1b3Sopenharmony_ci 66053a5a1b3Sopenharmony_ciint pa_channel_map_can_balance(const pa_channel_map *map) { 66153a5a1b3Sopenharmony_ci pa_channel_position_mask_t m; 66253a5a1b3Sopenharmony_ci 66353a5a1b3Sopenharmony_ci pa_assert(map); 66453a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 66553a5a1b3Sopenharmony_ci 66653a5a1b3Sopenharmony_ci m = pa_channel_map_mask(map); 66753a5a1b3Sopenharmony_ci 66853a5a1b3Sopenharmony_ci return 66953a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_LEFT & m) && 67053a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_RIGHT & m); 67153a5a1b3Sopenharmony_ci} 67253a5a1b3Sopenharmony_ci 67353a5a1b3Sopenharmony_ciint pa_channel_map_can_fade(const pa_channel_map *map) { 67453a5a1b3Sopenharmony_ci pa_channel_position_mask_t m; 67553a5a1b3Sopenharmony_ci 67653a5a1b3Sopenharmony_ci pa_assert(map); 67753a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 67853a5a1b3Sopenharmony_ci 67953a5a1b3Sopenharmony_ci m = pa_channel_map_mask(map); 68053a5a1b3Sopenharmony_ci 68153a5a1b3Sopenharmony_ci return 68253a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_FRONT & m) && 68353a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_REAR & m); 68453a5a1b3Sopenharmony_ci} 68553a5a1b3Sopenharmony_ci 68653a5a1b3Sopenharmony_ciint pa_channel_map_can_lfe_balance(const pa_channel_map *map) { 68753a5a1b3Sopenharmony_ci pa_channel_position_mask_t m; 68853a5a1b3Sopenharmony_ci 68953a5a1b3Sopenharmony_ci pa_assert(map); 69053a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 69153a5a1b3Sopenharmony_ci 69253a5a1b3Sopenharmony_ci m = pa_channel_map_mask(map); 69353a5a1b3Sopenharmony_ci 69453a5a1b3Sopenharmony_ci return 69553a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_LFE & m) && 69653a5a1b3Sopenharmony_ci (PA_CHANNEL_POSITION_MASK_HFE & m); 69753a5a1b3Sopenharmony_ci} 69853a5a1b3Sopenharmony_ci 69953a5a1b3Sopenharmony_ciconst char* pa_channel_map_to_name(const pa_channel_map *map) { 70053a5a1b3Sopenharmony_ci pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)]; 70153a5a1b3Sopenharmony_ci unsigned c; 70253a5a1b3Sopenharmony_ci 70353a5a1b3Sopenharmony_ci pa_assert(map); 70453a5a1b3Sopenharmony_ci 70553a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), NULL); 70653a5a1b3Sopenharmony_ci 70753a5a1b3Sopenharmony_ci memset(in_map, 0, sizeof(in_map)); 70853a5a1b3Sopenharmony_ci 70953a5a1b3Sopenharmony_ci for (c = 0; c < map->channels; c++) 71053a5a1b3Sopenharmony_ci pa_bitset_set(in_map, map->map[c], true); 71153a5a1b3Sopenharmony_ci 71253a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 71353a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_MONO, -1)) 71453a5a1b3Sopenharmony_ci return "mono"; 71553a5a1b3Sopenharmony_ci 71653a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 71753a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1)) 71853a5a1b3Sopenharmony_ci return "stereo"; 71953a5a1b3Sopenharmony_ci 72053a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 72153a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 72253a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1)) 72353a5a1b3Sopenharmony_ci return "surround-40"; 72453a5a1b3Sopenharmony_ci 72553a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 72653a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 72753a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 72853a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_LFE, -1)) 72953a5a1b3Sopenharmony_ci return "surround-41"; 73053a5a1b3Sopenharmony_ci 73153a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 73253a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 73353a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 73453a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, -1)) 73553a5a1b3Sopenharmony_ci return "surround-50"; 73653a5a1b3Sopenharmony_ci 73753a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 73853a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 73953a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 74053a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1)) 74153a5a1b3Sopenharmony_ci return "surround-51"; 74253a5a1b3Sopenharmony_ci 74353a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 74453a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 74553a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 74653a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, 74753a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1)) 74853a5a1b3Sopenharmony_ci return "surround-71"; 74953a5a1b3Sopenharmony_ci 75053a5a1b3Sopenharmony_ci return NULL; 75153a5a1b3Sopenharmony_ci} 75253a5a1b3Sopenharmony_ci 75353a5a1b3Sopenharmony_ciconst char* pa_channel_map_to_pretty_name(const pa_channel_map *map) { 75453a5a1b3Sopenharmony_ci pa_bitset_t in_map[PA_BITSET_ELEMENTS(PA_CHANNEL_POSITION_MAX)]; 75553a5a1b3Sopenharmony_ci unsigned c; 75653a5a1b3Sopenharmony_ci 75753a5a1b3Sopenharmony_ci pa_assert(map); 75853a5a1b3Sopenharmony_ci 75953a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), NULL); 76053a5a1b3Sopenharmony_ci 76153a5a1b3Sopenharmony_ci memset(in_map, 0, sizeof(in_map)); 76253a5a1b3Sopenharmony_ci 76353a5a1b3Sopenharmony_ci for (c = 0; c < map->channels; c++) 76453a5a1b3Sopenharmony_ci pa_bitset_set(in_map, map->map[c], true); 76553a5a1b3Sopenharmony_ci 76653a5a1b3Sopenharmony_ci pa_init_i18n(); 76753a5a1b3Sopenharmony_ci 76853a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 76953a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_MONO, -1)) 77053a5a1b3Sopenharmony_ci return _("Mono"); 77153a5a1b3Sopenharmony_ci 77253a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 77353a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, -1)) 77453a5a1b3Sopenharmony_ci return _("Stereo"); 77553a5a1b3Sopenharmony_ci 77653a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 77753a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 77853a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, -1)) 77953a5a1b3Sopenharmony_ci return _("Surround 4.0"); 78053a5a1b3Sopenharmony_ci 78153a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 78253a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 78353a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 78453a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_LFE, -1)) 78553a5a1b3Sopenharmony_ci return _("Surround 4.1"); 78653a5a1b3Sopenharmony_ci 78753a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 78853a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 78953a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 79053a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, -1)) 79153a5a1b3Sopenharmony_ci return _("Surround 5.0"); 79253a5a1b3Sopenharmony_ci 79353a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 79453a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 79553a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 79653a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, -1)) 79753a5a1b3Sopenharmony_ci return _("Surround 5.1"); 79853a5a1b3Sopenharmony_ci 79953a5a1b3Sopenharmony_ci if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX, 80053a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, 80153a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, 80253a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_FRONT_CENTER, PA_CHANNEL_POSITION_LFE, 80353a5a1b3Sopenharmony_ci PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT, -1)) 80453a5a1b3Sopenharmony_ci return _("Surround 7.1"); 80553a5a1b3Sopenharmony_ci 80653a5a1b3Sopenharmony_ci return NULL; 80753a5a1b3Sopenharmony_ci} 80853a5a1b3Sopenharmony_ci 80953a5a1b3Sopenharmony_ciint pa_channel_map_has_position(const pa_channel_map *map, pa_channel_position_t p) { 81053a5a1b3Sopenharmony_ci unsigned c; 81153a5a1b3Sopenharmony_ci 81253a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 81353a5a1b3Sopenharmony_ci pa_return_val_if_fail(p < PA_CHANNEL_POSITION_MAX, 0); 81453a5a1b3Sopenharmony_ci 81553a5a1b3Sopenharmony_ci for (c = 0; c < map->channels; c++) 81653a5a1b3Sopenharmony_ci if (map->map[c] == p) 81753a5a1b3Sopenharmony_ci return 1; 81853a5a1b3Sopenharmony_ci 81953a5a1b3Sopenharmony_ci return 0; 82053a5a1b3Sopenharmony_ci} 82153a5a1b3Sopenharmony_ci 82253a5a1b3Sopenharmony_cipa_channel_position_mask_t pa_channel_map_mask(const pa_channel_map *map) { 82353a5a1b3Sopenharmony_ci unsigned c; 82453a5a1b3Sopenharmony_ci pa_channel_position_mask_t r = 0; 82553a5a1b3Sopenharmony_ci 82653a5a1b3Sopenharmony_ci pa_return_val_if_fail(pa_channel_map_valid(map), 0); 82753a5a1b3Sopenharmony_ci 82853a5a1b3Sopenharmony_ci for (c = 0; c < map->channels; c++) 82953a5a1b3Sopenharmony_ci r |= PA_CHANNEL_POSITION_MASK(map->map[c]); 83053a5a1b3Sopenharmony_ci 83153a5a1b3Sopenharmony_ci return r; 83253a5a1b3Sopenharmony_ci} 833