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_category( CAT_INPUT );
44 set_subcategory( SUBCAT_INPUT_ACODEC );
45 set_callbacks( DecoderOpen, DecoderClose );
47 /* audio encoder submodule */
49 set_description( _("Raw audio encoder") );
50 set_capability( "encoder", 150 );
51 set_callbacks( EncoderOpen, EncoderClose );
54 /*****************************************************************************
56 *****************************************************************************/
57 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
58 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
62 int16_t *p_logtos16; /* used with m/alaw to int16_t */
64 audio_date_t end_date;
67 static int pi_channels_maps[] =
71 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
72 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
73 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
74 | AOUT_CHAN_REARRIGHT,
75 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
76 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
77 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
78 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
79 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
80 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
81 | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT,
82 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
83 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
84 | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE
87 static int16_t ulawtos16[256] =
89 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
90 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
91 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
92 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
93 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
94 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
95 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
96 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
97 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
98 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
99 -876, -844, -812, -780, -748, -716, -684, -652,
100 -620, -588, -556, -524, -492, -460, -428, -396,
101 -372, -356, -340, -324, -308, -292, -276, -260,
102 -244, -228, -212, -196, -180, -164, -148, -132,
103 -120, -112, -104, -96, -88, -80, -72, -64,
104 -56, -48, -40, -32, -24, -16, -8, 0,
105 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
106 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
107 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
108 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
109 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
110 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
111 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
112 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
113 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
114 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
115 876, 844, 812, 780, 748, 716, 684, 652,
116 620, 588, 556, 524, 492, 460, 428, 396,
117 372, 356, 340, 324, 308, 292, 276, 260,
118 244, 228, 212, 196, 180, 164, 148, 132,
119 120, 112, 104, 96, 88, 80, 72, 64,
120 56, 48, 40, 32, 24, 16, 8, 0
123 static int16_t alawtos16[256] =
125 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
126 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
127 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
128 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
129 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
130 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
131 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
132 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
133 -344, -328, -376, -360, -280, -264, -312, -296,
134 -472, -456, -504, -488, -408, -392, -440, -424,
135 -88, -72, -120, -104, -24, -8, -56, -40,
136 -216, -200, -248, -232, -152, -136, -184, -168,
137 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
138 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
139 -688, -656, -752, -720, -560, -528, -624, -592,
140 -944, -912, -1008, -976, -816, -784, -880, -848,
141 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
142 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
143 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
144 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
145 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
146 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
147 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
148 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
149 344, 328, 376, 360, 280, 264, 312, 296,
150 472, 456, 504, 488, 408, 392, 440, 424,
151 88, 72, 120, 104, 24, 8, 56, 40,
152 216, 200, 248, 232, 152, 136, 184, 168,
153 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
154 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
155 688, 656, 752, 720, 560, 528, 624, 592,
156 944, 912, 1008, 976, 816, 784, 880, 848
159 /*****************************************************************************
160 * DecoderOpen: probe the decoder and return score
161 *****************************************************************************/
162 static int DecoderOpen( vlc_object_t *p_this )
164 decoder_t *p_dec = (decoder_t*)p_this;
165 decoder_sys_t *p_sys;
167 switch( p_dec->fmt_in.i_codec )
169 /* from wav/avi/asf file */
170 case VLC_FOURCC('a','r','a','w'):
171 case VLC_FOURCC('a','f','l','t'):
172 /* _signed_ big endian samples (mov)*/
173 case VLC_FOURCC('t','w','o','s'):
174 /* _signed_ little endian samples (mov)*/
175 case VLC_FOURCC('s','o','w','t'):
177 case VLC_FOURCC('a','l','a','w'):
178 case VLC_FOURCC('u','l','a','w'):
179 case VLC_FOURCC('m','l','a','w'):
181 case VLC_FOURCC('f','l','6','4'):
182 case VLC_FOURCC('f','l','3','2'):
183 case VLC_FOURCC('s','3','2','l'):
184 case VLC_FOURCC('s','3','2','b'):
185 case VLC_FOURCC('s','2','4','l'):
186 case VLC_FOURCC('s','2','4','b'):
187 case VLC_FOURCC('s','1','6','l'):
188 case VLC_FOURCC('s','1','6','b'):
189 case VLC_FOURCC('s','8',' ',' '):
190 case VLC_FOURCC('u','8',' ',' '):
197 if( p_dec->fmt_in.audio.i_channels <= 0 ||
198 p_dec->fmt_in.audio.i_channels > 8 )
200 msg_Err( p_dec, "bad channels count (1-8)" );
204 if( p_dec->fmt_in.audio.i_rate <= 0 )
206 msg_Err( p_dec, "bad samplerate" );
210 /* Allocate the memory needed to store the decoder's structure */
211 if( ( p_dec->p_sys = p_sys =
212 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
214 msg_Err( p_dec, "out of memory" );
218 p_sys->p_logtos16 = NULL;
220 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
221 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
222 p_dec->fmt_in.audio.i_bitspersample );
224 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '6', '4' ) )
226 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
227 p_dec->fmt_in.audio.i_bitspersample = 64;
229 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', '3', '2' ) )
231 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
232 p_dec->fmt_in.audio.i_bitspersample = 32;
234 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'l' ) ||
235 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '3', '2', 'b' ) )
237 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
238 p_dec->fmt_in.audio.i_bitspersample = 32;
240 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'l' ) ||
241 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '2', '4', 'b' ) )
243 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
244 p_dec->fmt_in.audio.i_bitspersample = 24;
246 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) ||
247 p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'b' ) )
249 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
250 p_dec->fmt_in.audio.i_bitspersample = 16;
252 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) ||
253 p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
255 p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
256 p_dec->fmt_in.audio.i_bitspersample = 8;
258 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'f', 'l', 't' ) )
260 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
263 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
266 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
269 msg_Err( p_dec, "bad parameters(bits/sample)" );
273 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
275 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
278 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
281 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
284 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
287 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
290 msg_Err( p_dec, "bad parameters(bits/sample)" );
294 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
296 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
299 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
302 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
305 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
308 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
311 msg_Err( p_dec, "bad parameters(bits/sample)" );
315 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
317 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
320 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
323 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
326 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
329 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
332 msg_Err( p_dec, "bad parameters(bits/sample)" );
336 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
338 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
339 p_sys->p_logtos16 = alawtos16;
340 p_dec->fmt_in.audio.i_bitspersample = 8;
342 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
343 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
345 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
346 p_sys->p_logtos16 = ulawtos16;
347 p_dec->fmt_in.audio.i_bitspersample = 8;
350 /* Set output properties */
351 p_dec->fmt_out.i_cat = AUDIO_ES;
352 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
353 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
354 p_dec->fmt_out.audio.i_bitspersample = p_dec->fmt_in.audio.i_bitspersample;
355 p_dec->fmt_out.audio.i_physical_channels =
356 p_dec->fmt_out.audio.i_original_channels =
357 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
358 if( p_dec->fmt_in.audio.i_physical_channels )
359 p_dec->fmt_out.audio.i_physical_channels =
360 p_dec->fmt_in.audio.i_physical_channels;
361 if( p_dec->fmt_in.audio.i_original_channels )
362 p_dec->fmt_out.audio.i_original_channels =
363 p_dec->fmt_in.audio.i_original_channels;
365 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) ||
366 p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
367 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
369 p_dec->fmt_out.audio.i_bitspersample = 16;
372 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
373 aout_DateSet( &p_sys->end_date, 0 );
375 p_dec->pf_decode_audio = DecodeBlock;
380 /****************************************************************************
381 * DecodeBlock: the whole thing
382 ****************************************************************************
383 * This function must be fed with whole samples (see nBlockAlign).
384 ****************************************************************************/
385 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
387 decoder_sys_t *p_sys = p_dec->p_sys;
389 aout_buffer_t *p_out;
392 if( !pp_block || !*pp_block ) return NULL;
396 if( p_block->i_pts != 0 &&
397 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
399 aout_DateSet( &p_sys->end_date, p_block->i_pts );
401 else if( !aout_DateGet( &p_sys->end_date ) )
403 /* We've just started the stream, wait for the first PTS. */
404 block_Release( p_block );
408 /* Don't re-use the same pts twice */
411 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
412 p_dec->fmt_in.audio.i_channels;
416 block_Release( p_block );
420 /* Create chunks of max 1024 samples */
421 i_samples = __MIN( i_samples, 1024 );
423 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
426 block_Release( p_block );
430 p_out->start_date = aout_DateGet( &p_sys->end_date );
431 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
433 if( p_sys->p_logtos16 )
435 int16_t *s = (int16_t*)p_out->p_buffer;
438 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
440 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
446 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
447 p_block->p_buffer += p_out->i_nb_bytes;
448 p_block->i_buffer -= p_out->i_nb_bytes;
454 /*****************************************************************************
455 * DecoderClose: decoder destruction
456 *****************************************************************************/
457 static void DecoderClose( vlc_object_t *p_this )
459 decoder_t *p_dec = (decoder_t *)p_this;
461 free( p_dec->p_sys );
464 /*****************************************************************************
466 *****************************************************************************/
467 static int EncoderOpen( vlc_object_t *p_this )
469 encoder_t *p_enc = (encoder_t *)p_this;
471 if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','8',' ',' ') ||
472 p_enc->fmt_out.i_codec == VLC_FOURCC('s','8',' ',' ') )
474 p_enc->fmt_out.audio.i_bitspersample = 8;
476 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','l') ||
477 p_enc->fmt_out.i_codec == VLC_FOURCC('u','1','6','b') ||
478 p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','l') ||
479 p_enc->fmt_out.i_codec == VLC_FOURCC('s','1','6','b') )
481 p_enc->fmt_out.audio.i_bitspersample = 16;
483 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','l') ||
484 p_enc->fmt_out.i_codec == VLC_FOURCC('u','2','4','b') ||
485 p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','l') ||
486 p_enc->fmt_out.i_codec == VLC_FOURCC('s','2','4','b') )
488 p_enc->fmt_out.audio.i_bitspersample = 24;
490 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','l') ||
491 p_enc->fmt_out.i_codec == VLC_FOURCC('u','3','2','b') ||
492 p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','l') ||
493 p_enc->fmt_out.i_codec == VLC_FOURCC('s','3','2','b') ||
494 p_enc->fmt_out.i_codec == VLC_FOURCC('f','i','3','2') ||
495 p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','3','2') )
497 p_enc->fmt_out.audio.i_bitspersample = 32;
499 else if( p_enc->fmt_out.i_codec == VLC_FOURCC('f','l','6','4') )
501 p_enc->fmt_out.audio.i_bitspersample = 64;
509 p_enc->pf_encode_audio = EncoderEncode;
510 p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
515 /*****************************************************************************
517 *****************************************************************************/
518 static void EncoderClose ( vlc_object_t *p_this )
523 /*****************************************************************************
525 *****************************************************************************/
526 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
528 block_t *p_block = NULL;
530 if( !p_aout_buf || !p_aout_buf->i_nb_bytes ) return NULL;
532 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
534 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
535 p_aout_buf->i_nb_bytes );
540 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
541 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
542 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;