]> git.sesse.net Git - mlt/blobdiff - src/modules/core/filter_mono.c
Convert producer_xml to use mlt_log rather than fprintf.
[mlt] / src / modules / core / filter_mono.c
index 1c6b51294d374f46c8bec857286460546dde04b3..3d2eba71334d66b5576be9ee6be13962c4d4ee90 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * filter_mono.c -- mix all channels to a mono signal across n channels
- * Copyright (C) 2003-2006 Ushodaya Enterprises Limited
+ * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
  * Author: Dan Dennedy <dan@dennedy.org>
  *
  * This library is free software; you can redistribute it and/or
@@ -18,9 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "filter_mono.h"
-
+#include <framework/mlt_filter.h>
 #include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 /** Get the audio.
 */
 
-static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
 {
        // Get the properties of the a frame
        mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
        int channels_out = mlt_properties_get_int( properties, "mono.channels" );
        int i, j, size;
-       int16_t *new_buffer;
 
        // Get the producer's audio
        mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
 
-       size = *samples * channels_out * sizeof( int16_t );
-       new_buffer = mlt_pool_alloc( size );
-       mlt_properties_set_data( properties, "audio", new_buffer, size, ( mlt_destructor )mlt_pool_release, NULL );
+       if ( channels_out == -1 )
+               channels_out = *channels;
+       size = mlt_audio_format_size( *format, *samples, channels_out );
 
-       // Mix
-       for ( i = 0; i < *samples; i++ )
+       switch ( *format )
+       {
+               case mlt_audio_s16:
+               {
+                       int16_t *new_buffer = mlt_pool_alloc( size );
+                       for ( i = 0; i < *samples; i++ )
+                       {
+                               int16_t mixdown = 0;
+                               for ( j = 0; j < *channels; j++ )
+                                       mixdown += ((int16_t*) *buffer)[ ( i * *channels ) + j ] / *channels;
+                               for ( j = 0; j < channels_out; j++ )
+                                       new_buffer[ ( i * channels_out ) + j ] = mixdown;
+                       }
+                       *buffer = new_buffer;
+                       break;
+               }
+               case mlt_audio_s32le:
+               {
+                       int32_t *new_buffer = mlt_pool_alloc( size );
+                       for ( i = 0; i < *samples; i++ )
+                       {
+                               int32_t mixdown = 0;
+                               for ( j = 0; j < *channels; j++ )
+                                       mixdown += ((int32_t*) *buffer)[ ( i * *channels ) + j ] / *channels;
+                               for ( j = 0; j < channels_out; j++ )
+                                       new_buffer[ ( i * channels_out ) + j ] = mixdown;
+                       }
+                       *buffer = new_buffer;
+                       break;
+               }
+               case mlt_audio_f32le:
+               {
+                       float *new_buffer = mlt_pool_alloc( size );
+                       for ( i = 0; i < *samples; i++ )
+                       {
+                               float mixdown = 0;
+                               for ( j = 0; j < *channels; j++ )
+                                       mixdown += ((float*) *buffer)[ ( i * *channels ) + j ] / *channels;
+                               for ( j = 0; j < channels_out; j++ )
+                                       new_buffer[ ( i * channels_out ) + j ] = mixdown;
+                       }
+                       *buffer = new_buffer;
+                       break;
+               }
+               case mlt_audio_s32:
+               {
+                       int32_t *new_buffer = mlt_pool_alloc( size );
+                       for ( i = 0; i < *samples; i++ )
+                       {
+                               int32_t mixdown = 0;
+                               for ( j = 0; j < *channels; j++ )
+                                       mixdown += ((int32_t*) *buffer)[ ( j * *channels ) + i ] / *channels;
+                               for ( j = 0; j < channels_out; j++ )
+                                       new_buffer[ ( j * *samples ) + i ] = mixdown;
+                       }
+                       *buffer = new_buffer;
+                       break;
+               }
+               case mlt_audio_float:
+               {
+                       float *new_buffer = mlt_pool_alloc( size );
+                       for ( i = 0; i < *samples; i++ )
+                       {
+                               float mixdown = 0;
+                               for ( j = 0; j < *channels; j++ )
+                                       mixdown += ((float*) *buffer)[ ( j * *channels ) + i ] / *channels;
+                               for ( j = 0; j < channels_out; j++ )
+                                       new_buffer[ ( j * *samples ) + i ] = mixdown;
+                       }
+                       *buffer = new_buffer;
+                       break;
+               }
+               default:
+                       mlt_log_error( NULL, "[filter mono] Invalid audio format\n" );
+                       break;
+       }
+       if ( size > *samples * channels_out )
        {
-               int16_t mixdown = 0;
-               for ( j = 0; j < *channels; j++ )
-                       mixdown += (*buffer)[ ( i * *channels ) + j ] / *channels;
-               for ( j = 0; j < channels_out; j++ )
-                       new_buffer[ ( i * channels_out ) + j ] = mixdown;
+               mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
+               *channels = channels_out;
        }
 
-       // Apply results
-       *buffer = new_buffer;
-       *channels = channels_out;
-       
        return 0;
 }
 
@@ -80,7 +147,7 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 /** Constructor for the filter.
 */
 
-mlt_filter filter_mono_init( char *arg )
+mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
        mlt_filter this = mlt_filter_new( );
        if ( this != NULL )
@@ -89,7 +156,7 @@ mlt_filter filter_mono_init( char *arg )
                if ( arg != NULL )
                        mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", atoi( arg ) );
                else
-                       mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 );
+                       mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", -1 );
        }
        return this;
 }