2 * filter_audioconvert.c -- convert from one audio format to another
3 * Copyright (C) 2009 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;
89 switch ( requested_format )
93 int16_t *buffer = mlt_pool_alloc( size );
95 int32_t *q = (int32_t*) *audio;
97 for ( s = 0; s < samples; s++ )
98 for ( c = 0; c < channels; c++ )
99 *p++ = *( q + c * samples + s ) >> 16;
104 case mlt_audio_float:
106 float *buffer = mlt_pool_alloc( size );
108 int32_t *q = (int32_t*) *audio;
109 int i = samples * channels + 1;
111 *p++ = (float)( *q++ ) / 2147483648.0;
120 case mlt_audio_float:
121 switch ( requested_format )
125 int16_t *buffer = mlt_pool_alloc( size );
127 float *q = (float*) *audio;
129 for ( s = 0; s < samples; s++ )
130 for ( c = 0; c < channels; c++ )
132 float f = *( q + c * samples + s );
133 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
142 int32_t *buffer = mlt_pool_alloc( size );
144 float *q = (float*) *audio;
145 int i = samples * channels + 1;
149 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
150 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
160 case mlt_audio_s32le:
161 switch ( requested_format )
165 int16_t *buffer = mlt_pool_alloc( size );
167 int32_t *q = (int32_t*) *audio;
168 int i = samples * channels + 1;
177 int32_t *buffer = mlt_pool_alloc( size );
180 for ( c = 0; c < channels; c++ )
182 int32_t *q = (int32_t*) *audio + c;
194 case mlt_audio_float:
196 float *buffer = mlt_pool_alloc( size );
199 for ( c = 0; c < channels; c++ )
201 int32_t *q = (int32_t*) *audio + c;
205 *p++ = (float)( *q ) / 2147483648.0;
217 case mlt_audio_f32le:
218 switch ( requested_format )
222 int16_t *buffer = mlt_pool_alloc( size );
224 float *q = (float*) *audio;
225 int i = samples * channels + 1;
229 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
236 case mlt_audio_float:
238 float *buffer = mlt_pool_alloc( size );
241 for ( c = 0; c < channels; c++ )
243 float *q = (float*) *audio + c;
257 int32_t *buffer = mlt_pool_alloc( size );
260 for ( c = 0; c < channels; c++ )
262 float *q = (float*) *audio + c;
267 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
268 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
286 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
287 *format = requested_format;
292 /** Filter processing.
295 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
297 frame->convert_audio = convert_audio;
301 /** Constructor for the filter.
304 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
306 mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
307 if ( mlt_filter_init( this, this ) == 0 )
308 this->process = filter_process;