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