1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.30 2004/02/23 23:01:05 gbazin Exp $
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", 10 );
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[7] =
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
79 static int16_t ulawtos16[256] =
81 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
82 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
83 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
84 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
85 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
86 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
87 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
88 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
89 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
90 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
91 -876, -844, -812, -780, -748, -716, -684, -652,
92 -620, -588, -556, -524, -492, -460, -428, -396,
93 -372, -356, -340, -324, -308, -292, -276, -260,
94 -244, -228, -212, -196, -180, -164, -148, -132,
95 -120, -112, -104, -96, -88, -80, -72, -64,
96 -56, -48, -40, -32, -24, -16, -8, 0,
97 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
98 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
99 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
100 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
101 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
102 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
103 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
104 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
105 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
106 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
107 876, 844, 812, 780, 748, 716, 684, 652,
108 620, 588, 556, 524, 492, 460, 428, 396,
109 372, 356, 340, 324, 308, 292, 276, 260,
110 244, 228, 212, 196, 180, 164, 148, 132,
111 120, 112, 104, 96, 88, 80, 72, 64,
112 56, 48, 40, 32, 24, 16, 8, 0
115 static int16_t alawtos16[256] =
117 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
118 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
119 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
120 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
121 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
122 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
123 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
124 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
125 -344, -328, -376, -360, -280, -264, -312, -296,
126 -472, -456, -504, -488, -408, -392, -440, -424,
127 -88, -72, -120, -104, -24, -8, -56, -40,
128 -216, -200, -248, -232, -152, -136, -184, -168,
129 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
130 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
131 -688, -656, -752, -720, -560, -528, -624, -592,
132 -944, -912, -1008, -976, -816, -784, -880, -848,
133 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
134 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
135 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
136 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
137 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
138 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
139 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
140 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
141 344, 328, 376, 360, 280, 264, 312, 296,
142 472, 456, 504, 488, 408, 392, 440, 424,
143 88, 72, 120, 104, 24, 8, 56, 40,
144 216, 200, 248, 232, 152, 136, 184, 168,
145 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
146 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
147 688, 656, 752, 720, 560, 528, 624, 592,
148 944, 912, 1008, 976, 816, 784, 880, 848
151 /*****************************************************************************
152 * DecoderOpen: probe the decoder and return score
153 *****************************************************************************/
154 static int DecoderOpen( vlc_object_t *p_this )
156 decoder_t *p_dec = (decoder_t*)p_this;
157 decoder_sys_t *p_sys;
159 switch( p_dec->fmt_in.i_codec )
161 /* from wav/avi/asf file */
162 case VLC_FOURCC('a','r','a','w'):
163 case VLC_FOURCC('a','f','l','t'):
164 /* _signed_ big endian samples (mov)*/
165 case VLC_FOURCC('t','w','o','s'):
166 /* _signed_ little endian samples (mov)*/
167 case VLC_FOURCC('s','o','w','t'):
169 case VLC_FOURCC('a','l','a','w'):
170 case VLC_FOURCC('u','l','a','w'):
171 case VLC_FOURCC('m','l','a','w'):
178 /* Allocate the memory needed to store the decoder's structure */
179 if( ( p_dec->p_sys = p_sys =
180 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
182 msg_Err( p_dec, "out of memory" );
186 if( p_dec->fmt_in.audio.i_channels <= 0 ||
187 p_dec->fmt_in.audio.i_channels > 6 )
189 msg_Err( p_dec, "bad channels count(1-6)" );
193 if( p_dec->fmt_in.audio.i_rate <= 0 )
195 msg_Err( p_dec, "bad samplerate" );
199 p_sys->p_logtos16 = NULL;
201 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
202 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
203 p_dec->fmt_in.audio.i_bitspersample );
205 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'f', 'l', 't' ) )
207 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
210 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
213 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
216 msg_Err( p_dec, "bad parameters(bits/sample)" );
222 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
224 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
227 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
230 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
233 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
236 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
239 msg_Err( p_dec, "bad parameters(bits/sample)" );
243 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
245 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
248 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
251 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
254 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
257 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
260 msg_Err( p_dec, "bad parameters(bits/sample)" );
264 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
266 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
269 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
272 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
275 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
278 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
281 msg_Err( p_dec, "bad parameters(bits/sample)" );
285 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
287 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
288 p_sys->p_logtos16 = alawtos16;
289 p_dec->fmt_in.audio.i_bitspersample = 8;
291 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
292 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
294 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
295 p_sys->p_logtos16 = ulawtos16;
296 p_dec->fmt_in.audio.i_bitspersample = 8;
300 /* Set output properties */
301 p_dec->fmt_out.i_cat = AUDIO_ES;
302 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
303 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
304 p_dec->fmt_out.audio.i_physical_channels =
305 p_dec->fmt_out.audio.i_original_channels =
306 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
308 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
309 aout_DateSet( &p_sys->end_date, 0 );
311 p_dec->pf_decode_audio = DecodeBlock;
316 /****************************************************************************
317 * DecodeBlock: the whole thing
318 ****************************************************************************
319 * This function must be fed with whole samples (see nBlockAlign).
320 ****************************************************************************/
321 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
323 decoder_sys_t *p_sys = p_dec->p_sys;
327 if( !pp_block || !*pp_block ) return NULL;
331 if( p_block->i_pts != 0 &&
332 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
334 aout_DateSet( &p_sys->end_date, p_block->i_pts );
336 else if( !aout_DateGet( &p_sys->end_date ) )
338 /* We've just started the stream, wait for the first PTS. */
339 block_Release( p_block );
343 /* Don't re-use the same pts twice */
346 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
347 p_dec->fmt_in.audio.i_channels;
350 /* Create chunks of max 1024 samples */
353 aout_buffer_t *p_out;
354 i_samples = __MIN( i_samples, 1024 );
356 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
359 block_Release( p_block );
363 p_out->start_date = aout_DateGet( &p_sys->end_date );
364 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
366 if( p_sys->p_logtos16 )
368 int16_t *s = (int16_t*)p_out->p_buffer;
371 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
373 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
379 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
380 p_block->p_buffer += p_out->i_nb_bytes;
381 p_block->i_buffer -= p_out->i_nb_bytes;
387 block_Release( p_block );
391 /*****************************************************************************
392 * DecoderClose: decoder destruction
393 *****************************************************************************/
394 static void DecoderClose( vlc_object_t *p_this )
396 decoder_t *p_dec = (decoder_t *)p_this;
398 free( p_dec->p_sys );
401 /*****************************************************************************
403 *****************************************************************************/
404 static int EncoderOpen( vlc_object_t *p_this )
406 encoder_t *p_enc = (encoder_t *)p_this;
408 if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
409 p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
411 msg_Warn( p_enc, "unhandled input format" );
415 switch( p_enc->fmt_out.i_codec )
417 case VLC_FOURCC( 's', '1', '6', 'b' ):
418 case VLC_FOURCC( 's', '1', '6', 'l' ):
419 case VLC_FOURCC( 'u', '8', ' ', ' ' ):
420 case VLC_FOURCC( 's', '8', ' ', ' ' ):
422 -> could be easyly done with table look up
423 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
424 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
432 p_enc->pf_encode_audio = EncoderEncode;
437 /*****************************************************************************
439 *****************************************************************************/
440 static void EncoderClose ( vlc_object_t *p_this )
445 /*****************************************************************************
447 *****************************************************************************/
448 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
450 block_t *p_block = NULL;
453 if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
455 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
457 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
458 p_aout_buf->i_nb_bytes );
461 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
463 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
465 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
466 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
468 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
473 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
475 *p_dst++ = *p_src + 128; p_src += 2;
479 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
481 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
483 int8_t *p_dst = (int8_t*)p_block->p_buffer;
484 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
486 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
491 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
493 *p_dst++ = *p_src; p_src += 2;
499 /* endian swapping */
500 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
502 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
503 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
505 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
518 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
519 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
520 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;