// Obtain the resample context if it exists
ReSampleContext *resample = mlt_properties_get_data( filter_properties, "audio_resample", NULL );
- // Used to return number of channels in the source
- int channels_avail = *channels;
-
// If no resample frequency is specified, default to requested value
if ( output_rate == 0 )
output_rate = *frequency;
// Get the producer's audio
- *format = mlt_audio_s16;
- mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
-
- // Duplicate channels as necessary
- if ( channels_avail < *channels )
- {
- int size = mlt_audio_format_size( *format, *samples, *channels );
- int16_t *new_buffer = mlt_pool_alloc( size );
- int i, j, k;
-
- // Duplicate the existing channels
- for ( i = 0; i < *samples; i++ )
- {
- for ( j = 0; j < *channels; j++ )
- {
- new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
- k = ( k + 1 ) % channels_avail;
- }
- }
-
- // Update the audio buffer now - destroys the old
- mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
-
- *buffer = new_buffer;
- }
- else if ( channels_avail > *channels )
- {
- int size = mlt_audio_format_size( *format, *samples, *channels );
- int16_t *new_buffer = mlt_pool_alloc( size );
- int i, j;
-
- // Drop all but the first *channels
- for ( i = 0; i < *samples; i++ )
- {
- for ( j = 0; j < *channels; j++ )
- new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
- }
-
- // Update the audio buffer now - destroys the old
- mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
-
- *buffer = new_buffer;
- }
+ int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+ if ( error ) return error;
// Return now if no work to do
if ( output_rate != *frequency )
// Will store number of samples created
int used = 0;
+ // Do not convert to s16 unless we need to change the rate
+ if ( *format != mlt_audio_s16 )
+ {
+ *format = mlt_audio_s16;
+ mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+ }
+
// Create a resampler if nececessary
if ( resample == NULL || *frequency != mlt_properties_get_int( filter_properties, "last_frequency" ) )
{
mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
}
- return 0;
+ return error;
}
/** Filter processing.
producer_loader.o \
producer_noise.o \
producer_ppm.o \
+ filter_audiochannels.o \
filter_audioconvert.o \
filter_audiowave.o \
filter_brightness.o \
#include <string.h>
extern mlt_consumer consumer_null_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_filter filter_audiowave_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
extern mlt_filter filter_brightness_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
MLT_REPOSITORY
{
MLT_REGISTER( consumer_type, "null", consumer_null_init );
+ MLT_REGISTER( filter_type, "audiochannels", filter_audiochannels_init );
MLT_REGISTER( filter_type, "audioconvert", filter_audioconvert_init );
MLT_REGISTER( filter_type, "audiowave", filter_audiowave_init );
MLT_REGISTER( filter_type, "brightness", filter_brightness_init );
--- /dev/null
+/*
+ * filter_audiochannels.c -- convert from one audio format to another
+ * Copyright (C) 2009 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <framework/mlt_filter.h>
+#include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
+
+#include <string.h>
+
+static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+ // Used to return number of channels in the source
+ int channels_avail = *channels;
+
+ // Get the producer's audio
+ int error = mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
+ if ( error ) return error;
+
+ if ( channels_avail < *channels )
+ {
+ int size = mlt_audio_format_size( *format, *samples, *channels );
+ int16_t *new_buffer = mlt_pool_alloc( size );
+
+ // Duplicate the existing channels
+ if ( *format == mlt_audio_s16 )
+ {
+ int i, j, k;
+ for ( i = 0; i < *samples; i++ )
+ {
+ for ( j = 0; j < *channels; j++ )
+ {
+ new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
+ k = ( k + 1 ) % channels_avail;
+ }
+ }
+ }
+ else
+ {
+ // non-interleaved
+ int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
+ int32_t *p = (int32_t*) new_buffer;
+ int i = *channels / channels_avail;
+ while ( i-- )
+ {
+ memcpy( p, *buffer, size_avail );
+ p += size_avail / sizeof(*p);
+ }
+ i = *channels % channels_avail;
+ if ( i )
+ {
+ size_avail = mlt_audio_format_size( *format, *samples, i );
+ memcpy( p, *buffer, size_avail );
+ }
+ }
+ // Update the audio buffer now - destroys the old
+ mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
+ *buffer = new_buffer;
+ }
+ else if ( channels_avail > *channels )
+ {
+ int size = mlt_audio_format_size( *format, *samples, *channels );
+ int16_t *new_buffer = mlt_pool_alloc( size );
+
+ // Drop all but the first *channels
+ if ( *format == mlt_audio_s16 )
+ {
+ int i, j;
+ for ( i = 0; i < *samples; i++ )
+ for ( j = 0; j < *channels; j++ )
+ new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
+ }
+ else
+ {
+ // non-interleaved
+ memcpy( new_buffer, *buffer, size );
+ }
+ // Update the audio buffer now - destroys the old
+ mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
+ *buffer = new_buffer;
+ }
+ return error;
+}
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
+{
+ mlt_frame_push_audio( frame, filter_get_audio );
+ return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+ mlt_filter filter = mlt_filter_new();
+ if ( filter )
+ filter->process = filter_process;
+ return filter;
+}
resizer=resize
# audio filters
-resampler=resample,avresample
+channels=audiochannels
+resampler=avresample,resample
# metadata filters
data=data_feed:attr_check
// Get the resample information
int output_rate = mlt_properties_get_int( filter_properties, "frequency" );
- int error = 0;
-
- // Used to return number of channels in the source
- int channels_avail = *channels;
// If no resample frequency is specified, default to requested value
if ( output_rate == 0 )
output_rate = *frequency;
// Get the producer's audio
- mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
-
- if ( channels_avail < *channels )
- {
- int size = mlt_audio_format_size( *format, *samples, *channels );
- int16_t *new_buffer = mlt_pool_alloc( size );
- int sample_size_factor = mlt_audio_format_size( *format, 1, 1 ) / sizeof( *new_buffer );
- int i, j, k;
-
- // Duplicate the existing channels
- for ( i = 0; i < *samples; i++ )
- {
- for ( j = 0; j < *channels; j++ )
- {
- new_buffer[ ( ( i * *channels ) + j ) * sample_size_factor ]
- = ((int16_t*)(*buffer))[ ( ( i * channels_avail ) + k ) * sample_size_factor ];
- k = ( k + 1 ) % channels_avail;
- }
- }
-
- // Update the audio buffer now - destroys the old
- mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
-
- *buffer = new_buffer;
- }
- else if ( channels_avail > *channels )
- {
- int size = mlt_audio_format_size( *format, *samples, *channels );
- int16_t *new_buffer = mlt_pool_alloc( size );
- int sample_size_factor = mlt_audio_format_size( *format, 1, 1 ) / sizeof( *new_buffer );
- int i, j;
-
- // Drop all but the first *channels
- for ( i = 0; i < *samples; i++ )
- {
- for ( j = 0; j < *channels; j++ )
- new_buffer[ ( ( i * *channels ) + j ) * sample_size_factor ]
- = ((int16_t*)(*buffer))[ ( ( i * channels_avail ) + j ) * sample_size_factor ];
- }
-
- // Update the audio buffer now - destroys the old
- mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
-
- *buffer = new_buffer;
- }
+ int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+ if ( error ) return error;
// Return now if no work to do
if ( output_rate != *frequency )
{
- mlt_log_verbose( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
+ mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n",
*channels, *samples, *frequency, output_rate );
// Do not convert to float unless we need to change the rate