2 * filter_audioconvert.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>
28 static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *format, mlt_audio_format requested_format )
31 mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
32 int channels = mlt_properties_get_int( properties, "audio_channels" );
33 int samples = mlt_properties_get_int( properties, "audio_samples" );
34 int size = mlt_audio_format_size( requested_format, samples, channels );
36 if ( *format != requested_format )
38 mlt_log_debug( NULL, "[filter audioconvert] %s -> %s %d channels %d samples\n",
39 mlt_audio_format_name( *format ), mlt_audio_format_name( requested_format ),
44 switch ( requested_format )
48 int32_t *buffer = mlt_pool_alloc( size );
51 for ( c = 0; c < channels; c++ )
53 int16_t *q = (int16_t*) *audio + c;
57 *p++ = (int32_t) *q << 16;
67 float *buffer = mlt_pool_alloc( size );
70 for ( c = 0; c < channels; c++ )
72 int16_t *q = (int16_t*) *audio + c;
76 *p++ = (float)( *q ) / 32768.0;
86 int32_t *buffer = mlt_pool_alloc( size );
88 int16_t *q = (int16_t*) *audio;
89 int i = samples * channels + 1;
91 *p++ = (int32_t) *q++ << 16;
98 float *buffer = mlt_pool_alloc( size );
100 int16_t *q = (int16_t*) *audio;
101 int i = samples * channels + 1;
104 float f = (float)( *q++ ) / 32768.0;
105 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
117 switch ( requested_format )
121 int16_t *buffer = mlt_pool_alloc( size );
123 int32_t *q = (int32_t*) *audio;
125 for ( s = 0; s < samples; s++ )
126 for ( c = 0; c < channels; c++ )
127 *p++ = *( q + c * samples + s ) >> 16;
132 case mlt_audio_float:
134 float *buffer = mlt_pool_alloc( size );
136 int32_t *q = (int32_t*) *audio;
137 int i = samples * channels + 1;
139 *p++ = (float)( *q++ ) / 2147483648.0;
144 case mlt_audio_s32le:
146 int32_t *buffer = mlt_pool_alloc( size );
148 int32_t *q = (int32_t*) *audio;
150 for ( s = 0; s < samples; s++ )
151 for ( c = 0; c < channels; c++ )
152 *p++ = *( q + c * samples + s );
157 case mlt_audio_f32le:
159 float *buffer = mlt_pool_alloc( size );
161 int32_t *q = (int32_t*) *audio;
163 for ( s = 0; s < samples; s++ )
164 for ( c = 0; c < channels; c++ )
166 float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
167 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
178 case mlt_audio_float:
179 switch ( requested_format )
183 int16_t *buffer = mlt_pool_alloc( size );
185 float *q = (float*) *audio;
187 for ( s = 0; s < samples; s++ )
188 for ( c = 0; c < channels; c++ )
190 float f = *( q + c * samples + s );
191 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
200 int32_t *buffer = mlt_pool_alloc( size );
202 float *q = (float*) *audio;
203 int i = samples * channels + 1;
207 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
208 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
214 case mlt_audio_s32le:
216 int32_t *buffer = mlt_pool_alloc( size );
218 float *q = (float*) *audio;
220 for ( s = 0; s < samples; s++ )
221 for ( c = 0; c < channels; c++ )
223 float f = *( q + c * samples + s );
224 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
225 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
231 case mlt_audio_f32le:
233 float *buffer = mlt_pool_alloc( size );
235 float *q = (float*) *audio;
237 for ( s = 0; s < samples; s++ )
238 for ( c = 0; c < channels; c++ )
239 *p++ = *( q + c * samples + s );
248 case mlt_audio_s32le:
249 switch ( requested_format )
253 int16_t *buffer = mlt_pool_alloc( size );
255 int32_t *q = (int32_t*) *audio;
256 int i = samples * channels + 1;
265 int32_t *buffer = mlt_pool_alloc( size );
268 for ( c = 0; c < channels; c++ )
270 int32_t *q = (int32_t*) *audio + c;
282 case mlt_audio_float:
284 float *buffer = mlt_pool_alloc( size );
287 for ( c = 0; c < channels; c++ )
289 int32_t *q = (int32_t*) *audio + c;
293 *p++ = (float)( *q ) / 2147483648.0;
301 case mlt_audio_f32le:
303 float *buffer = mlt_pool_alloc( size );
305 int32_t *q = (int32_t*) *audio;
306 int i = samples * channels + 1;
308 *p++ = (float)( *q++ ) / 2147483648.0;
317 case mlt_audio_f32le:
318 switch ( requested_format )
322 int16_t *buffer = mlt_pool_alloc( size );
324 float *q = (float*) *audio;
325 int i = samples * channels + 1;
329 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
336 case mlt_audio_float:
338 float *buffer = mlt_pool_alloc( size );
341 for ( c = 0; c < channels; c++ )
343 float *q = (float*) *audio + c;
357 int32_t *buffer = mlt_pool_alloc( size );
360 for ( c = 0; c < channels; c++ )
362 float *q = (float*) *audio + c;
367 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
368 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
376 case mlt_audio_s32le:
378 int32_t *buffer = mlt_pool_alloc( size );
380 float *q = (float*) *audio;
381 int i = samples * channels + 1;
385 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
386 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
402 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
403 *format = requested_format;
408 /** Filter processing.
411 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
413 frame->convert_audio = convert_audio;
417 /** Constructor for the filter.
420 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
422 mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
423 if ( mlt_filter_init( this, this ) == 0 )
424 this->process = filter_process;