[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