]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* modules/demux/wav.c: started support for WAVEFORMATEXTENSIBLE (aka multichannel).
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2003 VideoLAN
5  * $Id: araw.c,v 1.29 2004/02/14 17:03:32 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/decoder.h>
29
30 /*****************************************************************************
31  * Module descriptor
32  *****************************************************************************/
33 static int  DecoderOpen ( vlc_object_t * );
34 static void DecoderClose( vlc_object_t * );
35
36 static int  EncoderOpen ( vlc_object_t * );
37 static void EncoderClose( vlc_object_t * );
38
39 vlc_module_begin();
40     /* audio decoder module */
41     set_description( _("Raw/Log Audio decoder") );
42     set_capability( "decoder", 100 );
43     set_callbacks( DecoderOpen, DecoderClose );
44
45     /* audio encoder submodule */
46     add_submodule();
47     set_description( _("Raw audio encoder") );
48     set_capability( "encoder", 10 );
49     set_callbacks( EncoderOpen, EncoderClose );
50 vlc_module_end();
51
52 /*****************************************************************************
53  * Local prototypes
54  *****************************************************************************/
55 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
56 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
57
58 struct decoder_sys_t
59 {
60     int16_t *p_logtos16;  /* used with m/alaw to int16_t */
61
62     audio_date_t end_date;
63 };
64
65 static int pi_channels_maps[7] =
66 {
67     0,
68     AOUT_CHAN_CENTER,
69     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
70     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
71     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
72      | AOUT_CHAN_REARRIGHT,
73     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
74      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
75     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
76      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
77 };
78
79 static int16_t ulawtos16[256] =
80 {
81     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
82     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
83     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
84     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
85      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
86      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
87      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
88      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
89      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
90      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
91       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
92       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
93       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
94       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
95       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
96        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
97      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
98      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
99      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
100      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
101       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
102       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
103       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
104       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
105       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
106       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
107        876,    844,    812,    780,    748,    716,    684,    652,
108        620,    588,    556,    524,    492,    460,    428,    396,
109        372,    356,    340,    324,    308,    292,    276,    260,
110        244,    228,    212,    196,    180,    164,    148,    132,
111        120,    112,    104,     96,     88,     80,     72,     64,
112         56,     48,     40,     32,     24,     16,      8,      0
113 };
114
115 static int16_t alawtos16[256] =
116 {
117      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
118      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
119      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
120      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
121     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
122     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
123     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
124     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
125       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
126       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
127        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
128       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
129      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
130      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
131       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
132       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
133       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
134       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
135       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
136       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
137      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
138      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
139      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
140      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
141        344,    328,    376,    360,    280,    264,    312,    296,
142        472,    456,    504,    488,    408,    392,    440,    424,
143         88,     72,    120,    104,     24,      8,     56,     40,
144        216,    200,    248,    232,    152,    136,    184,    168,
145       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
146       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
147        688,    656,    752,    720,    560,    528,    624,    592,
148        944,    912,   1008,    976,    816,    784,    880,    848
149 };
150
151 /*****************************************************************************
152  * DecoderOpen: probe the decoder and return score
153  *****************************************************************************/
154 static int DecoderOpen( vlc_object_t *p_this )
155 {
156     decoder_t *p_dec = (decoder_t*)p_this;
157     decoder_sys_t *p_sys;
158
159     switch( p_dec->fmt_in.i_codec )
160     {
161     /* from wav/avi/asf file */
162     case VLC_FOURCC('a','r','a','w'):
163     case VLC_FOURCC('f','l','3','2'):
164     /* _signed_ big endian samples (mov)*/
165     case VLC_FOURCC('t','w','o','s'):
166     /* _signed_ little endian samples (mov)*/
167     case VLC_FOURCC('s','o','w','t'):
168
169     case VLC_FOURCC('a','l','a','w'):
170     case VLC_FOURCC('u','l','a','w'):
171     case VLC_FOURCC('m','l','a','w'):
172         break;
173
174     default:
175         return VLC_EGENERIC;
176     }
177
178     /* Allocate the memory needed to store the decoder's structure */
179     if( ( p_dec->p_sys = p_sys =
180           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
181     {
182         msg_Err( p_dec, "out of memory" );
183         return VLC_EGENERIC;
184     }
185
186     if( p_dec->fmt_in.audio.i_channels <= 0 ||
187         p_dec->fmt_in.audio.i_channels > 6 )
188     {
189         msg_Err( p_dec, "bad channels count(1-6)" );
190         return VLC_EGENERIC;
191     }
192
193     if( p_dec->fmt_in.audio.i_rate <= 0 )
194     {
195         msg_Err( p_dec, "bad samplerate" );
196         return VLC_EGENERIC;
197     }
198
199     p_sys->p_logtos16 = NULL;
200
201     msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
202              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
203              p_dec->fmt_in.audio.i_bitspersample );
204
205     if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '3', '2' ) )
206     {
207         switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
208         {
209         case 4:
210             p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
211             break;
212         default:
213             msg_Err( p_dec, "bad parameters(bits/sample)" );
214             return VLC_EGENERIC;
215         }
216     }
217     else
218     {
219         if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
220         {
221             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
222             {
223             case 1:
224                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
225                 break;
226             case 2:
227                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
228                 break;
229             case 3:
230                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
231                 break;
232             case 4:
233                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
234                 break;
235             default:
236                 msg_Err( p_dec, "bad parameters(bits/sample)" );
237                 return VLC_EGENERIC;
238             }
239         }
240         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
241         {
242             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
243             {
244             case 1:
245                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
246                 break;
247             case 2:
248                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
249                 break;
250             case 3:
251                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
252                 break;
253             case 4:
254                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
255                 break;
256             default:
257                 msg_Err( p_dec, "bad parameters(bits/sample)" );
258                 return VLC_EGENERIC;
259             }
260         }
261         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
262         {
263             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
264             {
265             case 1:
266                 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
267                 break;
268             case 2:
269                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
270                 break;
271             case 3:
272                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
273                 break;
274             case 4:
275                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
276                 break;
277             default:
278                 msg_Err( p_dec, "bad parameters(bits/sample)" );
279                 return VLC_EGENERIC;
280             }
281         }
282         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
283         {
284             p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
285             p_sys->p_logtos16  = alawtos16;
286             p_dec->fmt_in.audio.i_bitspersample = 8;
287         }
288         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
289                  p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
290         {
291             p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
292             p_sys->p_logtos16  = ulawtos16;
293             p_dec->fmt_in.audio.i_bitspersample = 8;
294         }
295     }
296
297     /* Set output properties */
298     p_dec->fmt_out.i_cat = AUDIO_ES;
299     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
300     p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
301     p_dec->fmt_out.audio.i_physical_channels =
302         p_dec->fmt_out.audio.i_original_channels =
303             pi_channels_maps[p_dec->fmt_in.audio.i_channels];
304
305     aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
306     aout_DateSet( &p_sys->end_date, 0 );
307
308     p_dec->pf_decode_audio = DecodeBlock;
309
310     return VLC_SUCCESS;
311 }
312
313 /****************************************************************************
314  * DecodeBlock: the whole thing
315  ****************************************************************************
316  * This function must be fed with whole samples (see nBlockAlign).
317  ****************************************************************************/
318 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
319 {
320     decoder_sys_t *p_sys = p_dec->p_sys;
321     block_t *p_block;
322     int i_samples;
323
324     if( !pp_block || !*pp_block ) return NULL;
325
326     p_block = *pp_block;
327
328     if( p_block->i_pts != 0 &&
329         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
330     {
331         aout_DateSet( &p_sys->end_date, p_block->i_pts );
332     }
333     else if( !aout_DateGet( &p_sys->end_date ) )
334     {
335         /* We've just started the stream, wait for the first PTS. */
336         block_Release( p_block );
337         return NULL;
338     }
339
340     /* Don't re-use the same pts twice */
341     p_block->i_pts = 0;
342
343     i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
344         p_dec->fmt_in.audio.i_channels;
345
346
347     /* Create chunks of max 1024 samples */
348     if( i_samples > 0 )
349     {
350         aout_buffer_t *p_out;
351         i_samples = __MIN( i_samples, 1024 );
352
353         p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
354         if( p_out == NULL )
355         {
356             block_Release( p_block );
357             return NULL;
358         }
359
360         p_out->start_date = aout_DateGet( &p_sys->end_date );
361         p_out->end_date   = aout_DateIncrement( &p_sys->end_date, i_samples );
362
363         if( p_sys->p_logtos16 )
364         {
365             int16_t *s = (int16_t*)p_out->p_buffer;
366             unsigned int i;
367
368             for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
369             {
370                 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
371                 p_block->i_buffer--;
372             }
373         }
374         else
375         {
376             memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
377             p_block->p_buffer += p_out->i_nb_bytes;
378             p_block->i_buffer -= p_out->i_nb_bytes;
379         }
380
381         return p_out;
382     }
383
384     block_Release( p_block );
385     return NULL;
386 }
387
388 /*****************************************************************************
389  * DecoderClose: decoder destruction
390  *****************************************************************************/
391 static void DecoderClose( vlc_object_t *p_this )
392 {
393     decoder_t *p_dec = (decoder_t *)p_this;
394
395     free( p_dec->p_sys );
396 }
397
398 /*****************************************************************************
399  * EncoderOpen:
400  *****************************************************************************/
401 static int EncoderOpen( vlc_object_t *p_this )
402 {
403     encoder_t *p_enc = (encoder_t *)p_this;
404
405     if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
406         p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
407     {
408         msg_Warn( p_enc, "unhandled input format" );
409         return VLC_EGENERIC;
410     }
411
412     switch( p_enc->fmt_out.i_codec )
413     {
414         case VLC_FOURCC( 's', '1', '6', 'b' ):
415         case VLC_FOURCC( 's', '1', '6', 'l' ):
416         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
417         case VLC_FOURCC( 's', '8', ' ', ' ' ):
418 #if 0
419         -> could be easyly done with table look up
420         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
421         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
422 #endif
423             break;
424         default:
425             return VLC_EGENERIC;
426     }
427
428     p_enc->p_sys = NULL;
429     p_enc->pf_encode_audio = EncoderEncode;
430
431     return VLC_SUCCESS;
432 }
433
434 /*****************************************************************************
435  * EncoderClose:
436  *****************************************************************************/
437 static void EncoderClose ( vlc_object_t *p_this )
438 {
439     return;
440 }
441
442 /*****************************************************************************
443  * EncoderEncode:
444  *****************************************************************************/
445 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
446 {
447     block_t *p_block = NULL;
448     unsigned int i;
449
450     if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
451     {
452         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
453         {
454             memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
455                     p_aout_buf->i_nb_bytes );
456         }
457     }
458     else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
459     {
460         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
461         {
462             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
463             int8_t  *p_src = (int8_t*) p_aout_buf->p_buffer;
464
465             if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
466             {
467                 p_src++;
468             }
469
470             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
471             {
472                 *p_dst++ = *p_src + 128; p_src += 2;
473             }
474         }
475     }
476     else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
477     {
478         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
479         {
480             int8_t *p_dst = (int8_t*)p_block->p_buffer;
481             int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
482
483             if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
484             {
485                 p_src++;
486             }
487
488             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
489             {
490                 *p_dst++ = *p_src; p_src += 2;
491             }
492         }
493     }
494     else
495     {
496         /* endian swapping */
497         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
498         {
499             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
500             uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
501
502             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
503             {
504                 p_dst[0] = p_src[1];
505                 p_dst[1] = p_src[0];
506
507                 p_dst += 2;
508                 p_src += 2;
509             }
510         }
511     }
512
513     if( p_block )
514     {
515         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
516         p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
517             (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;
518     }
519
520     return p_block;
521 }