1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.24 2003/11/16 21:07:30 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 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
30 #include <vlc/decoder.h>
31 #include <vlc/input.h>
35 /*****************************************************************************
37 *****************************************************************************/
38 static int DecoderOpen ( vlc_object_t * );
39 static void DecoderClose( vlc_object_t * );
41 static int EncoderOpen ( vlc_object_t * );
42 static void EncoderClose( vlc_object_t * );
45 /* audio decoder module */
46 set_description( _("Raw/Log Audio decoder") );
47 set_capability( "decoder", 50 );
48 set_callbacks( DecoderOpen, DecoderClose );
50 /* audio encoder submodule */
52 set_description( _("Raw audio encoder") );
53 set_capability( "encoder", 10 );
54 set_callbacks( EncoderOpen, EncoderClose );
57 /*****************************************************************************
59 *****************************************************************************/
60 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
61 static block_t *EncoderEncode( encoder_t *, aout_buffer_t * );
65 int16_t *p_logtos16; /* used with m/alaw to int16_t */
67 audio_date_t end_date;
70 static int pi_channels_maps[6] =
74 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
75 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
76 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
77 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
78 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
81 static int16_t ulawtos16[256] =
83 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
84 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
85 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
86 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
87 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
88 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
89 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
90 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
91 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
92 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
93 -876, -844, -812, -780, -748, -716, -684, -652,
94 -620, -588, -556, -524, -492, -460, -428, -396,
95 -372, -356, -340, -324, -308, -292, -276, -260,
96 -244, -228, -212, -196, -180, -164, -148, -132,
97 -120, -112, -104, -96, -88, -80, -72, -64,
98 -56, -48, -40, -32, -24, -16, -8, 0,
99 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
100 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
101 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
102 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
103 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
104 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
105 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
106 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
107 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
108 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
109 876, 844, 812, 780, 748, 716, 684, 652,
110 620, 588, 556, 524, 492, 460, 428, 396,
111 372, 356, 340, 324, 308, 292, 276, 260,
112 244, 228, 212, 196, 180, 164, 148, 132,
113 120, 112, 104, 96, 88, 80, 72, 64,
114 56, 48, 40, 32, 24, 16, 8, 0
117 static int16_t alawtos16[256] =
119 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
120 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
121 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
122 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
123 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
124 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
125 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
126 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
127 -344, -328, -376, -360, -280, -264, -312, -296,
128 -472, -456, -504, -488, -408, -392, -440, -424,
129 -88, -72, -120, -104, -24, -8, -56, -40,
130 -216, -200, -248, -232, -152, -136, -184, -168,
131 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
132 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
133 -688, -656, -752, -720, -560, -528, -624, -592,
134 -944, -912, -1008, -976, -816, -784, -880, -848,
135 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
136 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
137 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
138 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
139 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
140 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
141 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
142 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
143 344, 328, 376, 360, 280, 264, 312, 296,
144 472, 456, 504, 488, 408, 392, 440, 424,
145 88, 72, 120, 104, 24, 8, 56, 40,
146 216, 200, 248, 232, 152, 136, 184, 168,
147 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
148 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
149 688, 656, 752, 720, 560, 528, 624, 592,
150 944, 912, 1008, 976, 816, 784, 880, 848
153 /*****************************************************************************
154 * DecoderOpen: probe the decoder and return score
155 *****************************************************************************/
156 static int DecoderOpen( vlc_object_t *p_this )
158 decoder_t *p_dec = (decoder_t*)p_this;
159 decoder_sys_t *p_sys;
161 switch( p_dec->fmt_in.i_codec )
163 /* from wav/avi/asf file */
164 case VLC_FOURCC('a','r','a','w'):
165 /* _signed_ big endian samples (mov)*/
166 case VLC_FOURCC('t','w','o','s'):
167 /* _signed_ little endian samples (mov)*/
168 case VLC_FOURCC('s','o','w','t'):
170 case VLC_FOURCC('a','l','a','w'):
171 case VLC_FOURCC('u','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 > 5 )
189 msg_Err( p_dec, "bad channels count(1-5)" );
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( 0 /* p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT */ )
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' ) )
293 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
294 p_sys->p_logtos16 = ulawtos16;
295 p_dec->fmt_in.audio.i_bitspersample = 8;
299 /* Set output properties */
300 p_dec->fmt_out.i_cat = AUDIO_ES;
301 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
302 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
303 p_dec->fmt_out.audio.i_physical_channels =
304 p_dec->fmt_out.audio.i_original_channels =
305 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
307 aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate );
308 aout_DateSet( &p_sys->end_date, 0 );
310 p_dec->pf_decode_audio = DecodeBlock;
315 /****************************************************************************
316 * DecodeBlock: the whole thing
317 ****************************************************************************
318 * This function must be fed with whole samples (see nBlockAlign).
319 ****************************************************************************/
320 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
322 decoder_sys_t *p_sys = p_dec->p_sys;
326 if( !pp_block || !*pp_block ) return NULL;
330 if( p_block->i_pts != 0 &&
331 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
333 aout_DateSet( &p_sys->end_date, p_block->i_pts );
335 else if( !aout_DateGet( &p_sys->end_date ) )
337 /* We've just started the stream, wait for the first PTS. */
338 block_Release( p_block );
342 /* Don't re-use the same pts twice */
345 i_samples = p_block->i_buffer * 8 / p_dec->fmt_in.audio.i_bitspersample /
346 p_dec->fmt_in.audio.i_channels;
349 /* Create chunks of max 1024 samples */
352 aout_buffer_t *p_out;
353 i_samples = __MIN( i_samples, 1024 );
355 p_out = p_dec->pf_aout_buffer_new( p_dec, i_samples );
358 block_Release( p_block );
362 p_out->start_date = aout_DateGet( &p_sys->end_date );
363 p_out->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
365 if( p_sys->p_logtos16 )
367 int16_t *s = (int16_t*)p_out->p_buffer;
370 for( i = 0; i < p_out->i_nb_bytes / 2; i++ )
372 *s++ = p_sys->p_logtos16[*p_block->p_buffer++];
378 memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_nb_bytes );
379 p_block->p_buffer += p_out->i_nb_bytes;
380 p_block->i_buffer -= p_out->i_nb_bytes;
386 block_Release( p_block );
390 /*****************************************************************************
391 * DecoderClose: decoder destruction
392 *****************************************************************************/
393 static void DecoderClose( vlc_object_t *p_this )
395 decoder_t *p_dec = (decoder_t *)p_this;
397 free( p_dec->p_sys );
400 /*****************************************************************************
402 *****************************************************************************/
403 static int EncoderOpen( vlc_object_t *p_this )
405 encoder_t *p_enc = (encoder_t *)p_this;
407 if( p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'b' ) &&
408 p_enc->fmt_in.i_codec != VLC_FOURCC( 's', '1', '6', 'l' ) )
410 msg_Warn( p_enc, "unhandled input format" );
414 switch( p_enc->fmt_out.i_codec )
416 case VLC_FOURCC( 's', '1', '6', 'b' ):
417 case VLC_FOURCC( 's', '1', '6', 'l' ):
418 case VLC_FOURCC( 'u', '8', ' ', ' ' ):
419 case VLC_FOURCC( 's', '8', ' ', ' ' ):
421 -> could be easyly done with table look up
422 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
423 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
431 p_enc->pf_encode_audio = EncoderEncode;
436 /*****************************************************************************
438 *****************************************************************************/
439 static void EncoderClose ( vlc_object_t *p_this )
444 /*****************************************************************************
446 *****************************************************************************/
447 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
449 block_t *p_block = NULL;
452 if( p_enc->fmt_in.i_codec == p_enc->fmt_out.i_codec )
454 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
456 memcpy( p_block->p_buffer, p_aout_buf->p_buffer,
457 p_aout_buf->i_nb_bytes );
460 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
462 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
464 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
465 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
467 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
472 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
474 *p_dst++ = *p_src + 128; p_src += 2;
478 else if( p_enc->fmt_out.i_codec == VLC_FOURCC( 's', '8', ' ', ' ' ) )
480 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
482 int8_t *p_dst = (int8_t*)p_block->p_buffer;
483 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
485 if( p_enc->fmt_in.i_codec == VLC_FOURCC( 's', '1', '6', 'l' ) )
490 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
492 *p_dst++ = *p_src; p_src += 2;
498 /* endian swapping */
499 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
501 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
502 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
504 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
517 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
518 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples *
519 (int64_t)1000000 / p_enc->fmt_in.audio.i_rate;