2020-05-15 19:42:15 +02:00
/***
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
2025-05-27 09:06:08 +01:00
# include "spa/utils/defs.h"
2020-05-15 19:42:15 +02:00
# ifdef __cplusplus
extern " C " {
# endif
2025-10-24 17:16:03 +02:00
# ifdef SPA_AUDIO_MAX_CHANNELS
# define PA_CHANNELS_MAX ((int)SPA_AUDIO_MAX_CHANNELS)
# else
# define PA_CHANNELS_MAX 64
# endif
2020-05-15 19:42:15 +02:00
2021-11-04 16:41:32 +01:00
# define PA_CHANNEL_MAP_SNPRINT_MAX (PA_CHANNELS_MAX * 32)
2020-05-15 19:42:15 +02:00
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 )
{
2021-10-18 10:51:48 +02:00
unsigned i ;
2020-05-15 19:42:15 +02:00
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 ;
2021-10-23 14:23:14 +01:00
SPA_FALLTHROUGH ;
2020-05-15 19:42:15 +02:00
case 6 :
m - > map [ 5 ] = PA_CHANNEL_POSITION_LFE ;
2021-10-23 14:23:14 +01:00
SPA_FALLTHROUGH ;
2020-05-15 19:42:15 +02:00
case 5 :
m - > map [ 4 ] = PA_CHANNEL_POSITION_FRONT_CENTER ;
2021-10-23 14:23:14 +01:00
SPA_FALLTHROUGH ;
2020-05-15 19:42:15 +02:00
case 4 :
m - > map [ 2 ] = PA_CHANNEL_POSITION_REAR_LEFT ;
m - > map [ 3 ] = PA_CHANNEL_POSITION_REAR_RIGHT ;
2021-10-23 14:23:14 +01:00
SPA_FALLTHROUGH ;
2020-05-15 19:42:15 +02:00
case 2 :
m - > map [ 0 ] = PA_CHANNEL_POSITION_FRONT_LEFT ;
m - > map [ 1 ] = PA_CHANNEL_POSITION_FRONT_RIGHT ;
return m ;
default :
return NULL ;
}
2021-10-18 10:51:48 +02:00
case PA_CHANNEL_MAP_AUX :
for ( i = 0 ; i < channels ; i + + )
m - > map [ i ] = PA_CHANNEL_POSITION_AUX0 + ( i & 31 ) ;
2022-06-02 12:44:31 +02:00
return m ;
2020-05-15 19:42:15 +02:00
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 )
{
2022-06-02 12:54:04 +02:00
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 ) ;
2020-05-15 19:42:15 +02:00
}
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 " ,
2021-10-18 10:51:48 +02:00
2020-05-15 19:42:15 +02:00
[ 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 ;
char * e ;
if ( ! pa_channel_map_valid ( map ) ) {
2021-04-14 17:57:34 +02:00
pa_snprintf ( s , l , " %s " , _ ( " (invalid) " ) ) ;
2020-05-15 19:42:15 +02:00
return s ;
}
* ( e = s ) = 0 ;
for ( channel = 0 ; channel < map - > channels & & l > 1 ; channel + + ) {
l - = pa_snprintf ( e , l , " %s%s " ,
2025-10-24 17:00:11 +02:00
channel = = 0 ? " " : " , " ,
2020-05-15 19:42:15 +02:00
pa_channel_position_to_string ( map - > map [ channel ] ) ) ;
e = strchr ( e , 0 ) ;
}
return s ;
}
# ifdef __cplusplus
}
# endif
# endif /* PULSE_CHANNELMAP_H */