2 * filter_audiochannels.c -- convert from one audio format to another
3 * Copyright (C) 2009-2012 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_log.h>
27 static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
29 // Used to return number of channels in the source
30 int channels_avail = *channels;
32 // Get the producer's audio
33 int error = mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples );
34 if ( error ) return error;
36 if ( channels_avail < *channels )
38 int size = mlt_audio_format_size( *format, *samples, *channels );
39 int16_t *new_buffer = mlt_pool_alloc( size );
41 // Duplicate the existing channels
42 if ( *format == mlt_audio_s16 )
45 for ( i = 0; i < *samples; i++ )
47 for ( j = 0; j < *channels; j++ )
49 new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + k ];
50 k = ( k + 1 ) % channels_avail;
54 else if ( *format == mlt_audio_s32le || *format == mlt_audio_f32le )
56 int32_t *p = (int32_t*) new_buffer;
58 for ( i = 0; i < *samples; i++ )
60 for ( j = 0; j < *channels; j++ )
62 p[ ( i * *channels ) + j ] = ((int32_t*)(*buffer))[ ( i * channels_avail ) + k ];
63 k = ( k + 1 ) % channels_avail;
69 // non-interleaved - s32 or float
70 int size_avail = mlt_audio_format_size( *format, *samples, channels_avail );
71 int32_t *p = (int32_t*) new_buffer;
72 int i = *channels / channels_avail;
75 memcpy( p, *buffer, size_avail );
76 p += size_avail / sizeof(*p);
78 i = *channels % channels_avail;
81 size_avail = mlt_audio_format_size( *format, *samples, i );
82 memcpy( p, *buffer, size_avail );
85 // Update the audio buffer now - destroys the old
86 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
89 else if ( channels_avail > *channels )
91 int size = mlt_audio_format_size( *format, *samples, *channels );
92 int16_t *new_buffer = mlt_pool_alloc( size );
94 // Drop all but the first *channels
95 if ( *format == mlt_audio_s16 )
98 for ( i = 0; i < *samples; i++ )
99 for ( j = 0; j < *channels; j++ )
100 new_buffer[ ( i * *channels ) + j ] = ((int16_t*)(*buffer))[ ( i * channels_avail ) + j ];
105 memcpy( new_buffer, *buffer, size );
107 // Update the audio buffer now - destroys the old
108 mlt_frame_set_audio( frame, new_buffer, *format, size, mlt_pool_release );
109 *buffer = new_buffer;
114 /** Filter processing.
117 static mlt_frame filter_process( mlt_filter filter, mlt_frame frame )
119 mlt_frame_push_audio( frame, filter_get_audio );
123 /** Constructor for the filter.
126 mlt_filter filter_audiochannels_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
128 mlt_filter filter = mlt_filter_new();
130 filter->process = filter_process;