/*
* 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
#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 )
{
- 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;
+ 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 )
+ {
+ mlt_frame_set_audio( frame, *buffer, *format, size, mlt_pool_release );
+ *channels = channels_out;
}
- // Apply results
- *buffer = new_buffer;
- *channels = channels_out;
-
return 0;
}
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;
}