1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.25 2003/11/22 23:39:14 fenrir 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", 50 );
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[6] =
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
76 static int16_t ulawtos16[256] =
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
112 static int16_t alawtos16[256] =
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
148 /*****************************************************************************
149 * DecoderOpen: probe the decoder and return score
150 *****************************************************************************/
151 static int DecoderOpen( vlc_object_t *p_this )
153 decoder_t *p_dec = (decoder_t*)p_this;
154 decoder_sys_t *p_sys;
156 switch( p_dec->fmt_in.i_codec )
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'):
165 case VLC_FOURCC('a','l','a','w'):
166 case VLC_FOURCC('u','l','a','w'):
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 )
177 msg_Err( p_dec, "out of memory" );
181 if( p_dec->fmt_in.audio.i_channels <= 0 ||
182 p_dec->fmt_in.audio.i_channels > 5 )
184 msg_Err( p_dec, "bad channels count(1-5)" );
188 if( p_dec->fmt_in.audio.i_rate <= 0 )
190 msg_Err( p_dec, "bad samplerate" );
194 p_sys->p_logtos16 = NULL;
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 );
200 if( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
202 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
205 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
208 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
211 msg_Err( p_dec, "bad parameters(bits/sample)" );
217 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
219 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
222 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
225 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
228 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
231 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
234 msg_Err( p_dec, "bad parameters(bits/sample)" );
238 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
240 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
243 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
246 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
249 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
252 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
255 msg_Err( p_dec, "bad parameters(bits/sample)" );
259 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
261 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
264 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
267 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
270 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
273 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
276 msg_Err( p_dec, "bad parameters(bits/sample)" );
280 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
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;
286 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
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;
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];
302 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
303 aout_DateSet( &p_sys->end_date, 0 );
305 p_dec->pf_decode_audio = DecodeBlock;
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 )
317 decoder_sys_t *p_sys = p_dec->p_sys;
321 if( !pp_block || !*pp_block ) return NULL;
325 if( p_block->i_pts != 0 &&
326 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
328 aout_DateSet( &p_sys->end_date, p_block->i_pts );
330 else if( !aout_DateGet( &p_sys->end_date ) )
332 /* We've just started the stream, wait for the first PTS. */
333 block_Release( p_block );
337 /* Don't re-use the same pts twice */
340 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
341 p_dec->fmt_in.audio.i_channels;
344 /* Create chunks of max 1024 samples */
347 aout_buffer_t *p_out;
348 i_samples = __MIN( i_samples, 1024 );
350 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
353 block_Release( p_block );
357 p_out->start_date = aout_DateGet( &p_sys->end_date );
358 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
360 if( p_sys->p_logtos16 )
362 int16_t *s = (int16_t*)p_out->p_buffer;
365 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
367 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
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;
381 block_Release( p_block );
385 /*****************************************************************************
386 * DecoderClose: decoder destruction
387 *****************************************************************************/
388 static void DecoderClose( vlc_object_t *p_this )
390 decoder_t *p_dec = (decoder_t *)p_this;
392 free( p_dec->p_sys );
395 /*****************************************************************************
397 *****************************************************************************/
398 static int EncoderOpen( vlc_object_t *p_this )
400 encoder_t *p_enc = (encoder_t *)p_this;
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' ) )
405 msg_Warn( p_enc, "unhandled input format" );
409 switch( p_enc->fmt_out.i_codec )
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', ' ', ' ' ):
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' ):
426 p_enc->pf_encode_audio = EncoderEncode;
431 /*****************************************************************************
433 *****************************************************************************/
434 static void EncoderClose ( vlc_object_t *p_this )
439 /*****************************************************************************
441 *****************************************************************************/
442 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
444 block_t *p_block = NULL;
447 if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
449 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
451 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
452 p_aout_buf->i_nb_bytes );
455 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
457 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
459 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
460 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
462 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
467 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
469 *p_dst++ = *p_src + 128; p_src += 2;
473 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
475 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
477 int8_t *p_dst = (int8_t*)p_block->p_buffer;
478 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
480 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
485 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
487 *p_dst++ = *p_src; p_src += 2;
493 /* endian swapping */
494 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
496 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
497 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
499 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
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;