1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.28 2004/01/25 20:40:59 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[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'):
167 case VLC_FOURCC('m','l','a','w'):
174 /* Allocate the memory needed to store the decoder's structure */
175 if( ( p_dec->p_sys = p_sys =
176 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
178 msg_Err( p_dec, "out of memory" );
182 if( p_dec->fmt_in.audio.i_channels <= 0 ||
183 p_dec->fmt_in.audio.i_channels > 5 )
185 msg_Err( p_dec, "bad channels count(1-5)" );
189 if( p_dec->fmt_in.audio.i_rate <= 0 )
191 msg_Err( p_dec, "bad samplerate" );
195 p_sys->p_logtos16 = NULL;
197 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
198 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
199 p_dec->fmt_in.audio.i_bitspersample );
201 if( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
203 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
206 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
209 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
212 msg_Err( p_dec, "bad parameters(bits/sample)" );
218 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
220 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
223 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
226 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
229 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
232 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
235 msg_Err( p_dec, "bad parameters(bits/sample)" );
239 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
241 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
244 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
247 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
250 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
253 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
256 msg_Err( p_dec, "bad parameters(bits/sample)" );
260 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
262 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
265 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
268 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
271 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
274 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
277 msg_Err( p_dec, "bad parameters(bits/sample)" );
281 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
283 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
284 p_sys->p_logtos16 = alawtos16;
285 p_dec->fmt_in.audio.i_bitspersample = 8;
287 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
288 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
290 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
291 p_sys->p_logtos16 = ulawtos16;
292 p_dec->fmt_in.audio.i_bitspersample = 8;
296 /* Set output properties */
297 p_dec->fmt_out.i_cat = AUDIO_ES;
298 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
299 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
300 p_dec->fmt_out.audio.i_physical_channels =
301 p_dec->fmt_out.audio.i_original_channels =
302 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
304 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
305 aout_DateSet( &p_sys->end_date, 0 );
307 p_dec->pf_decode_audio = DecodeBlock;
312 /****************************************************************************
313 * DecodeBlock: the whole thing
314 ****************************************************************************
315 * This function must be fed with whole samples (see nBlockAlign).
316 ****************************************************************************/
317 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
319 decoder_sys_t *p_sys = p_dec->p_sys;
323 if( !pp_block || !*pp_block ) return NULL;
327 if( p_block->i_pts != 0 &&
328 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
330 aout_DateSet( &p_sys->end_date, p_block->i_pts );
332 else if( !aout_DateGet( &p_sys->end_date ) )
334 /* We've just started the stream, wait for the first PTS. */
335 block_Release( p_block );
339 /* Don't re-use the same pts twice */
342 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
343 p_dec->fmt_in.audio.i_channels;
346 /* Create chunks of max 1024 samples */
349 aout_buffer_t *p_out;
350 i_samples = __MIN( i_samples, 1024 );
352 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
355 block_Release( p_block );
359 p_out->start_date = aout_DateGet( &p_sys->end_date );
360 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
362 if( p_sys->p_logtos16 )
364 int16_t *s = (int16_t*)p_out->p_buffer;
367 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
369 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
375 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
376 p_block->p_buffer += p_out->i_nb_bytes;
377 p_block->i_buffer -= p_out->i_nb_bytes;
383 block_Release( p_block );
387 /*****************************************************************************
388 * DecoderClose: decoder destruction
389 *****************************************************************************/
390 static void DecoderClose( vlc_object_t *p_this )
392 decoder_t *p_dec = (decoder_t *)p_this;
394 free( p_dec->p_sys );
397 /*****************************************************************************
399 *****************************************************************************/
400 static int EncoderOpen( vlc_object_t *p_this )
402 encoder_t *p_enc = (encoder_t *)p_this;
404 if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
405 p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
407 msg_Warn( p_enc, "unhandled input format" );
411 switch( p_enc->fmt_out.i_codec )
413 case VLC_FOURCC( 's', '1', '6', 'b' ):
414 case VLC_FOURCC( 's', '1', '6', 'l' ):
415 case VLC_FOURCC( 'u', '8', ' ', ' ' ):
416 case VLC_FOURCC( 's', '8', ' ', ' ' ):
418 -> could be easyly done with table look up
419 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
420 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
428 p_enc->pf_encode_audio = EncoderEncode;
433 /*****************************************************************************
435 *****************************************************************************/
436 static void EncoderClose ( vlc_object_t *p_this )
441 /*****************************************************************************
443 *****************************************************************************/
444 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
446 block_t *p_block = NULL;
449 if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
451 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
453 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
454 p_aout_buf->i_nb_bytes );
457 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
459 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
461 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
462 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
464 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
469 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
471 *p_dst++ = *p_src + 128; p_src += 2;
475 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
477 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
479 int8_t *p_dst = (int8_t*)p_block->p_buffer;
480 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
482 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
487 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
489 *p_dst++ = *p_src; p_src += 2;
495 /* endian swapping */
496 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
498 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
499 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
501 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
514 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
515 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
516 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;