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>
29 #define CLAMP( x, min, max ) (x) < (min) ? (min) : (x) > (max) ? (max) : (x)
32 static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *format, mlt_audio_format requested_format )
35 mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
36 int channels = mlt_properties_get_int( properties, "audio_channels" );
37 int samples = mlt_properties_get_int( properties, "audio_samples" );
38 int size = mlt_audio_format_size( requested_format, samples, channels );
40 if ( *format != requested_format )
42 mlt_log_debug( NULL, "[filter audioconvert] %s -> %s %d channels %d samples\n",
43 mlt_audio_format_name( *format ), mlt_audio_format_name( requested_format ),
48 switch ( requested_format )
52 int32_t *buffer = mlt_pool_alloc( size );
55 for ( c = 0; c < channels; c++ )
57 int16_t *q = (int16_t*) *audio + c;
61 *p++ = (int32_t) *q << 16;
71 float *buffer = mlt_pool_alloc( size );
74 for ( c = 0; c < channels; c++ )
76 int16_t *q = (int16_t*) *audio + c;
80 *p++ = (float)( *q ) / 32768.0;
90 int32_t *buffer = mlt_pool_alloc( size );
92 int16_t *q = (int16_t*) *audio;
93 int i = samples * channels + 1;
95 *p++ = (int32_t) *q++ << 16;
100 case mlt_audio_f32le:
102 float *buffer = mlt_pool_alloc( size );
104 int16_t *q = (int16_t*) *audio;
105 int i = samples * channels + 1;
108 float f = (float)( *q++ ) / 32768.0;
109 *p++ = CLAMP( f, -1.0f, 1.0f );
117 uint8_t *buffer = mlt_pool_alloc( size );
119 int16_t *q = (int16_t*) *audio;
120 int i = samples * channels + 1;
122 *p++ = ( *q++ >> 8 ) + 128;
132 switch ( requested_format )
136 int16_t *buffer = mlt_pool_alloc( size );
138 int32_t *q = (int32_t*) *audio;
140 for ( s = 0; s < samples; s++ )
141 for ( c = 0; c < channels; c++ )
142 *p++ = *( q + c * samples + s ) >> 16;
147 case mlt_audio_float:
149 float *buffer = mlt_pool_alloc( size );
151 int32_t *q = (int32_t*) *audio;
152 int i = samples * channels + 1;
154 *p++ = (float)( *q++ ) / 2147483648.0;
159 case mlt_audio_s32le:
161 int32_t *buffer = mlt_pool_alloc( size );
163 int32_t *q = (int32_t*) *audio;
165 for ( s = 0; s < samples; s++ )
166 for ( c = 0; c < channels; c++ )
167 *p++ = *( q + c * samples + s );
172 case mlt_audio_f32le:
174 float *buffer = mlt_pool_alloc( size );
176 int32_t *q = (int32_t*) *audio;
178 for ( s = 0; s < samples; s++ )
179 for ( c = 0; c < channels; c++ )
181 float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
182 *p++ = CLAMP( f, -1.0f, 1.0f );
190 uint8_t *buffer = mlt_pool_alloc( size );
192 int32_t *q = (int32_t*) *audio;
194 for ( s = 0; s < samples; s++ )
195 for ( c = 0; c < channels; c++ )
196 *p++ = ( q[c * samples + s] >> 24 ) + 128;
205 case mlt_audio_float:
206 switch ( requested_format )
210 int16_t *buffer = mlt_pool_alloc( size );
212 float *q = (float*) *audio;
214 for ( s = 0; s < samples; s++ )
215 for ( c = 0; c < channels; c++ )
217 float f = *( q + c * samples + s );
218 f = CLAMP( f, -1.0f, 1.0f );
227 int32_t *buffer = mlt_pool_alloc( size );
229 float *q = (float*) *audio;
230 int i = samples * channels + 1;
234 f = CLAMP( f, -1.0f, 1.0f );
235 int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
236 *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
242 case mlt_audio_s32le:
244 int32_t *buffer = mlt_pool_alloc( size );
246 float *q = (float*) *audio;
248 for ( s = 0; s < samples; s++ )
249 for ( c = 0; c < channels; c++ )
251 float f = *( q + c * samples + s );
252 f = CLAMP( f, -1.0f, 1.0f );
253 int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
254 *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
260 case mlt_audio_f32le:
262 float *buffer = mlt_pool_alloc( size );
264 float *q = (float*) *audio;
266 for ( s = 0; s < samples; s++ )
267 for ( c = 0; c < channels; c++ )
268 *p++ = *( q + c * samples + s );
275 uint8_t *buffer = mlt_pool_alloc( size );
277 float *q = (float*) *audio;
279 for ( s = 0; s < samples; s++ )
280 for ( c = 0; c < channels; c++ )
282 float f = *( q + c * samples + s );
283 f = CLAMP( f, -1.0f, 1.0f );
284 *p++ = ( 127 * f ) + 128;
294 case mlt_audio_s32le:
295 switch ( requested_format )
299 int16_t *buffer = mlt_pool_alloc( size );
301 int32_t *q = (int32_t*) *audio;
302 int i = samples * channels + 1;
311 int32_t *buffer = mlt_pool_alloc( size );
314 for ( c = 0; c < channels; c++ )
316 int32_t *q = (int32_t*) *audio + c;
328 case mlt_audio_float:
330 float *buffer = mlt_pool_alloc( size );
333 for ( c = 0; c < channels; c++ )
335 int32_t *q = (int32_t*) *audio + c;
339 *p++ = (float)( *q ) / 2147483648.0;
347 case mlt_audio_f32le:
349 float *buffer = mlt_pool_alloc( size );
351 int32_t *q = (int32_t*) *audio;
352 int i = samples * channels + 1;
354 *p++ = (float)( *q++ ) / 2147483648.0;
361 uint8_t *buffer = mlt_pool_alloc( size );
363 int32_t *q = (int32_t*) *audio;
364 int i = samples * channels + 1;
366 *p++ = ( *q++ >> 24 ) + 128;
375 case mlt_audio_f32le:
376 switch ( requested_format )
380 int16_t *buffer = mlt_pool_alloc( size );
382 float *q = (float*) *audio;
383 int i = samples * channels + 1;
387 f = CLAMP( f, -1.0f , 1.0f );
394 case mlt_audio_float:
396 float *buffer = mlt_pool_alloc( size );
399 for ( c = 0; c < channels; c++ )
401 float *q = (float*) *audio + c;
415 int32_t *buffer = mlt_pool_alloc( size );
418 for ( c = 0; c < channels; c++ )
420 float *q = (float*) *audio + c;
425 f = CLAMP( f, -1.0f , 1.0f );
426 int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
427 *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
435 case mlt_audio_s32le:
437 int32_t *buffer = mlt_pool_alloc( size );
439 float *q = (float*) *audio;
440 int i = samples * channels + 1;
444 f = CLAMP( f, -1.0f , 1.0f );
445 int64_t pcm = ( f > 0.0f ? 2147483647LL : 2147483648LL ) * f;
446 *p++ = CLAMP( pcm, -2147483648LL, 2147483647LL );
454 uint8_t *buffer = mlt_pool_alloc( size );
456 float *q = (float*) *audio;
457 int i = samples * channels + 1;
461 f = CLAMP( f, -1.0f , 1.0f );
462 *p++ = ( 127 * f ) + 128;
473 switch ( requested_format )
477 int32_t *buffer = mlt_pool_alloc( size );
480 for ( c = 0; c < channels; c++ )
482 uint8_t *q = (uint8_t*) *audio + c;
486 *p++ = ( (int32_t) *q - 128 ) << 24;
494 case mlt_audio_float:
496 float *buffer = mlt_pool_alloc( size );
499 for ( c = 0; c < channels; c++ )
501 uint8_t *q = (uint8_t*) *audio + c;
505 *p++ = ( (float) *q - 128 ) / 256.0f;
515 int16_t *buffer = mlt_pool_alloc( size );
517 uint8_t *q = (uint8_t*) *audio;
518 int i = samples * channels + 1;
520 *p++ = ( (int16_t) *q++ - 128 ) << 8;
525 case mlt_audio_s32le:
527 int32_t *buffer = mlt_pool_alloc( size );
529 uint8_t *q = (uint8_t*) *audio;
530 int i = samples * channels + 1;
532 *p++ = ( (int32_t) *q++ - 128 ) << 24;
537 case mlt_audio_f32le:
539 float *buffer = mlt_pool_alloc( size );
541 uint8_t *q = (uint8_t*) *audio;
542 int i = samples * channels + 1;
545 float f = ( (float) *q++ - 128 ) / 256.0f;
546 *p++ = CLAMP( f, -1.0f, 1.0f );
562 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
563 *format = requested_format;
568 /** Filter processing.
571 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
573 frame->convert_audio = convert_audio;
577 /** Constructor for the filter.
580 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
582 mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
583 if ( mlt_filter_init( this, this ) == 0 )
584 this->process = filter_process;