[vlc-commits] mixer/trivial: fix up-mixing and respect channel map
Thomas Guillem
git at videolan.org
Thu Oct 13 17:41:09 CEST 2016
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Oct 13 17:38:02 2016 +0200| [38d2451ef3f22c7c1ba999c906a0afbc8fa3fb58] | committer: Thomas Guillem
mixer/trivial: fix up-mixing and respect channel map
As the trivial down-mixer just drop extra channels, trivial up-mixer should set
0 to extra channels.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=38d2451ef3f22c7c1ba999c906a0afbc8fa3fb58
---
modules/audio_filter/channel_mixer/trivial.c | 50 ++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 3 deletions(-)
diff --git a/modules/audio_filter/channel_mixer/trivial.c b/modules/audio_filter/channel_mixer/trivial.c
index c75c4e1..7c1e92b 100644
--- a/modules/audio_filter/channel_mixer/trivial.c
+++ b/modules/audio_filter/channel_mixer/trivial.c
@@ -36,15 +36,21 @@
#include <vlc_filter.h>
static int Create( vlc_object_t * );
+static void Destroy( vlc_object_t * );
vlc_module_begin ()
set_description( N_("Audio filter for trivial channel mixing") )
set_capability( "audio converter", 1 )
set_category( CAT_AUDIO )
set_subcategory( SUBCAT_AUDIO_MISC )
- set_callbacks( Create, NULL )
+ set_callbacks( Create, Destroy )
vlc_module_end ()
+struct filter_sys_t
+{
+ int channel_map[AOUT_CHAN_MAX];
+};
+
/**
* Trivially upmixes
*/
@@ -70,11 +76,12 @@ static block_t *Upmix( filter_t *p_filter, block_t *p_in_buf )
float *p_dest = (float *)p_out_buf->p_buffer;
const float *p_src = (float *)p_in_buf->p_buffer;
+ const int *channel_map = p_filter->p_sys->channel_map;
for( size_t i = 0; i < p_in_buf->i_nb_samples; i++ )
{
for( unsigned j = 0; j < i_output_nb; j++ )
- p_dest[j] = p_src[j % i_input_nb];
+ p_dest[j] = channel_map[j] == -1 ? 0.f : p_src[channel_map[j]];
p_src += i_input_nb;
p_dest += i_output_nb;
@@ -96,11 +103,15 @@ static block_t *Downmix( filter_t *p_filter, block_t *p_buf )
float *p_dest = (float *)p_buf->p_buffer;
const float *p_src = p_dest;
+ const int *channel_map = p_filter->p_sys->channel_map;
+ /* Use an extra buffer to avoid overlapping */
+ float buffer[i_output_nb];
for( size_t i = 0; i < p_buf->i_nb_samples; i++ )
{
for( unsigned j = 0; j < i_output_nb; j++ )
- p_dest[j] = p_src[j];
+ buffer[j] = channel_map[j] == -1 ? 0.f : p_src[channel_map[j]];
+ memcpy( p_dest, buffer, i_output_nb * sizeof(float) );
p_src += i_input_nb;
p_dest += i_output_nb;
@@ -196,6 +207,7 @@ static int Create( vlc_object_t *p_this )
&& infmt->i_original_channels == outfmt->i_original_channels )
return VLC_EGENERIC;
+ p_filter->p_sys = NULL;
if( outfmt->i_physical_channels == AOUT_CHANS_STEREO )
{
bool swap = (outfmt->i_original_channels & AOUT_CHAN_REVERSESTEREO)
@@ -239,6 +251,32 @@ static int Create( vlc_object_t *p_this )
}
}
+ p_filter->p_sys = malloc( sizeof(*p_filter->p_sys) );
+ if(! p_filter->p_sys )
+ return VLC_ENOMEM;
+
+ /* Setup channel order */
+ int i_src_idx = 0;
+ unsigned i_dst_idx = 0;
+ for( unsigned i = 0; i < AOUT_CHAN_MAX; ++i )
+ {
+ if( pi_vlc_chan_order_wg4[i] & outfmt->i_physical_channels )
+ {
+ p_filter->p_sys->channel_map[i_dst_idx++] =
+ pi_vlc_chan_order_wg4[i] & infmt->i_physical_channels ?
+ i_src_idx : -1;
+ }
+ if( pi_vlc_chan_order_wg4[i] & infmt->i_physical_channels )
+ i_src_idx++;
+ }
+#ifndef NDEBUG
+ for( unsigned i = 0; i < aout_FormatNbChannels( outfmt ); ++i )
+ {
+ assert( p_filter->p_sys->channel_map[i] == -1
+ || (unsigned) p_filter->p_sys->channel_map[i] < aout_FormatNbChannels( infmt ) );
+ }
+#endif
+
if( aout_FormatNbChannels( outfmt ) > aout_FormatNbChannels( infmt ) )
p_filter->pf_audio_filter = Upmix;
else
@@ -246,3 +284,9 @@ static int Create( vlc_object_t *p_this )
return VLC_SUCCESS;
}
+
+static void Destroy( vlc_object_t *p_this )
+{
+ filter_t *p_filter = (filter_t *)p_this;
+ free( p_filter->p_sys );
+}
More information about the vlc-commits
mailing list