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