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