]> git.sesse.net Git - mlt/blob - src/modules/core/filter_audioconvert.c
Fix calloc() parameter ordering
[mlt] / src / modules / core / filter_audioconvert.c
1 /*
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>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_log.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *format, mlt_audio_format requested_format )
29 {
30         int error = 1;
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 );
35
36         if ( *format != requested_format )
37         {
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 ),
40                         channels, samples );
41                 switch ( *format )
42                 {
43                 case mlt_audio_s16:
44                         switch ( requested_format )
45                         {
46                         case mlt_audio_s32:
47                         {
48                                 int32_t *buffer = mlt_pool_alloc( size );
49                                 int32_t *p = buffer;
50                                 int c;
51                                 for ( c = 0; c < channels; c++ )
52                                 {
53                                         int16_t *q = (int16_t*) *audio + c;
54                                         int i = samples + 1;
55                                         while ( --i )
56                                         {
57                                                 *p++ = (int32_t) *q << 16;
58                                                 q += channels;
59                                         }
60                                 }
61                                 *audio = buffer;
62                                 error = 0;
63                                 break;
64                         }
65                         case mlt_audio_float:
66                         {
67                                 float *buffer = mlt_pool_alloc( size );
68                                 float *p = buffer;
69                                 int c;
70                                 for ( c = 0; c < channels; c++ )
71                                 {
72                                         int16_t *q = (int16_t*) *audio + c;
73                                         int i = samples + 1;
74                                         while ( --i )
75                                         {
76                                                 *p++ = (float)( *q ) / 32768.0;
77                                                 q += channels;
78                                         }
79                                 }
80                                 *audio = buffer;
81                                 error = 0;
82                                 break;
83                         }
84                         case mlt_audio_s32le:
85                         {
86                                 int32_t *buffer = mlt_pool_alloc( size );
87                                 int32_t *p = buffer;
88                                 int16_t *q = (int16_t*) *audio;
89                                 int i = samples * channels + 1;
90                                 while ( --i )
91                                         *p++ = (int32_t) *q++ << 16;
92                                 *audio = buffer;
93                                 error = 0;
94                                 break;
95                         }
96                         case mlt_audio_f32le:
97                         {
98                                 float *buffer = mlt_pool_alloc( size );
99                                 float *p = buffer;
100                                 int16_t *q = (int16_t*) *audio;
101                                 int i = samples * channels + 1;
102                                 while ( --i )
103                                 {
104                                         float f = (float)( *q++ ) / 32768.0;
105                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
106                                         *p++ = f;
107                                 }
108                                 *audio = buffer;
109                                 error = 0;
110                                 break;
111                         }
112                         default:
113                                 break;
114                         }
115                         break;
116                 case mlt_audio_s32:
117                         switch ( requested_format )
118                         {
119                         case mlt_audio_s16:
120                         {
121                                 int16_t *buffer = mlt_pool_alloc( size );
122                                 int16_t *p = buffer;
123                                 int32_t *q = (int32_t*) *audio;
124                                 int s, c;
125                                 for ( s = 0; s < samples; s++ )
126                                         for ( c = 0; c < channels; c++ )
127                                                 *p++ = *( q + c * samples + s ) >> 16;
128                                 *audio = buffer;
129                                 error = 0;
130                                 break;
131                         }
132                         case mlt_audio_float:
133                         {
134                                 float *buffer = mlt_pool_alloc( size );
135                                 float *p = buffer;
136                                 int32_t *q = (int32_t*) *audio;
137                                 int i = samples * channels + 1;
138                                 while ( --i )
139                                         *p++ = (float)( *q++ ) / 2147483648.0;
140                                 *audio = buffer;
141                                 error = 0;
142                                 break;
143                         }
144                         case mlt_audio_s32le:
145                         {
146                                 int32_t *buffer = mlt_pool_alloc( size );
147                                 int32_t *p = buffer;
148                                 int32_t *q = (int32_t*) *audio;
149                                 int s, c;
150                                 for ( s = 0; s < samples; s++ )
151                                         for ( c = 0; c < channels; c++ )
152                                                 *p++ = *( q + c * samples + s );
153                                 *audio = buffer;
154                                 error = 0;
155                                 break;
156                         }
157                         case mlt_audio_f32le:
158                         {
159                                 float *buffer = mlt_pool_alloc( size );
160                                 float *p = buffer;
161                                 int32_t *q = (int32_t*) *audio;
162                                 int s, c;
163                                 for ( s = 0; s < samples; s++ )
164                                         for ( c = 0; c < channels; c++ )
165                                         {
166                                                 float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
167                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
168                                                 *p++ = f;
169                                         }
170                                 *audio = buffer;
171                                 error = 0;
172                                 break;
173                         }
174                         default:
175                                 break;
176                         }
177                         break;
178                 case mlt_audio_float:
179                         switch ( requested_format )
180                         {
181                         case mlt_audio_s16:
182                         {
183                                 int16_t *buffer = mlt_pool_alloc( size );
184                                 int16_t *p = buffer;
185                                 float *q = (float*) *audio;
186                                 int s, c;
187                                 for ( s = 0; s < samples; s++ )
188                                         for ( c = 0; c < channels; c++ )
189                                         {
190                                                 float f = *( q + c * samples + s );
191                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
192                                                 *p++ = 32767 * f;
193                                         }
194                                 *audio = buffer;
195                                 error = 0;
196                                 break;
197                         }
198                         case mlt_audio_s32:
199                         {
200                                 int32_t *buffer = mlt_pool_alloc( size );
201                                 int32_t *p = buffer;
202                                 float *q = (float*) *audio;
203                                 int i = samples * channels + 1;
204                                 while ( --i )
205                                 {
206                                         float f = *q++;
207                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
208                                         *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
209                                 }
210                                 *audio = buffer;
211                                 error = 0;
212                                 break;
213                         }
214                         case mlt_audio_s32le:
215                         {
216                                 int32_t *buffer = mlt_pool_alloc( size );
217                                 int32_t *p = buffer;
218                                 float *q = (float*) *audio;
219                                 int s, c;
220                                 for ( s = 0; s < samples; s++ )
221                                         for ( c = 0; c < channels; c++ )
222                                         {
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;
226                                         }
227                                 *audio = buffer;
228                                 error = 0;
229                                 break;
230                         }
231                         case mlt_audio_f32le:
232                         {
233                                 float *buffer = mlt_pool_alloc( size );
234                                 float *p = buffer;
235                                 float *q = (float*) *audio;
236                                 int s, c;
237                                 for ( s = 0; s < samples; s++ )
238                                         for ( c = 0; c < channels; c++ )
239                                                 *p++ = *( q + c * samples + s );
240                                 *audio = buffer;
241                                 error = 0;
242                                 break;
243                         }
244                         default:
245                                 break;
246                         }
247                         break;
248                 case mlt_audio_s32le:
249                         switch ( requested_format )
250                         {
251                         case mlt_audio_s16:
252                         {
253                                 int16_t *buffer = mlt_pool_alloc( size );
254                                 int16_t *p = buffer;
255                                 int32_t *q = (int32_t*) *audio;
256                                 int i = samples * channels + 1;
257                                 while ( --i )
258                                         *p++ = *q++ >> 16;
259                                 *audio = buffer;
260                                 error = 0;
261                                 break;
262                         }
263                         case mlt_audio_s32:
264                         {
265                                 int32_t *buffer = mlt_pool_alloc( size );
266                                 int32_t *p = buffer;
267                                 int c;
268                                 for ( c = 0; c < channels; c++ )
269                                 {
270                                         int32_t *q = (int32_t*) *audio + c;
271                                         int i = samples + 1;
272                                         while ( --i )
273                                         {
274                                                 *p++ = *q;
275                                                 q += channels;
276                                         }
277                                 }
278                                 *audio = buffer;
279                                 error = 0;
280                                 break;
281                         }
282                         case mlt_audio_float:
283                         {
284                                 float *buffer = mlt_pool_alloc( size );
285                                 float *p = buffer;
286                                 int c;
287                                 for ( c = 0; c < channels; c++ )
288                                 {
289                                         int32_t *q = (int32_t*) *audio + c;
290                                         int i = samples + 1;
291                                         while ( --i )
292                                         {
293                                                 *p++ = (float)( *q ) / 2147483648.0;
294                                                 q += channels;
295                                         }
296                                 }
297                                 *audio = buffer;
298                                 error = 0;
299                                 break;
300                         }
301                         case mlt_audio_f32le:
302                         {
303                                 float *buffer = mlt_pool_alloc( size );
304                                 float *p = buffer;
305                                 int32_t *q = (int32_t*) *audio;
306                                 int i = samples * channels + 1;
307                                 while ( --i )
308                                         *p++ = (float)( *q++ ) / 2147483648.0;
309                                 *audio = buffer;
310                                 error = 0;
311                                 break;
312                         }
313                         default:
314                                 break;
315                         }
316                         break;
317                 case mlt_audio_f32le:
318                         switch ( requested_format )
319                         {
320                         case mlt_audio_s16:
321                         {
322                                 int16_t *buffer = mlt_pool_alloc( size );
323                                 int16_t *p = buffer;
324                                 float *q = (float*) *audio;
325                                 int i = samples * channels + 1;
326                                 while ( --i )
327                                 {
328                                         float f = *q++;
329                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
330                                         *p++ = 32767 * f;
331                                 }
332                                 *audio = buffer;
333                                 error = 0;
334                                 break;
335                         }
336                         case mlt_audio_float:
337                         {
338                                 float *buffer = mlt_pool_alloc( size );
339                                 float *p = buffer;
340                                 int c;
341                                 for ( c = 0; c < channels; c++ )
342                                 {
343                                         float *q = (float*) *audio + c;
344                                         int i = samples + 1;
345                                         while ( --i )
346                                         {
347                                                 *p++ = *q;
348                                                 q += channels;
349                                         }
350                                 }
351                                 *audio = buffer;
352                                 error = 0;
353                                 break;
354                         }
355                         case mlt_audio_s32:
356                         {
357                                 int32_t *buffer = mlt_pool_alloc( size );
358                                 int32_t *p = buffer;
359                                 int c;
360                                 for ( c = 0; c < channels; c++ )
361                                 {
362                                         float *q = (float*) *audio + c;
363                                         int i = samples + 1;
364                                         while ( --i )
365                                         {
366                                                 float f = *q;
367                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
368                                                 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
369                                                 q += channels;
370                                         }
371                                 }
372                                 *audio = buffer;
373                                 error = 0;
374                                 break;
375                         }
376                         case mlt_audio_s32le:
377                         {
378                                 int32_t *buffer = mlt_pool_alloc( size );
379                                 int32_t *p = buffer;
380                                 float *q = (float*) *audio;
381                                 int i = samples * channels + 1;
382                                 while ( --i )
383                                 {
384                                         float f = *q++;
385                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
386                                         *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
387                                 }
388                                 *audio = buffer;
389                                 error = 0;
390                                 break;
391                         }
392                         default:
393                                 break;
394                         }
395                         break;
396                 default:
397                         break;
398                 }
399         }
400         if ( !error )
401         {
402                 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
403                 *format = requested_format;
404         }
405         return error;
406 }
407
408 /** Filter processing.
409 */
410
411 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
412 {
413         frame->convert_audio = convert_audio;
414         return frame;
415 }
416
417 /** Constructor for the filter.
418 */
419
420 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
421 {
422         mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
423         if ( mlt_filter_init( this, this ) == 0 )
424                 this->process = filter_process;
425         return this;
426 }