]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* modules/demux/wav.c: more fixes for multichannel wav files support.
[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.30 2004/02/23 23:01:05 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('a','f','l','t'):
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( 'a', 'f', 'l', 't' ) )
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         case 8:
213             p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
214             break;
215         default:
216             msg_Err( p_dec, "bad parameters(bits/sample)" );
217             return VLC_EGENERIC;
218         }
219     }
220     else
221     {
222         if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
223         {
224             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
225             {
226             case 1:
227                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
228                 break;
229             case 2:
230                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
231                 break;
232             case 3:
233                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
234                 break;
235             case 4:
236                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
237                 break;
238             default:
239                 msg_Err( p_dec, "bad parameters(bits/sample)" );
240                 return VLC_EGENERIC;
241             }
242         }
243         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
244         {
245             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
246             {
247             case 1:
248                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
249                 break;
250             case 2:
251                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
252                 break;
253             case 3:
254                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
255                 break;
256             case 4:
257                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
258                 break;
259             default:
260                 msg_Err( p_dec, "bad parameters(bits/sample)" );
261                 return VLC_EGENERIC;
262             }
263         }
264         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
265         {
266             switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
267             {
268             case 1:
269                 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
270                 break;
271             case 2:
272                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
273                 break;
274             case 3:
275                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
276                 break;
277             case 4:
278                 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
279                 break;
280             default:
281                 msg_Err( p_dec, "bad parameters(bits/sample)" );
282                 return VLC_EGENERIC;
283             }
284         }
285         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
286         {
287             p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
288             p_sys->p_logtos16  = alawtos16;
289             p_dec->fmt_in.audio.i_bitspersample = 8;
290         }
291         else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
292                  p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
293         {
294             p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
295             p_sys->p_logtos16  = ulawtos16;
296             p_dec->fmt_in.audio.i_bitspersample = 8;
297         }
298     }
299
300     /* Set output properties */
301     p_dec->fmt_out.i_cat = AUDIO_ES;
302     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
303     p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
304     p_dec->fmt_out.audio.i_physical_channels =
305         p_dec->fmt_out.audio.i_original_channels =
306             pi_channels_maps[p_dec->fmt_in.audio.i_channels];
307
308     aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
309     aout_DateSet( &p_sys->end_date, 0 );
310
311     p_dec->pf_decode_audio = DecodeBlock;
312
313     return VLC_SUCCESS;
314 }
315
316 /****************************************************************************
317  * DecodeBlock: the whole thing
318  ****************************************************************************
319  * This function must be fed with whole samples (see nBlockAlign).
320  ****************************************************************************/
321 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
322 {
323     decoder_sys_t *p_sys = p_dec->p_sys;
324     block_t *p_block;
325     int i_samples;
326
327     if( !pp_block || !*pp_block ) return NULL;
328
329     p_block = *pp_block;
330
331     if( p_block->i_pts != 0 &&
332         p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
333     {
334         aout_DateSet( &p_sys->end_date, p_block->i_pts );
335     }
336     else if( !aout_DateGet( &p_sys->end_date ) )
337     {
338         /* We've just started the stream, wait for the first PTS. */
339         block_Release( p_block );
340         return NULL;
341     }
342
343     /* Don't re-use the same pts twice */
344     p_block->i_pts = 0;
345
346     i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
347         p_dec->fmt_in.audio.i_channels;
348
349
350     /* Create chunks of max 1024 samples */
351     if( i_samples > 0 )
352     {
353         aout_buffer_t *p_out;
354         i_samples = __MIN( i_samples, 1024 );
355
356         p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
357         if( p_out == NULL )
358         {
359             block_Release( p_block );
360             return NULL;
361         }
362
363         p_out->start_date = aout_DateGet( &p_sys->end_date );
364         p_out->end_date   = aout_DateIncrement( &p_sys->end_date, i_samples );
365
366         if( p_sys->p_logtos16 )
367         {
368             int16_t *s = (int16_t*)p_out->p_buffer;
369             unsigned int i;
370
371             for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
372             {
373                 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
374                 p_block->i_buffer--;
375             }
376         }
377         else
378         {
379             memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
380             p_block->p_buffer += p_out->i_nb_bytes;
381             p_block->i_buffer -= p_out->i_nb_bytes;
382         }
383
384         return p_out;
385     }
386
387     block_Release( p_block );
388     return NULL;
389 }
390
391 /*****************************************************************************
392  * DecoderClose: decoder destruction
393  *****************************************************************************/
394 static void DecoderClose( vlc_object_t *p_this )
395 {
396     decoder_t *p_dec = (decoder_t *)p_this;
397
398     free( p_dec->p_sys );
399 }
400
401 /*****************************************************************************
402  * EncoderOpen:
403  *****************************************************************************/
404 static int EncoderOpen( vlc_object_t *p_this )
405 {
406     encoder_t *p_enc = (encoder_t *)p_this;
407
408     if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
409         p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
410     {
411         msg_Warn( p_enc, "unhandled input format" );
412         return VLC_EGENERIC;
413     }
414
415     switch( p_enc->fmt_out.i_codec )
416     {
417         case VLC_FOURCC( 's', '1', '6', 'b' ):
418         case VLC_FOURCC( 's', '1', '6', 'l' ):
419         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
420         case VLC_FOURCC( 's', '8', ' ', ' ' ):
421 #if 0
422         -> could be easyly done with table look up
423         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
424         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
425 #endif
426             break;
427         default:
428             return VLC_EGENERIC;
429     }
430
431     p_enc->p_sys = NULL;
432     p_enc->pf_encode_audio = EncoderEncode;
433
434     return VLC_SUCCESS;
435 }
436
437 /*****************************************************************************
438  * EncoderClose:
439  *****************************************************************************/
440 static void EncoderClose ( vlc_object_t *p_this )
441 {
442     return;
443 }
444
445 /*****************************************************************************
446  * EncoderEncode:
447  *****************************************************************************/
448 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
449 {
450     block_t *p_block = NULL;
451     unsigned int i;
452
453     if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
454     {
455         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
456         {
457             memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
458                     p_aout_buf->i_nb_bytes );
459         }
460     }
461     else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
462     {
463         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
464         {
465             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
466             int8_t  *p_src = (int8_t*) p_aout_buf->p_buffer;
467
468             if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
469             {
470                 p_src++;
471             }
472
473             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
474             {
475                 *p_dst++ = *p_src + 128; p_src += 2;
476             }
477         }
478     }
479     else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
480     {
481         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
482         {
483             int8_t *p_dst = (int8_t*)p_block->p_buffer;
484             int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
485
486             if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
487             {
488                 p_src++;
489             }
490
491             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
492             {
493                 *p_dst++ = *p_src; p_src += 2;
494             }
495         }
496     }
497     else
498     {
499         /* endian swapping */
500         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
501         {
502             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
503             uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
504
505             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
506             {
507                 p_dst[0] = p_src[1];
508                 p_dst[1] = p_src[0];
509
510                 p_dst += 2;
511                 p_src += 2;
512             }
513         }
514     }
515
516     if( p_block )
517     {
518         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
519         p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
520             (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;
521     }
522
523     return p_block;
524 }