From 17f16d7678fdf7453a07f06ea18596751d6e1afa Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Thu, 30 Sep 2004 16:46:37 +0000 Subject: [PATCH] * src/audio_output/common.c: common facility for channel reordering (aout_CheckChannelReorder() and aout_ChannelReorder()). --- include/audio_output.h | 4 ++ src/audio_output/common.c | 102 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/include/audio_output.h b/include/audio_output.h index af16452c53..5c664d5990 100644 --- a/include/audio_output.h +++ b/include/audio_output.h @@ -98,6 +98,7 @@ typedef int32_t vlc_fixed_t; #define AOUT_CHAN_REVERSESTEREO 0x40000 #define AOUT_CHAN_PHYSMASK 0xFFFF +#define AOUT_CHAN_MAX 9 /* Values used for the audio-device and audio-channels object variables */ #define AOUT_VAR_MONO 1 @@ -167,6 +168,9 @@ VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) ); VLC_EXPORT( mtime_t, aout_DateGet, ( const audio_date_t * ) ); VLC_EXPORT( mtime_t, aout_DateIncrement, ( audio_date_t *, uint32_t ) ); +VLC_EXPORT( int, aout_CheckChannelReorder, ( const uint32_t *, const uint32_t *, uint32_t, int, int * ) ); +VLC_EXPORT( void, aout_ChannelReorder, ( uint8_t *, int, int, const int *, int ) ); + /* From dec.c : */ #define aout_DecNew(a, b, c) __aout_DecNew(VLC_OBJECT(a), b, c) VLC_EXPORT( aout_input_t *, __aout_DecNew, ( vlc_object_t *, aout_instance_t **, audio_sample_format_t * ) ); diff --git a/src/audio_output/common.c b/src/audio_output/common.c index 96a4366c6d..239ba1f0b4 100644 --- a/src/audio_output/common.c +++ b/src/audio_output/common.c @@ -464,3 +464,105 @@ mtime_t aout_DateIncrement( audio_date_t * p_date, uint32_t i_nb_samples ) return p_date->date; } +/***************************************************************************** + * aout_CheckChannelReorder : Check if we need to do some channel re-ordering + *****************************************************************************/ +int aout_CheckChannelReorder( const uint32_t *pi_chan_order_in, + const uint32_t *pi_chan_order_out, + uint32_t i_channel_mask, + int i_channels, int *pi_chan_table ) +{ + vlc_bool_t b_chan_reorder = VLC_FALSE; + int i, j, k, l; + + if( i_channels > AOUT_CHAN_MAX ) return VLC_FALSE; + + for( i = 0, j = 0; pi_chan_order_in[i]; i++ ) + { + if( !(i_channel_mask & pi_chan_order_in[i]) ) continue; + + for( k = 0, l = 0; pi_chan_order_in[i] != pi_chan_order_out[k]; k++ ) + { + if( i_channel_mask & pi_chan_order_out[k] ) l++; + } + + pi_chan_table[j++] = l; + } + + for( i = 0; i < i_channels; i++ ) + { + if( pi_chan_table[i] != i ) b_chan_reorder = VLC_TRUE; + } + + return b_chan_reorder; +} + +/***************************************************************************** + * aout_ChannelReorder : + *****************************************************************************/ +void aout_ChannelReorder( uint8_t *p_buf, int i_buffer, + int i_channels, const int *pi_chan_table, + int i_bits_per_sample ) +{ + uint8_t p_tmp[AOUT_CHAN_MAX * 4]; + int i, j; + + if( i_bits_per_sample == 8 ) + { + for( i = 0; i < i_buffer / i_channels; i++ ) + { + for( j = 0; j < i_channels; j++ ) + { + p_tmp[pi_chan_table[j]] = p_buf[j]; + } + + memcpy( p_buf, p_tmp, i_channels ); + p_buf += i_channels; + } + } + else if( i_bits_per_sample == 16 ) + { + for( i = 0; i < i_buffer / i_channels / 2; i++ ) + { + for( j = 0; j < i_channels; j++ ) + { + p_tmp[2 * pi_chan_table[j]] = p_buf[2 * j]; + p_tmp[2 * pi_chan_table[j] + 1] = p_buf[2 * j + 1]; + } + + memcpy( p_buf, p_tmp, 2 * i_channels ); + p_buf += 2 * i_channels; + } + } + else if( i_bits_per_sample == 24 ) + { + for( i = 0; i < i_buffer / i_channels / 3; i++ ) + { + for( j = 0; j < i_channels; j++ ) + { + p_tmp[3 * pi_chan_table[j]] = p_buf[3 * j]; + p_tmp[3 * pi_chan_table[j] + 1] = p_buf[3 * j + 1]; + p_tmp[3 * pi_chan_table[j] + 2] = p_buf[3 * j + 2]; + } + + memcpy( p_buf, p_tmp, 3 * i_channels ); + p_buf += 3 * i_channels; + } + } + else if( i_bits_per_sample == 32 ) + { + for( i = 0; i < i_buffer / i_channels / 4; i++ ) + { + for( j = 0; j < i_channels; j++ ) + { + p_tmp[4 * pi_chan_table[j]] = p_buf[4 * j]; + p_tmp[4 * pi_chan_table[j] + 1] = p_buf[4 * j + 1]; + p_tmp[4 * pi_chan_table[j] + 2] = p_buf[4 * j + 2]; + p_tmp[4 * pi_chan_table[j] + 3] = p_buf[4 * j + 3]; + } + + memcpy( p_buf, p_tmp, 4 * i_channels ); + p_buf += 4 * i_channels; + } + } +}