1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
28 #include <vlc/decoder.h>
30 /*****************************************************************************
32 *****************************************************************************/
33 static int DecoderOpen ( vlc_object_t * );
34 static void DecoderClose( vlc_object_t * );
36 static int EncoderOpen ( vlc_object_t * );
37 static void EncoderClose( vlc_object_t * );
40 /* audio decoder module */
41 set_description( _("Raw/Log Audio decoder") );
42 set_capability( "decoder", 100 );
43 set_callbacks( DecoderOpen, DecoderClose );
45 /* audio encoder submodule */
47 set_description( _("Raw audio encoder") );
48 set_capability( "encoder", 150 );
49 set_callbacks( EncoderOpen, EncoderClose );
52 /*****************************************************************************
54 *****************************************************************************/
55 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
56 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
60 int16_t *p_logtos16; /* used with m/alaw to int16_t */
62 audio_date_t end_date;
65 static int pi_channels_maps[] =
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 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
78 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
79 | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT,
80 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
81 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
82 | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE
85 static int16_t ulawtos16[256] =
87 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
88 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
89 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
90 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
91 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
92 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
93 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
94 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
95 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
96 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
97 -876, -844, -812, -780, -748, -716, -684, -652,
98 -620, -588, -556, -524, -492, -460, -428, -396,
99 -372, -356, -340, -324, -308, -292, -276, -260,
100 -244, -228, -212, -196, -180, -164, -148, -132,
101 -120, -112, -104, -96, -88, -80, -72, -64,
102 -56, -48, -40, -32, -24, -16, -8, 0,
103 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
104 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
105 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
106 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
107 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
108 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
109 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
110 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
111 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
112 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
113 876, 844, 812, 780, 748, 716, 684, 652,
114 620, 588, 556, 524, 492, 460, 428, 396,
115 372, 356, 340, 324, 308, 292, 276, 260,
116 244, 228, 212, 196, 180, 164, 148, 132,
117 120, 112, 104, 96, 88, 80, 72, 64,
118 56, 48, 40, 32, 24, 16, 8, 0
121 static int16_t alawtos16[256] =
123 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
124 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
125 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
126 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
127 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
128 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
129 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
130 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
131 -344, -328, -376, -360, -280, -264, -312, -296,
132 -472, -456, -504, -488, -408, -392, -440, -424,
133 -88, -72, -120, -104, -24, -8, -56, -40,
134 -216, -200, -248, -232, -152, -136, -184, -168,
135 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
136 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
137 -688, -656, -752, -720, -560, -528, -624, -592,
138 -944, -912, -1008, -976, -816, -784, -880, -848,
139 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
140 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
141 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
142 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
143 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
144 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
145 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
146 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
147 344, 328, 376, 360, 280, 264, 312, 296,
148 472, 456, 504, 488, 408, 392, 440, 424,
149 88, 72, 120, 104, 24, 8, 56, 40,
150 216, 200, 248, 232, 152, 136, 184, 168,
151 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
152 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
153 688, 656, 752, 720, 560, 528, 624, 592,
154 944, 912, 1008, 976, 816, 784, 880, 848
157 /*****************************************************************************
158 * DecoderOpen: probe the decoder and return score
159 *****************************************************************************/
160 static int DecoderOpen( vlc_object_t *p_this )
162 decoder_t *p_dec = (decoder_t*)p_this;
163 decoder_sys_t *p_sys;
165 switch( p_dec->fmt_in.i_codec )
167 /* from wav/avi/asf file */
168 case VLC_FOURCC('a','r','a','w'):
169 case VLC_FOURCC('a','f','l','t'):
170 /* _signed_ big endian samples (mov)*/
171 case VLC_FOURCC('t','w','o','s'):
172 /* _signed_ little endian samples (mov)*/
173 case VLC_FOURCC('s','o','w','t'):
175 case VLC_FOURCC('a','l','a','w'):
176 case VLC_FOURCC('u','l','a','w'):
177 case VLC_FOURCC('m','l','a','w'):
179 case VLC_FOURCC('f','l','6','4'):
180 case VLC_FOURCC('f','l','3','2'):
181 case VLC_FOURCC('s','3','2','l'):
182 case VLC_FOURCC('s','3','2','b'):
183 case VLC_FOURCC('s','2','4','l'):
184 case VLC_FOURCC('s','2','4','b'):
185 case VLC_FOURCC('s','1','6','l'):
186 case VLC_FOURCC('s','1','6','b'):
187 case VLC_FOURCC('s','8',' ',' '):
188 case VLC_FOURCC('u','8',' ',' '):
195 if( p_dec->fmt_in.audio.i_channels <= 0 ||
196 p_dec->fmt_in.audio.i_channels > 8 )
198 msg_Err( p_dec, "bad channels count (1-8)" );
202 if( p_dec->fmt_in.audio.i_rate <= 0 )
204 msg_Err( p_dec, "bad samplerate" );
208 /* Allocate the memory needed to store the decoder's structure */
209 if( ( p_dec->p_sys = p_sys =
210 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
212 msg_Err( p_dec, "out of memory" );
216 p_sys->p_logtos16 = NULL;
218 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
219 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
220 p_dec->fmt_in.audio.i_bitspersample );
222 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '6', '4' ) )
224 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
225 p_dec->fmt_in.audio.i_bitspersample = 64;
227 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '3', '2' ) )
229 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
230 p_dec->fmt_in.audio.i_bitspersample = 32;
232 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'l' ) ||
233 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'b' ) )
235 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
236 p_dec->fmt_in.audio.i_bitspersample = 32;
238 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'l' ) ||
239 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'b' ) )
241 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
242 p_dec->fmt_in.audio.i_bitspersample = 24;
244 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
245 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
247 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
248 p_dec->fmt_in.audio.i_bitspersample = 16;
250 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
251 p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
253 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
254 p_dec->fmt_in.audio.i_bitspersample = 8;
256 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'f', 'l', 't' ) )
258 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
261 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
264 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
267 msg_Err( p_dec, "bad parameters(bits/sample)" );
271 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
273 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
276 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
279 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
282 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
285 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
288 msg_Err( p_dec, "bad parameters(bits/sample)" );
292 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
294 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
297 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
300 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
303 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
306 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
309 msg_Err( p_dec, "bad parameters(bits/sample)" );
313 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
315 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
318 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
321 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
324 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
327 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
330 msg_Err( p_dec, "bad parameters(bits/sample)" );
334 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
336 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
337 p_sys->p_logtos16 = alawtos16;
338 p_dec->fmt_in.audio.i_bitspersample = 8;
340 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
341 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
343 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
344 p_sys->p_logtos16 = ulawtos16;
345 p_dec->fmt_in.audio.i_bitspersample = 8;
348 /* Set output properties */
349 p_dec->fmt_out.i_cat = AUDIO_ES;
350 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
351 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
352 p_dec->fmt_out.audio.i_bitspersample = p_dec->fmt_in.audio.i_bitspersample;
353 p_dec->fmt_out.audio.i_physical_channels =
354 p_dec->fmt_out.audio.i_original_channels =
355 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
356 if( p_dec->fmt_in.audio.i_physical_channels )
357 p_dec->fmt_out.audio.i_physical_channels =
358 p_dec->fmt_in.audio.i_physical_channels;
359 if( p_dec->fmt_in.audio.i_original_channels )
360 p_dec->fmt_out.audio.i_original_channels =
361 p_dec->fmt_in.audio.i_original_channels;
363 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) ||
364 p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
365 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
367 p_dec->fmt_out.audio.i_bitspersample = 16;
370 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
371 aout_DateSet( &p_sys->end_date, 0 );
373 p_dec->pf_decode_audio = DecodeBlock;
378 /****************************************************************************
379 * DecodeBlock: the whole thing
380 ****************************************************************************
381 * This function must be fed with whole samples (see nBlockAlign).
382 ****************************************************************************/
383 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
385 decoder_sys_t *p_sys = p_dec->p_sys;
387 aout_buffer_t *p_out;
390 if( !pp_block || !*pp_block ) return NULL;
394 if( p_block->i_pts != 0 &&
395 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
397 aout_DateSet( &p_sys->end_date, p_block->i_pts );
399 else if( !aout_DateGet( &p_sys->end_date ) )
401 /* We've just started the stream, wait for the first PTS. */
402 block_Release( p_block );
406 /* Don't re-use the same pts twice */
409 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
410 p_dec->fmt_in.audio.i_channels;
414 block_Release( p_block );
418 /* Create chunks of max 1024 samples */
419 i_samples = __MIN( i_samples, 1024 );
421 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
424 block_Release( p_block );
428 p_out->start_date = aout_DateGet( &p_sys->end_date );
429 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
431 if( p_sys->p_logtos16 )
433 int16_t *s = (int16_t*)p_out->p_buffer;
436 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
438 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
444 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
445 p_block->p_buffer += p_out->i_nb_bytes;
446 p_block->i_buffer -= p_out->i_nb_bytes;
452 /*****************************************************************************
453 * DecoderClose: decoder destruction
454 *****************************************************************************/
455 static void DecoderClose( vlc_object_t *p_this )
457 decoder_t *p_dec = (decoder_t *)p_this;
459 free( p_dec->p_sys );
462 /*****************************************************************************
464 *****************************************************************************/
465 static int EncoderOpen( vlc_object_t *p_this )
467 encoder_t *p_enc = (encoder_t *)p_this;
469 if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','8',' ',' ') ||
470 p_enc->fmt_out.i_codec == VLC_FOURCC('s','8',' ',' ') )
472 p_enc->fmt_out.audio.i_bitspersample = 8;
474 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','l') ||
475 p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','b') ||
476 p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','l') ||
477 p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','b') )
479 p_enc->fmt_out.audio.i_bitspersample = 16;
481 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','l') ||
482 p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','b') ||
483 p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','l') ||
484 p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','b') )
486 p_enc->fmt_out.audio.i_bitspersample = 24;
488 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','l') ||
489 p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','b') ||
490 p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','l') ||
491 p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','b') ||
492 p_enc->fmt_out.i_codec == VLC_FOURCC('f','i','3','2') ||
493 p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','3','2') )
495 p_enc->fmt_out.audio.i_bitspersample = 32;
497 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','6','4') )
499 p_enc->fmt_out.audio.i_bitspersample = 64;
507 p_enc->pf_encode_audio = EncoderEncode;
508 p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
513 /*****************************************************************************
515 *****************************************************************************/
516 static void EncoderClose ( vlc_object_t *p_this )
521 /*****************************************************************************
523 *****************************************************************************/
524 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
526 block_t *p_block = NULL;
528 if( !p_aout_buf || !p_aout_buf->i_nb_bytes ) return NULL;
530 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
532 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
533 p_aout_buf->i_nb_bytes );
538 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
539 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
540 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;