1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.29 2004/02/14 17:03:32 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('f','l','3','2'):
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( 'f', 'l', '3', '2' ) )
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 msg_Err( p_dec, "bad parameters(bits/sample)" );
219 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 't', 'w', 'o', 's' ) )
221 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
224 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
227 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','b');
230 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','b');
233 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','b');
236 msg_Err( p_dec, "bad parameters(bits/sample)" );
240 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 's', 'o', 'w', 't' ) )
242 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
245 p_dec->fmt_out.i_codec = VLC_FOURCC('s','8',' ',' ');
248 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
251 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
254 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
257 msg_Err( p_dec, "bad parameters(bits/sample)" );
261 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
263 switch( ( p_dec->fmt_in.audio.i_bitspersample + 7 ) / 8 )
266 p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
269 p_dec->fmt_out.i_codec = VLC_FOURCC('s','1','6','l');
272 p_dec->fmt_out.i_codec = VLC_FOURCC('s','2','4','l');
275 p_dec->fmt_out.i_codec = VLC_FOURCC('s','3','2','l');
278 msg_Err( p_dec, "bad parameters(bits/sample)" );
282 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
284 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
285 p_sys->p_logtos16 = alawtos16;
286 p_dec->fmt_in.audio.i_bitspersample = 8;
288 else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'u', 'l', 'a', 'w' ) ||
289 p_dec->fmt_in.i_codec == VLC_FOURCC( 'm', 'l', 'a', 'w' ) )
291 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
292 p_sys->p_logtos16 = ulawtos16;
293 p_dec->fmt_in.audio.i_bitspersample = 8;
297 /* Set output properties */
298 p_dec->fmt_out.i_cat = AUDIO_ES;
299 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
300 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
301 p_dec->fmt_out.audio.i_physical_channels =
302 p_dec->fmt_out.audio.i_original_channels =
303 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
305 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
306 aout_DateSet( &p_sys->end_date, 0 );
308 p_dec->pf_decode_audio = DecodeBlock;
313 /****************************************************************************
314 * DecodeBlock: the whole thing
315 ****************************************************************************
316 * This function must be fed with whole samples (see nBlockAlign).
317 ****************************************************************************/
318 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
320 decoder_sys_t *p_sys = p_dec->p_sys;
324 if( !pp_block || !*pp_block ) return NULL;
328 if( p_block->i_pts != 0 &&
329 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
331 aout_DateSet( &p_sys->end_date, p_block->i_pts );
333 else if( !aout_DateGet( &p_sys->end_date ) )
335 /* We've just started the stream, wait for the first PTS. */
336 block_Release( p_block );
340 /* Don't re-use the same pts twice */
343 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
344 p_dec->fmt_in.audio.i_channels;
347 /* Create chunks of max 1024 samples */
350 aout_buffer_t *p_out;
351 i_samples = __MIN( i_samples, 1024 );
353 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
356 block_Release( p_block );
360 p_out->start_date = aout_DateGet( &p_sys->end_date );
361 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
363 if( p_sys->p_logtos16 )
365 int16_t *s = (int16_t*)p_out->p_buffer;
368 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
370 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
376 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
377 p_block->p_buffer += p_out->i_nb_bytes;
378 p_block->i_buffer -= p_out->i_nb_bytes;
384 block_Release( p_block );
388 /*****************************************************************************
389 * DecoderClose: decoder destruction
390 *****************************************************************************/
391 static void DecoderClose( vlc_object_t *p_this )
393 decoder_t *p_dec = (decoder_t *)p_this;
395 free( p_dec->p_sys );
398 /*****************************************************************************
400 *****************************************************************************/
401 static int EncoderOpen( vlc_object_t *p_this )
403 encoder_t *p_enc = (encoder_t *)p_this;
405 if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
406 p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
408 msg_Warn( p_enc, "unhandled input format" );
412 switch( p_enc->fmt_out.i_codec )
414 case VLC_FOURCC( 's', '1', '6', 'b' ):
415 case VLC_FOURCC( 's', '1', '6', 'l' ):
416 case VLC_FOURCC( 'u', '8', ' ', ' ' ):
417 case VLC_FOURCC( 's', '8', ' ', ' ' ):
419 -> could be easyly done with table look up
420 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
421 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
429 p_enc->pf_encode_audio = EncoderEncode;
434 /*****************************************************************************
436 *****************************************************************************/
437 static void EncoderClose ( vlc_object_t *p_this )
442 /*****************************************************************************
444 *****************************************************************************/
445 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
447 block_t *p_block = NULL;
450 if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
452 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
454 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
455 p_aout_buf->i_nb_bytes );
458 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
460 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
462 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
463 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
465 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
470 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
472 *p_dst++ = *p_src + 128; p_src += 2;
476 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
478 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
480 int8_t *p_dst = (int8_t*)p_block->p_buffer;
481 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
483 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
488 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
490 *p_dst++ = *p_src; p_src += 2;
496 /* endian swapping */
497 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
499 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
500 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
502 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
515 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
516 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
517 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;