]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* modules/access/cdda.c, modules/access/vcd/*: New CD digital audio module (by me...
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: araw.c,v 1.15 2003/05/17 20:30:31 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/aout.h>
29 #include <vlc/decoder.h>
30 #include <vlc/input.h>
31
32 #include <stdlib.h>                                      /* malloc(), free() */
33 #include <string.h>                                              /* strdup() */
34 #include "codecs.h"
35 /*****************************************************************************
36  * Local prototypes
37  *****************************************************************************/
38
39 typedef struct adec_thread_s
40 {
41     WAVEFORMATEX    *p_wf;
42
43     /* Input properties */
44     decoder_fifo_t *p_fifo;
45     int16_t        *p_logtos16;  // used with m/alaw to s16
46
47     /* Output properties */
48     aout_instance_t *   p_aout;       /* opaque */
49     aout_input_t *      p_aout_input; /* opaque */
50     audio_sample_format_t output_format;
51
52     audio_date_t        date;
53     mtime_t             pts;
54
55 } adec_thread_t;
56
57 static int  OpenDecoder    ( vlc_object_t * );
58
59 static int  RunDecoder     ( decoder_fifo_t * );
60 static int  InitThread     ( adec_thread_t * );
61 static void DecodeThread   ( adec_thread_t * );
62 static void EndThread      ( adec_thread_t * );
63
64 /*****************************************************************************
65  * Module descriptor
66  *****************************************************************************/
67
68 vlc_module_begin();
69     set_description( _("Pseudo Raw/Log Audio decoder") );
70     set_capability( "decoder", 50 );
71     set_callbacks( OpenDecoder, NULL );
72 vlc_module_end();
73
74
75 /*****************************************************************************
76  * OpenDecoder: probe the decoder and return score
77  *****************************************************************************
78  * Tries to launch a decoder and return score so that the interface is able
79  * to choose.
80  *****************************************************************************/
81 static int OpenDecoder( vlc_object_t *p_this )
82 {
83     decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
84
85     switch( p_fifo->i_fourcc )
86     {
87         case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
88         case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
89         case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
90
91         case VLC_FOURCC('a','l','a','w'):
92         case VLC_FOURCC('u','l','a','w'):
93             p_fifo->pf_run = RunDecoder;
94             return VLC_SUCCESS;
95
96         default:
97             return VLC_EGENERIC;
98     }
99
100 }
101
102 static int pi_channels_maps[6] =
103 {
104     0,
105     AOUT_CHAN_CENTER,
106     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
107     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
108     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
109     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
110      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
111 };
112
113 static int16_t ulawtos16[256] =
114 {
115     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
116     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
117     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
118     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
119      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
120      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
121      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
122      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
123      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
124      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
125       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
126       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
127       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
128       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
129       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
130        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
131      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
132      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
133      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
134      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
135       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
136       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
137       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
138       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
139       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
140       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
141        876,    844,    812,    780,    748,    716,    684,    652,
142        620,    588,    556,    524,    492,    460,    428,    396,
143        372,    356,    340,    324,    308,    292,    276,    260,
144        244,    228,    212,    196,    180,    164,    148,    132,
145        120,    112,    104,     96,     88,     80,     72,     64,
146         56,     48,     40,     32,     24,     16,      8,      0
147 };
148
149 static int16_t alawtos16[256] =
150 {
151      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
152      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
153      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
154      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
155     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
156     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
157     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
158     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
159       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
160       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
161        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
162       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
163      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
164      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
165       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
166       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
167       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
168       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
169       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
170       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
171      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
172      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
173      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
174      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
175        344,    328,    376,    360,    280,    264,    312,    296,
176        472,    456,    504,    488,    408,    392,    440,    424,
177         88,     72,    120,    104,     24,      8,     56,     40,
178        216,    200,    248,    232,    152,    136,    184,    168,
179       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
180       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
181        688,    656,    752,    720,    560,    528,    624,    592,
182        944,    912,   1008,    976,    816,    784,    880,    848
183 };
184
185 /*****************************************************************************
186  * RunDecoder: this function is called just after the thread is created
187  *****************************************************************************/
188 static int RunDecoder( decoder_fifo_t *p_fifo )
189 {
190     adec_thread_t *p_adec;
191     int b_error;
192
193     if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
194     {
195         msg_Err( p_fifo, "out of memory" );
196         DecoderError( p_fifo );
197         return( -1 );
198     }
199     memset( p_adec, 0, sizeof( adec_thread_t ) );
200
201     p_adec->p_fifo = p_fifo;
202
203     if( InitThread( p_adec ) != 0 )
204     {
205         DecoderError( p_fifo );
206         return( -1 );
207     }
208
209     while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
210     {
211         DecodeThread( p_adec );
212     }
213
214
215     if( ( b_error = p_adec->p_fifo->b_error ) )
216     {
217         DecoderError( p_adec->p_fifo );
218     }
219
220     EndThread( p_adec );
221     if( b_error )
222     {
223         return( -1 );
224     }
225
226     return( 0 );
227 }
228
229
230 #define FREE( p ) if( p ) free( p ); p = NULL
231 #define GetWLE( p ) \
232     ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
233
234 #define GetDWLE( p ) \
235     (  *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
236         ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
237
238
239 /*****************************************************************************
240  * InitThread: initialize data before entering main loop
241  *****************************************************************************/
242 static int InitThread( adec_thread_t * p_adec )
243 {
244     if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
245         == NULL )
246     {
247         msg_Err( p_adec->p_fifo, "unknown raw format" );
248         return( -1 );
249     }
250
251     /* fixing some values */
252     if( ( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_PCM ||
253           p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )&&
254         !p_adec->p_wf->nBlockAlign )
255     {
256         p_adec->p_wf->nBlockAlign =
257             p_adec->p_wf->nChannels *
258                 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
259     }
260
261     msg_Dbg( p_adec->p_fifo,
262              "raw format: samplerate:%dHz channels:%d bits/sample:%d "
263              "blockalign:%d",
264              p_adec->p_wf->nSamplesPerSec,
265              p_adec->p_wf->nChannels,
266              p_adec->p_wf->wBitsPerSample,
267              p_adec->p_wf->nBlockAlign );
268
269     /* Initialize the thread properties */
270     p_adec->p_logtos16 = NULL;
271     if( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )
272     {
273         switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
274         {
275             case( 4 ):
276                 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
277                 break;
278             case( 8 ):
279                 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
280                 break;
281             default:
282                 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
283                 return( -1 );
284         }
285     }
286     else
287     {
288         if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
289         {
290             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
291             {
292                 case( 1 ):
293                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
294                     break;
295                 case( 2 ):
296                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
297                     break;
298                 case( 3 ):
299                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
300                     break;
301                 case( 4 ):
302                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
303                     break;
304                 default:
305                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
306                     return( -1 );
307             }
308         }
309         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
310         {
311             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
312             {
313                 case( 1 ):
314                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
315                     break;
316                 case( 2 ):
317                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
318                     break;
319                 case( 3 ):
320                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
321                     break;
322                 case( 4 ):
323                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
324                     break;
325                 default:
326                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
327                     return( -1 );
328             }
329         }
330         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
331         {
332             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
333             {
334                 case( 1 ):
335                     p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
336                     break;
337                 case( 2 ):
338                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
339                     break;
340                 case( 3 ):
341                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
342                     break;
343                 case( 4 ):
344                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
345                     break;
346                 default:
347                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
348                     return( -1 );
349             }
350         }
351         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
352         {
353             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
354             p_adec->p_logtos16  = alawtos16;
355         }
356         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
357         {
358             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
359             p_adec->p_logtos16  = ulawtos16;
360         }
361     }
362     p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
363
364     if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
365     {
366         msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
367         return( -1 );
368     }
369
370     p_adec->output_format.i_physical_channels =
371             p_adec->output_format.i_original_channels =
372             pi_channels_maps[p_adec->p_wf->nChannels];
373     p_adec->p_aout = NULL;
374     p_adec->p_aout_input = NULL;
375
376     /* **** Create a new audio output **** */
377     aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
378     p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
379                                         &p_adec->p_aout,
380                                         &p_adec->output_format );
381     if( !p_adec->p_aout_input )
382     {
383         msg_Err( p_adec->p_fifo, "cannot create aout" );
384         return( -1 );
385     }
386
387     return( 0 );
388 }
389
390 static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
391 {
392     int i_copy;
393     int i_count;
394
395     data_packet_t   *p_data;
396
397     i_count = 0;
398     p_data = p_pes->p_first;
399     while( p_data != NULL && i_count < i_max )
400     {
401
402         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
403                         i_max - i_count );
404
405         if( i_copy > 0 )
406         {
407             memcpy( p_buf,
408                     p_data->p_payload_start,
409                     i_copy );
410         }
411
412         p_data = p_data->p_next;
413         i_count += i_copy;
414         p_buf   += i_copy;
415     }
416
417     if( i_count < i_max )
418     {
419         memset( p_buf, 0, i_max - i_count );
420     }
421 }
422
423 /*****************************************************************************
424  * DecodeThread: decodes a frame
425  *****************************************************************************/
426 static void DecodeThread( adec_thread_t *p_adec )
427 {
428     aout_buffer_t   *p_aout_buffer;
429     int             i_samples; // per channels
430     int             i_size;
431     uint8_t         *p_data, *p;
432     pes_packet_t    *p_pes;
433
434     /* **** get samples count **** */
435     input_ExtractPES( p_adec->p_fifo, &p_pes );
436     if( !p_pes )
437     {
438         p_adec->p_fifo->b_error = 1;
439         return;
440     }
441     i_size = p_pes->i_pes_size;
442
443     if( p_adec->p_wf->nBlockAlign > 0 )
444     {
445         i_size -= i_size % p_adec->p_wf->nBlockAlign;
446     }
447     if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
448     {
449         input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
450         return;
451     }
452
453     i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
454                 p_adec->p_wf->nChannels;
455
456     p_adec->pts = p_pes->i_pts;
457
458     /* **** Now we can output these samples **** */
459
460     if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
461     {
462         aout_DateSet( &p_adec->date, p_adec->pts );
463     }
464     else if( !aout_DateGet( &p_adec->date ) )
465     {
466         return;
467     }
468
469     /* gather data */
470     p = p_data = malloc( i_size );
471     GetPESData( p_data, i_size, p_pes );
472
473     while( i_samples > 0 )
474     {
475         int i_copy;
476
477         i_copy = __MIN( i_samples, 1024 );
478         p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
479                                            p_adec->p_aout_input,
480                                            i_copy );
481         if( !p_aout_buffer )
482         {
483             msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
484             p_adec->p_fifo->b_error = 1;
485
486             free( p_data );
487             return;
488         }
489
490         p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
491         p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
492                                                       i_copy );
493
494         if( p_adec->p_logtos16 )
495         {
496             int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
497
498             unsigned int     i;
499
500             for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
501             {
502                 *s++ = p_adec->p_logtos16[*p++];
503             }
504         }
505         else
506         {
507             memcpy( p_aout_buffer->p_buffer, p,
508                     p_aout_buffer->i_nb_bytes );
509
510             p += p_aout_buffer->i_nb_bytes;
511         }
512
513         aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
514
515         i_samples -= i_copy;
516     }
517
518     free( p_data );
519     input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
520 }
521
522 /*****************************************************************************
523  * EndThread : faad decoder thread destruction
524  *****************************************************************************/
525 static void EndThread (adec_thread_t *p_adec)
526 {
527     if( p_adec->p_aout_input )
528     {
529         aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
530     }
531
532     msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );
533
534     free( p_adec );
535 }