]> git.sesse.net Git - mlt/blob - src/modules/core/filter_audioconvert.c
a38219286f7c10968b2589296f240b3e0d91d398
[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                         case mlt_audio_u8:
113                         {
114                                 uint8_t *buffer = mlt_pool_alloc( size );
115                                 uint8_t *p = buffer;
116                                 int16_t *q = (int16_t*) *audio;
117                                 int i = samples * channels + 1;
118                                 while ( --i )
119                                         *p++ = ( *q++ >> 8 ) + 128;
120                                 *audio = buffer;
121                                 error = 0;
122                                 break;
123                         }
124                         default:
125                                 break;
126                         }
127                         break;
128                 case mlt_audio_s32:
129                         switch ( requested_format )
130                         {
131                         case mlt_audio_s16:
132                         {
133                                 int16_t *buffer = mlt_pool_alloc( size );
134                                 int16_t *p = buffer;
135                                 int32_t *q = (int32_t*) *audio;
136                                 int s, c;
137                                 for ( s = 0; s < samples; s++ )
138                                         for ( c = 0; c < channels; c++ )
139                                                 *p++ = *( q + c * samples + s ) >> 16;
140                                 *audio = buffer;
141                                 error = 0;
142                                 break;
143                         }
144                         case mlt_audio_float:
145                         {
146                                 float *buffer = mlt_pool_alloc( size );
147                                 float *p = buffer;
148                                 int32_t *q = (int32_t*) *audio;
149                                 int i = samples * channels + 1;
150                                 while ( --i )
151                                         *p++ = (float)( *q++ ) / 2147483648.0;
152                                 *audio = buffer;
153                                 error = 0;
154                                 break;
155                         }
156                         case mlt_audio_s32le:
157                         {
158                                 int32_t *buffer = mlt_pool_alloc( size );
159                                 int32_t *p = buffer;
160                                 int32_t *q = (int32_t*) *audio;
161                                 int s, c;
162                                 for ( s = 0; s < samples; s++ )
163                                         for ( c = 0; c < channels; c++ )
164                                                 *p++ = *( q + c * samples + s );
165                                 *audio = buffer;
166                                 error = 0;
167                                 break;
168                         }
169                         case mlt_audio_f32le:
170                         {
171                                 float *buffer = mlt_pool_alloc( size );
172                                 float *p = buffer;
173                                 int32_t *q = (int32_t*) *audio;
174                                 int s, c;
175                                 for ( s = 0; s < samples; s++ )
176                                         for ( c = 0; c < channels; c++ )
177                                         {
178                                                 float f = (float)( *( q + c * samples + s ) ) / 2147483648.0;
179                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
180                                                 *p++ = f;
181                                         }
182                                 *audio = buffer;
183                                 error = 0;
184                                 break;
185                         }
186                         case mlt_audio_u8:
187                         {
188                                 uint8_t *buffer = mlt_pool_alloc( size );
189                                 uint8_t *p = buffer;
190                                 int32_t *q = (int32_t*) *audio;
191                                 int s, c;
192                                 for ( s = 0; s < samples; s++ )
193                                         for ( c = 0; c < channels; c++ )
194                                                 *p++ = ( q[c * samples + s] >> 24 ) + 128;
195                                 *audio = buffer;
196                                 error = 0;
197                                 break;
198                         }
199                         default:
200                                 break;
201                         }
202                         break;
203                 case mlt_audio_float:
204                         switch ( requested_format )
205                         {
206                         case mlt_audio_s16:
207                         {
208                                 int16_t *buffer = mlt_pool_alloc( size );
209                                 int16_t *p = buffer;
210                                 float *q = (float*) *audio;
211                                 int s, c;
212                                 for ( s = 0; s < samples; s++ )
213                                         for ( c = 0; c < channels; c++ )
214                                         {
215                                                 float f = *( q + c * samples + s );
216                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
217                                                 *p++ = 32767 * f;
218                                         }
219                                 *audio = buffer;
220                                 error = 0;
221                                 break;
222                         }
223                         case mlt_audio_s32:
224                         {
225                                 int32_t *buffer = mlt_pool_alloc( size );
226                                 int32_t *p = buffer;
227                                 float *q = (float*) *audio;
228                                 int i = samples * channels + 1;
229                                 while ( --i )
230                                 {
231                                         float f = *q++;
232                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
233                                         *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
234                                 }
235                                 *audio = buffer;
236                                 error = 0;
237                                 break;
238                         }
239                         case mlt_audio_s32le:
240                         {
241                                 int32_t *buffer = mlt_pool_alloc( size );
242                                 int32_t *p = buffer;
243                                 float *q = (float*) *audio;
244                                 int s, c;
245                                 for ( s = 0; s < samples; s++ )
246                                         for ( c = 0; c < channels; c++ )
247                                         {
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;
251                                         }
252                                 *audio = buffer;
253                                 error = 0;
254                                 break;
255                         }
256                         case mlt_audio_f32le:
257                         {
258                                 float *buffer = mlt_pool_alloc( size );
259                                 float *p = buffer;
260                                 float *q = (float*) *audio;
261                                 int s, c;
262                                 for ( s = 0; s < samples; s++ )
263                                         for ( c = 0; c < channels; c++ )
264                                                 *p++ = *( q + c * samples + s );
265                                 *audio = buffer;
266                                 error = 0;
267                                 break;
268                         }
269                         case mlt_audio_u8:
270                         {
271                                 uint8_t *buffer = mlt_pool_alloc( size );
272                                 uint8_t *p = buffer;
273                                 float *q = (float*) *audio;
274                                 int s, c;
275                                 for ( s = 0; s < samples; s++ )
276                                         for ( c = 0; c < channels; c++ )
277                                         {
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;
281                                         }
282                                 *audio = buffer;
283                                 error = 0;
284                                 break;
285                         }
286                         default:
287                                 break;
288                         }
289                         break;
290                 case mlt_audio_s32le:
291                         switch ( requested_format )
292                         {
293                         case mlt_audio_s16:
294                         {
295                                 int16_t *buffer = mlt_pool_alloc( size );
296                                 int16_t *p = buffer;
297                                 int32_t *q = (int32_t*) *audio;
298                                 int i = samples * channels + 1;
299                                 while ( --i )
300                                         *p++ = *q++ >> 16;
301                                 *audio = buffer;
302                                 error = 0;
303                                 break;
304                         }
305                         case mlt_audio_s32:
306                         {
307                                 int32_t *buffer = mlt_pool_alloc( size );
308                                 int32_t *p = buffer;
309                                 int c;
310                                 for ( c = 0; c < channels; c++ )
311                                 {
312                                         int32_t *q = (int32_t*) *audio + c;
313                                         int i = samples + 1;
314                                         while ( --i )
315                                         {
316                                                 *p++ = *q;
317                                                 q += channels;
318                                         }
319                                 }
320                                 *audio = buffer;
321                                 error = 0;
322                                 break;
323                         }
324                         case mlt_audio_float:
325                         {
326                                 float *buffer = mlt_pool_alloc( size );
327                                 float *p = buffer;
328                                 int c;
329                                 for ( c = 0; c < channels; c++ )
330                                 {
331                                         int32_t *q = (int32_t*) *audio + c;
332                                         int i = samples + 1;
333                                         while ( --i )
334                                         {
335                                                 *p++ = (float)( *q ) / 2147483648.0;
336                                                 q += channels;
337                                         }
338                                 }
339                                 *audio = buffer;
340                                 error = 0;
341                                 break;
342                         }
343                         case mlt_audio_f32le:
344                         {
345                                 float *buffer = mlt_pool_alloc( size );
346                                 float *p = buffer;
347                                 int32_t *q = (int32_t*) *audio;
348                                 int i = samples * channels + 1;
349                                 while ( --i )
350                                         *p++ = (float)( *q++ ) / 2147483648.0;
351                                 *audio = buffer;
352                                 error = 0;
353                                 break;
354                         }
355                         case mlt_audio_u8:
356                         {
357                                 uint8_t *buffer = mlt_pool_alloc( size );
358                                 uint8_t *p = buffer;
359                                 int32_t *q = (int32_t*) *audio;
360                                 int i = samples * channels + 1;
361                                 while ( --i )
362                                         *p++ = ( *q++ >> 24 ) + 128;
363                                 *audio = buffer;
364                                 error = 0;
365                                 break;
366                         }
367                         default:
368                                 break;
369                         }
370                         break;
371                 case mlt_audio_f32le:
372                         switch ( requested_format )
373                         {
374                         case mlt_audio_s16:
375                         {
376                                 int16_t *buffer = mlt_pool_alloc( size );
377                                 int16_t *p = buffer;
378                                 float *q = (float*) *audio;
379                                 int i = samples * channels + 1;
380                                 while ( --i )
381                                 {
382                                         float f = *q++;
383                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
384                                         *p++ = 32767 * f;
385                                 }
386                                 *audio = buffer;
387                                 error = 0;
388                                 break;
389                         }
390                         case mlt_audio_float:
391                         {
392                                 float *buffer = mlt_pool_alloc( size );
393                                 float *p = buffer;
394                                 int c;
395                                 for ( c = 0; c < channels; c++ )
396                                 {
397                                         float *q = (float*) *audio + c;
398                                         int i = samples + 1;
399                                         while ( --i )
400                                         {
401                                                 *p++ = *q;
402                                                 q += channels;
403                                         }
404                                 }
405                                 *audio = buffer;
406                                 error = 0;
407                                 break;
408                         }
409                         case mlt_audio_s32:
410                         {
411                                 int32_t *buffer = mlt_pool_alloc( size );
412                                 int32_t *p = buffer;
413                                 int c;
414                                 for ( c = 0; c < channels; c++ )
415                                 {
416                                         float *q = (float*) *audio + c;
417                                         int i = samples + 1;
418                                         while ( --i )
419                                         {
420                                                 float f = *q;
421                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
422                                                 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
423                                                 q += channels;
424                                         }
425                                 }
426                                 *audio = buffer;
427                                 error = 0;
428                                 break;
429                         }
430                         case mlt_audio_s32le:
431                         {
432                                 int32_t *buffer = mlt_pool_alloc( size );
433                                 int32_t *p = buffer;
434                                 float *q = (float*) *audio;
435                                 int i = samples * channels + 1;
436                                 while ( --i )
437                                 {
438                                         float f = *q++;
439                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
440                                         *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
441                                 }
442                                 *audio = buffer;
443                                 error = 0;
444                                 break;
445                         }
446                         case mlt_audio_u8:
447                         {
448                                 uint8_t *buffer = mlt_pool_alloc( size );
449                                 uint8_t *p = buffer;
450                                 float *q = (float*) *audio;
451                                 int i = samples * channels + 1;
452                                 while ( --i )
453                                 {
454                                         float f = *q++;
455                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
456                                         *p++ = ( 127 * f ) + 128;
457                                 }
458                                 *audio = buffer;
459                                 error = 0;
460                                 break;
461                         }
462                         default:
463                                 break;
464                         }
465                         break;
466                 case mlt_audio_u8:
467                         switch ( requested_format )
468                         {
469                         case mlt_audio_s32:
470                         {
471                                 int32_t *buffer = mlt_pool_alloc( size );
472                                 int32_t *p = buffer;
473                                 int c;
474                                 for ( c = 0; c < channels; c++ )
475                                 {
476                                         uint8_t *q = (uint8_t*) *audio + c;
477                                         int i = samples + 1;
478                                         while ( --i )
479                                         {
480                                                 *p++ = ( (int32_t) *q - 128 ) << 24;
481                                                 q += channels;
482                                         }
483                                 }
484                                 *audio = buffer;
485                                 error = 0;
486                                 break;
487                         }
488                         case mlt_audio_float:
489                         {
490                                 float *buffer = mlt_pool_alloc( size );
491                                 float *p = buffer;
492                                 int c;
493                                 for ( c = 0; c < channels; c++ )
494                                 {
495                                         uint8_t *q = (uint8_t*) *audio + c;
496                                         int i = samples + 1;
497                                         while ( --i )
498                                         {
499                                                 *p++ = ( (float) *q - 128 ) / 256.0f;
500                                                 q += channels;
501                                         }
502                                 }
503                                 *audio = buffer;
504                                 error = 0;
505                                 break;
506                         }
507                         case mlt_audio_s16:
508                         {
509                                 int16_t *buffer = mlt_pool_alloc( size );
510                                 int16_t *p = buffer;
511                                 uint8_t *q = (uint8_t*) *audio;
512                                 int i = samples * channels + 1;
513                                 while ( --i )
514                                         *p++ = ( (int16_t) *q++ - 128 ) << 8;
515                                 *audio = buffer;
516                                 error = 0;
517                                 break;
518                         }
519                         case mlt_audio_s32le:
520                         {
521                                 int32_t *buffer = mlt_pool_alloc( size );
522                                 int32_t *p = buffer;
523                                 uint8_t *q = (uint8_t*) *audio;
524                                 int i = samples * channels + 1;
525                                 while ( --i )
526                                         *p++ = ( (int32_t) *q++ - 128 ) << 24;
527                                 *audio = buffer;
528                                 error = 0;
529                                 break;
530                         }
531                         case mlt_audio_f32le:
532                         {
533                                 float *buffer = mlt_pool_alloc( size );
534                                 float *p = buffer;
535                                 uint8_t *q = (uint8_t*) *audio;
536                                 int i = samples * channels + 1;
537                                 while ( --i )
538                                 {
539                                         float f = ( (float) *q++ - 128 ) / 256.0f;
540                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
541                                         *p++ = f;
542                                 }
543                                 *audio = buffer;
544                                 error = 0;
545                                 break;
546                         }
547                         default:
548                                 break;
549                         }
550                         break;
551                 default:
552                         break;
553                 }
554         }
555         if ( !error )
556         {
557                 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
558                 *format = requested_format;
559         }
560         return error;
561 }
562
563 /** Filter processing.
564 */
565
566 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
567 {
568         frame->convert_audio = convert_audio;
569         return frame;
570 }
571
572 /** Constructor for the filter.
573 */
574
575 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
576 {
577         mlt_filter this = calloc( 1, sizeof( struct mlt_filter_s ) );
578         if ( mlt_filter_init( this, this ) == 0 )
579                 this->process = filter_process;
580         return this;
581 }