pipewire/spa/plugins/alsa/acp/channelmap.h
Wim Taymans 6e6385e27d acp: don't mix non-AUX and AUX channels
When filling up the channels, either fill up the positions with one
of the know layouts or use AUX channels, never try to mix them.

This avoid cards with a large number channels to show a strange mix
of surround and AUX channels.
2022-06-02 12:54:04 +02:00

476 lines
18 KiB
C

/***
This file is part of PulseAudio.
Copyright 2004-2006 Lennart Poettering
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
#ifndef PULSE_CHANNELMAP_H
#define PULSE_CHANNELMAP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "spa/utils/defs.h"
#define PA_CHANNELS_MAX 64
#define PA_CHANNEL_MAP_SNPRINT_MAX (PA_CHANNELS_MAX * 32)
typedef enum pa_channel_map_def {
PA_CHANNEL_MAP_AIFF,
PA_CHANNEL_MAP_ALSA,
PA_CHANNEL_MAP_AUX,
PA_CHANNEL_MAP_WAVEEX,
PA_CHANNEL_MAP_OSS,
PA_CHANNEL_MAP_DEF_MAX,
PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
} pa_channel_map_def_t;
typedef enum pa_channel_position {
PA_CHANNEL_POSITION_INVALID = -1,
PA_CHANNEL_POSITION_MONO = 0,
PA_CHANNEL_POSITION_FRONT_LEFT, /**< Apple, Dolby call this 'Left' */
PA_CHANNEL_POSITION_FRONT_RIGHT, /**< Apple, Dolby call this 'Right' */
PA_CHANNEL_POSITION_FRONT_CENTER, /**< Apple, Dolby call this 'Center' */
/** \cond fulldocs */
PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT,
PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT,
PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER,
/** \endcond */
PA_CHANNEL_POSITION_REAR_CENTER, /**< Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */
PA_CHANNEL_POSITION_REAR_LEFT, /**< Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */
PA_CHANNEL_POSITION_REAR_RIGHT, /**< Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */
PA_CHANNEL_POSITION_LFE, /**< Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */
/** \cond fulldocs */
PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE,
/** \endcond */
PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, /**< Apple, Dolby call this 'Left Center' */
PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, /**< Apple, Dolby call this 'Right Center */
PA_CHANNEL_POSITION_SIDE_LEFT, /**< Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */
PA_CHANNEL_POSITION_SIDE_RIGHT, /**< Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */
PA_CHANNEL_POSITION_AUX0,
PA_CHANNEL_POSITION_AUX1,
PA_CHANNEL_POSITION_AUX2,
PA_CHANNEL_POSITION_AUX3,
PA_CHANNEL_POSITION_AUX4,
PA_CHANNEL_POSITION_AUX5,
PA_CHANNEL_POSITION_AUX6,
PA_CHANNEL_POSITION_AUX7,
PA_CHANNEL_POSITION_AUX8,
PA_CHANNEL_POSITION_AUX9,
PA_CHANNEL_POSITION_AUX10,
PA_CHANNEL_POSITION_AUX11,
PA_CHANNEL_POSITION_AUX12,
PA_CHANNEL_POSITION_AUX13,
PA_CHANNEL_POSITION_AUX14,
PA_CHANNEL_POSITION_AUX15,
PA_CHANNEL_POSITION_AUX16,
PA_CHANNEL_POSITION_AUX17,
PA_CHANNEL_POSITION_AUX18,
PA_CHANNEL_POSITION_AUX19,
PA_CHANNEL_POSITION_AUX20,
PA_CHANNEL_POSITION_AUX21,
PA_CHANNEL_POSITION_AUX22,
PA_CHANNEL_POSITION_AUX23,
PA_CHANNEL_POSITION_AUX24,
PA_CHANNEL_POSITION_AUX25,
PA_CHANNEL_POSITION_AUX26,
PA_CHANNEL_POSITION_AUX27,
PA_CHANNEL_POSITION_AUX28,
PA_CHANNEL_POSITION_AUX29,
PA_CHANNEL_POSITION_AUX30,
PA_CHANNEL_POSITION_AUX31,
PA_CHANNEL_POSITION_TOP_CENTER, /**< Apple calls this 'Top Center Surround' */
PA_CHANNEL_POSITION_TOP_FRONT_LEFT, /**< Apple calls this 'Vertical Height Left' */
PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, /**< Apple calls this 'Vertical Height Right' */
PA_CHANNEL_POSITION_TOP_FRONT_CENTER, /**< Apple calls this 'Vertical Height Center' */
PA_CHANNEL_POSITION_TOP_REAR_LEFT, /**< Microsoft and Apple call this 'Top Back Left' */
PA_CHANNEL_POSITION_TOP_REAR_RIGHT, /**< Microsoft and Apple call this 'Top Back Right' */
PA_CHANNEL_POSITION_TOP_REAR_CENTER, /**< Microsoft and Apple call this 'Top Back Center' */
PA_CHANNEL_POSITION_MAX
} pa_channel_position_t;
typedef struct pa_channel_map {
uint8_t channels;
pa_channel_position_t map[PA_CHANNELS_MAX];
} pa_channel_map;
static inline int pa_channels_valid(uint8_t channels)
{
return channels > 0 && channels <= PA_CHANNELS_MAX;
}
static inline int pa_channel_map_valid(const pa_channel_map *map)
{
unsigned c;
if (!pa_channels_valid(map->channels))
return 0;
for (c = 0; c < map->channels; c++)
if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
return 0;
return 1;
}
static inline pa_channel_map* pa_channel_map_init(pa_channel_map *m)
{
unsigned c;
m->channels = 0;
for (c = 0; c < PA_CHANNELS_MAX; c++)
m->map[c] = PA_CHANNEL_POSITION_INVALID;
return m;
}
static inline pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def)
{
unsigned i;
pa_assert(m);
pa_assert(pa_channels_valid(channels));
pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
m->channels = (uint8_t) channels;
switch (def) {
case PA_CHANNEL_MAP_ALSA:
switch (channels) {
case 1:
m->map[0] = PA_CHANNEL_POSITION_MONO;
return m;
case 8:
m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
SPA_FALLTHROUGH;
case 6:
m->map[5] = PA_CHANNEL_POSITION_LFE;
SPA_FALLTHROUGH;
case 5:
m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
SPA_FALLTHROUGH;
case 4:
m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
SPA_FALLTHROUGH;
case 2:
m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
return m;
default:
return NULL;
}
case PA_CHANNEL_MAP_AUX:
for (i = 0; i < channels; i++)
m->map[i] = PA_CHANNEL_POSITION_AUX0 + (i & 31);
return m;
default:
break;
}
return NULL;
}
static inline pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m,
unsigned channels, pa_channel_map_def_t def)
{
pa_channel_map *r;
if ((r = pa_channel_map_init_auto(m, channels, def)) != NULL)
return r;
return pa_channel_map_init_auto(m, channels, PA_CHANNEL_MAP_AUX);
}
typedef uint64_t pa_channel_position_mask_t;
#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f)))
#define PA_CHANNEL_POSITION_MASK_LEFT \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT)) \
#define PA_CHANNEL_POSITION_MASK_RIGHT \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT))
#define PA_CHANNEL_POSITION_MASK_CENTER \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER))
#define PA_CHANNEL_POSITION_MASK_FRONT \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER))
#define PA_CHANNEL_POSITION_MASK_REAR \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER))
#define PA_CHANNEL_POSITION_MASK_LFE \
PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_LFE)
#define PA_CHANNEL_POSITION_MASK_HFE \
(PA_CHANNEL_POSITION_MASK_REAR | PA_CHANNEL_POSITION_MASK_FRONT \
| PA_CHANNEL_POSITION_MASK_LEFT | PA_CHANNEL_POSITION_MASK_RIGHT \
| PA_CHANNEL_POSITION_MASK_CENTER)
#define PA_CHANNEL_POSITION_MASK_SIDE_OR_TOP_CENTER \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER))
#define PA_CHANNEL_POSITION_MASK_TOP \
(PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT) \
| PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER))
#define PA_CHANNEL_POSITION_MASK_ALL \
((pa_channel_position_mask_t) (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_MAX)-1))
static const char *const pa_position_table[PA_CHANNEL_POSITION_MAX] = {
[PA_CHANNEL_POSITION_MONO] = "mono",
[PA_CHANNEL_POSITION_FRONT_CENTER] = "front-center",
[PA_CHANNEL_POSITION_FRONT_LEFT] = "front-left",
[PA_CHANNEL_POSITION_FRONT_RIGHT] = "front-right",
[PA_CHANNEL_POSITION_REAR_CENTER] = "rear-center",
[PA_CHANNEL_POSITION_REAR_LEFT] = "rear-left",
[PA_CHANNEL_POSITION_REAR_RIGHT] = "rear-right",
[PA_CHANNEL_POSITION_LFE] = "lfe",
[PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "front-left-of-center",
[PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "front-right-of-center",
[PA_CHANNEL_POSITION_SIDE_LEFT] = "side-left",
[PA_CHANNEL_POSITION_SIDE_RIGHT] = "side-right",
[PA_CHANNEL_POSITION_AUX0] = "aux0",
[PA_CHANNEL_POSITION_AUX1] = "aux1",
[PA_CHANNEL_POSITION_AUX2] = "aux2",
[PA_CHANNEL_POSITION_AUX3] = "aux3",
[PA_CHANNEL_POSITION_AUX4] = "aux4",
[PA_CHANNEL_POSITION_AUX5] = "aux5",
[PA_CHANNEL_POSITION_AUX6] = "aux6",
[PA_CHANNEL_POSITION_AUX7] = "aux7",
[PA_CHANNEL_POSITION_AUX8] = "aux8",
[PA_CHANNEL_POSITION_AUX9] = "aux9",
[PA_CHANNEL_POSITION_AUX10] = "aux10",
[PA_CHANNEL_POSITION_AUX11] = "aux11",
[PA_CHANNEL_POSITION_AUX12] = "aux12",
[PA_CHANNEL_POSITION_AUX13] = "aux13",
[PA_CHANNEL_POSITION_AUX14] = "aux14",
[PA_CHANNEL_POSITION_AUX15] = "aux15",
[PA_CHANNEL_POSITION_AUX16] = "aux16",
[PA_CHANNEL_POSITION_AUX17] = "aux17",
[PA_CHANNEL_POSITION_AUX18] = "aux18",
[PA_CHANNEL_POSITION_AUX19] = "aux19",
[PA_CHANNEL_POSITION_AUX20] = "aux20",
[PA_CHANNEL_POSITION_AUX21] = "aux21",
[PA_CHANNEL_POSITION_AUX22] = "aux22",
[PA_CHANNEL_POSITION_AUX23] = "aux23",
[PA_CHANNEL_POSITION_AUX24] = "aux24",
[PA_CHANNEL_POSITION_AUX25] = "aux25",
[PA_CHANNEL_POSITION_AUX26] = "aux26",
[PA_CHANNEL_POSITION_AUX27] = "aux27",
[PA_CHANNEL_POSITION_AUX28] = "aux28",
[PA_CHANNEL_POSITION_AUX29] = "aux29",
[PA_CHANNEL_POSITION_AUX30] = "aux30",
[PA_CHANNEL_POSITION_AUX31] = "aux31",
[PA_CHANNEL_POSITION_TOP_CENTER] = "top-center",
[PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center",
[PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "top-front-left",
[PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "top-front-right",
[PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center",
[PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "top-rear-left",
[PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right"
};
static inline pa_channel_position_t pa_channel_position_from_string(const char *p)
{
pa_channel_position_t i;
/* Some special aliases */
if (pa_streq(p, "left"))
return PA_CHANNEL_POSITION_LEFT;
else if (pa_streq(p, "right"))
return PA_CHANNEL_POSITION_RIGHT;
else if (pa_streq(p, "center"))
return PA_CHANNEL_POSITION_CENTER;
else if (pa_streq(p, "subwoofer"))
return PA_CHANNEL_POSITION_SUBWOOFER;
for (i = 0; i < PA_CHANNEL_POSITION_MAX; i++)
if (pa_streq(p, pa_position_table[i]))
return i;
return PA_CHANNEL_POSITION_INVALID;
}
static inline pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s)
{
const char *state;
pa_channel_map map;
char *p;
pa_channel_map_init(&map);
if (pa_streq(s, "stereo")) {
map.channels = 2;
map.map[0] = PA_CHANNEL_POSITION_LEFT;
map.map[1] = PA_CHANNEL_POSITION_RIGHT;
goto finish;
} else if (pa_streq(s, "surround-21")) {
map.channels = 3;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_LFE;
goto finish;
} else if (pa_streq(s, "surround-40")) {
map.channels = 4;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
goto finish;
} else if (pa_streq(s, "surround-41")) {
map.channels = 5;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_LFE;
goto finish;
} else if (pa_streq(s, "surround-50")) {
map.channels = 5;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
goto finish;
} else if (pa_streq(s, "surround-51")) {
map.channels = 6;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
map.map[5] = PA_CHANNEL_POSITION_LFE;
goto finish;
} else if (pa_streq(s, "surround-71")) {
map.channels = 8;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
map.map[5] = PA_CHANNEL_POSITION_LFE;
map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
goto finish;
}
state = NULL;
map.channels = 0;
while ((p = pa_split(s, ",", &state))) {
pa_channel_position_t f;
if (map.channels >= PA_CHANNELS_MAX) {
pa_xfree(p);
return NULL;
}
if ((f = pa_channel_position_from_string(p)) == PA_CHANNEL_POSITION_INVALID) {
pa_xfree(p);
return NULL;
}
map.map[map.channels++] = f;
pa_xfree(p);
}
finish:
if (!pa_channel_map_valid(&map))
return NULL;
*rmap = map;
return rmap;
}
static inline const char* pa_channel_position_to_string(pa_channel_position_t pos) {
if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
return NULL;
return pa_position_table[pos];
}
static inline int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b)
{
unsigned c;
if (PA_UNLIKELY(a == b))
return 1;
if (a->channels != b->channels)
return 0;
for (c = 0; c < a->channels; c++)
if (a->map[c] != b->map[c])
return 0;
return 1;
}
static inline char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
unsigned channel;
bool first = true;
char *e;
if (!pa_channel_map_valid(map)) {
pa_snprintf(s, l, "%s", _("(invalid)"));
return s;
}
*(e = s) = 0;
for (channel = 0; channel < map->channels && l > 1; channel++) {
l -= pa_snprintf(e, l, "%s%s",
first ? "" : ",",
pa_channel_position_to_string(map->map[channel]));
e = strchr(e, 0);
first = false;
}
return s;
}
#ifdef __cplusplus
}
#endif
#endif /* PULSE_CHANNELMAP_H */