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;
114 uint8_t *buffer = mlt_pool_alloc( size );
116 int16_t *q = (int16_t*) *audio;
117 int i = samples * channels + 1;
119 *p++ = ( *q++ >> 8 ) + 128;
129 switch ( requested_format )
133 int16_t *buffer = mlt_pool_alloc( size );
135 int32_t *q = (int32_t*) *audio;
137 for ( s = 0; s < samples; s++ )
138 for ( c = 0; c < channels; c++ )
139 *p++ = *( q + c * samples + s ) >> 16;
144 case mlt_audio_float:
146 float *buffer = mlt_pool_alloc( size );
148 int32_t *q = (int32_t*) *audio;
149 int i = samples * channels + 1;
151 *p++ = (float)( *q++ ) / 2147483648.0;
156 case mlt_audio_s32le:
158 int32_t *buffer = mlt_pool_alloc( size );
160 int32_t *q = (int32_t*) *audio;
162 for ( s = 0; s < samples; s++ )
163 for ( c = 0; c < channels; c++ )
164 *p++ = *( q + c * samples + s );
169 case mlt_audio_f32le:
171 float *buffer = mlt_pool_alloc( size );
173 int32_t *q = (int32_t*) *audio;
175 for ( s = 0; s < samples; s++ )
176 for ( c = 0; c < channels; c++ )
178 float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
179 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
188 uint8_t *buffer = mlt_pool_alloc( size );
190 int32_t *q = (int32_t*) *audio;
192 for ( s = 0; s < samples; s++ )
193 for ( c = 0; c < channels; c++ )
194 *p++ = ( q[c * samples + s] >> 24 ) + 128;
203 case mlt_audio_float:
204 switch ( requested_format )
208 int16_t *buffer = mlt_pool_alloc( size );
210 float *q = (float*) *audio;
212 for ( s = 0; s < samples; s++ )
213 for ( c = 0; c < channels; c++ )
215 float f = *( q + c * samples + s );
216 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
225 int32_t *buffer = mlt_pool_alloc( size );
227 float *q = (float*) *audio;
228 int i = samples * channels + 1;
232 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
233 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
239 case mlt_audio_s32le:
241 int32_t *buffer = mlt_pool_alloc( size );
243 float *q = (float*) *audio;
245 for ( s = 0; s < samples; s++ )
246 for ( c = 0; c < channels; c++ )
248 float f = *( q + c * samples + s );
249 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
250 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
256 case mlt_audio_f32le:
258 float *buffer = mlt_pool_alloc( size );
260 float *q = (float*) *audio;
262 for ( s = 0; s < samples; s++ )
263 for ( c = 0; c < channels; c++ )
264 *p++ = *( q + c * samples + s );
271 uint8_t *buffer = mlt_pool_alloc( size );
273 float *q = (float*) *audio;
275 for ( s = 0; s < samples; s++ )
276 for ( c = 0; c < channels; c++ )
278 float f = *( q + c * samples + s );
279 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
280 *p++ = ( 127 * f ) + 128;
290 case mlt_audio_s32le:
291 switch ( requested_format )
295 int16_t *buffer = mlt_pool_alloc( size );
297 int32_t *q = (int32_t*) *audio;
298 int i = samples * channels + 1;
307 int32_t *buffer = mlt_pool_alloc( size );
310 for ( c = 0; c < channels; c++ )
312 int32_t *q = (int32_t*) *audio + c;
324 case mlt_audio_float:
326 float *buffer = mlt_pool_alloc( size );
329 for ( c = 0; c < channels; c++ )
331 int32_t *q = (int32_t*) *audio + c;
335 *p++ = (float)( *q ) / 2147483648.0;
343 case mlt_audio_f32le:
345 float *buffer = mlt_pool_alloc( size );
347 int32_t *q = (int32_t*) *audio;
348 int i = samples * channels + 1;
350 *p++ = (float)( *q++ ) / 2147483648.0;
357 uint8_t *buffer = mlt_pool_alloc( size );
359 int32_t *q = (int32_t*) *audio;
360 int i = samples * channels + 1;
362 *p++ = ( *q++ >> 24 ) + 128;
371 case mlt_audio_f32le:
372 switch ( requested_format )
376 int16_t *buffer = mlt_pool_alloc( size );
378 float *q = (float*) *audio;
379 int i = samples * channels + 1;
383 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
390 case mlt_audio_float:
392 float *buffer = mlt_pool_alloc( size );
395 for ( c = 0; c < channels; c++ )
397 float *q = (float*) *audio + c;
411 int32_t *buffer = mlt_pool_alloc( size );
414 for ( c = 0; c < channels; c++ )
416 float *q = (float*) *audio + c;
421 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
422 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
430 case mlt_audio_s32le:
432 int32_t *buffer = mlt_pool_alloc( size );
434 float *q = (float*) *audio;
435 int i = samples * channels + 1;
439 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
440 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
448 uint8_t *buffer = mlt_pool_alloc( size );
450 float *q = (float*) *audio;
451 int i = samples * channels + 1;
455 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
456 *p++ = ( 127 * f ) + 128;
467 switch ( requested_format )
471 int32_t *buffer = mlt_pool_alloc( size );
474 for ( c = 0; c < channels; c++ )
476 uint8_t *q = (uint8_t*) *audio + c;
480 *p++ = ( (int32_t) *q - 128 ) << 24;
488 case mlt_audio_float:
490 float *buffer = mlt_pool_alloc( size );
493 for ( c = 0; c < channels; c++ )
495 uint8_t *q = (uint8_t*) *audio + c;
499 *p++ = ( (float) *q - 128 ) / 256.0f;
509 int16_t *buffer = mlt_pool_alloc( size );
511 uint8_t *q = (uint8_t*) *audio;
512 int i = samples * channels + 1;
514 *p++ = ( (int16_t) *q++ - 128 ) << 8;
519 case mlt_audio_s32le:
521 int32_t *buffer = mlt_pool_alloc( size );
523 uint8_t *q = (uint8_t*) *audio;
524 int i = samples * channels + 1;
526 *p++ = ( (int32_t) *q++ - 128 ) << 24;
531 case mlt_audio_f32le:
533 float *buffer = mlt_pool_alloc( size );
535 uint8_t *q = (uint8_t*) *audio;
536 int i = samples * channels + 1;
539 float f = ( (float) *q++ - 128 ) / 256.0f;
540 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
557 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
558 *format = requested_format;
563 /** Filter processing.
566 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
568 frame->convert_audio = convert_audio;
572 /** Constructor for the filter.
575 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
577 mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
578 if ( mlt_filter_init( this, this ) == 0 )
579 this->process = filter_process;