1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VideoLAN
5 * $Id: araw.c,v 1.22 2003/11/05 01:47:40 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 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
31 #include <vlc/decoder.h>
32 #include <vlc/input.h>
38 /*****************************************************************************
40 *****************************************************************************/
41 static int DecoderOpen ( vlc_object_t * );
43 static int EncoderOpen ( vlc_object_t *p_this );
44 static void EncoderClose ( vlc_object_t *p_this );
47 /* audio decoder module */
48 set_description( _("Raw/Log Audio decoder") );
49 set_capability( "decoder", 50 );
50 set_callbacks( DecoderOpen, NULL );
52 /* audio encoder submodule */
54 set_description( _("Raw audio encoder") );
55 set_capability( "audio encoder", 10 );
56 set_callbacks( EncoderOpen, EncoderClose );
60 /*****************************************************************************
62 *****************************************************************************/
63 static int DecoderInit ( decoder_t * );
64 static int DecoderDecode( decoder_t *, block_t * );
65 static int DecoderEnd ( decoder_t * );
71 int16_t *p_logtos16; // used with m/alaw to int16_t
73 /* Output properties */
74 aout_instance_t * p_aout; /* opaque */
75 aout_input_t * p_aout_input; /* opaque */
76 audio_sample_format_t output_format;
82 static block_t *EncoderEncode( encoder_t *, aout_buffer_t *p_aout_buf );
84 /*****************************************************************************
85 * DecoderOpen: probe the decoder and return score
86 *****************************************************************************
87 * Tries to launch a decoder and return score so that the interface is able
89 *****************************************************************************/
90 static int DecoderOpen( vlc_object_t *p_this )
92 decoder_t *p_dec = (decoder_t*)p_this;
94 switch( p_dec->p_fifo->i_fourcc )
96 case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
97 case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
98 case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
100 case VLC_FOURCC('a','l','a','w'):
101 case VLC_FOURCC('u','l','a','w'):
102 p_dec->pf_init = DecoderInit;
103 p_dec->pf_decode = DecoderDecode;
104 p_dec->pf_end = DecoderEnd;
106 p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
114 static int pi_channels_maps[6] =
118 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
119 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
120 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
121 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
122 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
125 static int16_t ulawtos16[256] =
127 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
128 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
129 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
130 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
131 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
132 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
133 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
134 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
135 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
136 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
137 -876, -844, -812, -780, -748, -716, -684, -652,
138 -620, -588, -556, -524, -492, -460, -428, -396,
139 -372, -356, -340, -324, -308, -292, -276, -260,
140 -244, -228, -212, -196, -180, -164, -148, -132,
141 -120, -112, -104, -96, -88, -80, -72, -64,
142 -56, -48, -40, -32, -24, -16, -8, 0,
143 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
144 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
145 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
146 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
147 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
148 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
149 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
150 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
151 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
152 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
153 876, 844, 812, 780, 748, 716, 684, 652,
154 620, 588, 556, 524, 492, 460, 428, 396,
155 372, 356, 340, 324, 308, 292, 276, 260,
156 244, 228, 212, 196, 180, 164, 148, 132,
157 120, 112, 104, 96, 88, 80, 72, 64,
158 56, 48, 40, 32, 24, 16, 8, 0
161 static int16_t alawtos16[256] =
163 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
164 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
165 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
166 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
167 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
168 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
169 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
170 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
171 -344, -328, -376, -360, -280, -264, -312, -296,
172 -472, -456, -504, -488, -408, -392, -440, -424,
173 -88, -72, -120, -104, -24, -8, -56, -40,
174 -216, -200, -248, -232, -152, -136, -184, -168,
175 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
176 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
177 -688, -656, -752, -720, -560, -528, -624, -592,
178 -944, -912, -1008, -976, -816, -784, -880, -848,
179 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
180 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
181 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
182 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
183 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
184 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
185 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
186 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
187 344, 328, 376, 360, 280, 264, 312, 296,
188 472, 456, 504, 488, 408, 392, 440, 424,
189 88, 72, 120, 104, 24, 8, 56, 40,
190 216, 200, 248, 232, 152, 136, 184, 168,
191 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
192 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
193 688, 656, 752, 720, 560, 528, 624, 592,
194 944, 912, 1008, 976, 816, 784, 880, 848
197 /*****************************************************************************
198 * DecoderInit: initialize data before entering main loop
199 *****************************************************************************/
200 static int DecoderInit( decoder_t *p_dec )
202 decoder_sys_t *p_sys = p_dec->p_sys;
205 if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
207 msg_Err( p_dec, "unknown raw format" );
211 if( p_wf->nChannels <= 0 || p_wf->nChannels > 5 )
213 msg_Err( p_dec, "bad channels count(1-5)" );
216 if( p_wf->nSamplesPerSec <= 0 )
218 msg_Err( p_dec, "bad samplerate" );
223 p_sys->p_logtos16 = NULL;
225 /* fixing some values */
226 if( p_wf->nBlockAlign == 0 &&
227 ( p_wf->wFormatTag == WAVE_FORMAT_PCM ||
228 p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ) )
230 p_wf->nBlockAlign = ( p_wf->wBitsPerSample + 7 ) / 8 * p_wf->nChannels;
234 "samplerate:%dHz channels:%d bits/sample:%d blockalign:%d",
235 p_wf->nSamplesPerSec, p_wf->nChannels,
236 p_wf->wBitsPerSample, p_wf->nBlockAlign );
238 if( p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )
240 switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
243 p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
246 p_sys->output_format.i_format = VLC_FOURCC('f','l','6','4');
249 msg_Err( p_dec, "bad parameters(bits/sample)" );
255 if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
257 switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
260 p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
263 p_sys->output_format.i_format = VLC_FOURCC('s','1','6','b');
266 p_sys->output_format.i_format = VLC_FOURCC('s','2','4','b');
269 p_sys->output_format.i_format = VLC_FOURCC('s','3','2','b');
272 msg_Err( p_dec, "bad parameters(bits/sample)" );
276 else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
278 switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
281 p_sys->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
284 p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
287 p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
290 p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
293 msg_Err( p_dec, "bad parameters(bits/sample)" );
297 else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
299 switch( ( p_wf->wBitsPerSample + 7 ) / 8 )
302 p_sys->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
305 p_sys->output_format.i_format = VLC_FOURCC('s','1','6','l');
308 p_sys->output_format.i_format = VLC_FOURCC('s','2','4','l');
311 p_sys->output_format.i_format = VLC_FOURCC('s','3','2','l');
314 msg_Err( p_dec, "bad parameters(bits/sample)" );
318 else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
320 p_sys->output_format.i_format = AOUT_FMT_S16_NE;
321 p_sys->p_logtos16 = alawtos16;
323 else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
325 p_sys->output_format.i_format = AOUT_FMT_S16_NE;
326 p_sys->p_logtos16 = ulawtos16;
329 p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
331 p_sys->output_format.i_physical_channels =
332 p_sys->output_format.i_original_channels = pi_channels_maps[p_wf->nChannels];
334 p_sys->p_aout = NULL;
335 p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
336 &p_sys->output_format );
337 if( p_sys->p_aout_input == NULL )
339 msg_Err( p_dec, "cannot create aout" );
343 aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
344 aout_DateSet( &p_sys->date, 0 );
349 /*****************************************************************************
350 * DecoderDecode: decodes a frame
351 *****************************************************************************/
352 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
354 decoder_sys_t *p_sys = p_dec->p_sys;
355 int i_size = p_block->i_buffer;
356 uint8_t *p = p_block->p_buffer;
357 int i_samples; // per channels
359 if( p_sys->p_wf->nBlockAlign > 0 )
361 /* Align it (it should already be aligned by demuxer) */
362 i_size -= i_size % p_sys->p_wf->nBlockAlign;
364 if( i_size < p_sys->p_wf->nBlockAlign )
366 block_Release( p_block );
369 i_samples = i_size / ( ( p_sys->p_wf->wBitsPerSample + 7 ) / 8 ) /
370 p_sys->p_wf->nChannels;
372 if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
374 aout_DateSet( &p_sys->date, p_block->i_pts );
376 else if( !aout_DateGet( &p_sys->date ) )
378 block_Release( p_block );
382 while( i_samples > 0 )
384 int i_copy = __MIN( i_samples, 1024 );
387 out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, i_copy );
390 msg_Err( p_dec, "cannot get aout buffer" );
391 block_Release( p_block );
395 out->start_date = aout_DateGet( &p_sys->date );
396 out->end_date = aout_DateIncrement( &p_sys->date, i_copy );
398 if( p_sys->p_logtos16 )
400 int16_t *s = (int16_t*)out->p_buffer;
403 for( i = 0; i < out->i_nb_bytes / 2; i++ )
405 *s++ = p_sys->p_logtos16[*p++];
410 memcpy( out->p_buffer, p, out->i_nb_bytes );
412 p += out->i_nb_bytes;
415 aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
419 block_Release( p_block );
423 /*****************************************************************************
424 * DecoderEnd : faad decoder thread destruction
425 *****************************************************************************/
426 static int DecoderEnd( decoder_t *p_dec )
428 decoder_sys_t *p_sys = p_dec->p_sys;
430 if( p_sys->p_aout_input )
432 aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
439 /*****************************************************************************
441 *****************************************************************************/
442 static int EncoderOpen ( vlc_object_t *p_this )
444 encoder_t *p_enc = (encoder_t *)p_this;
446 if( p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'b' ) &&
447 p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'l' ) )
449 msg_Warn( p_enc, "unhandled input format" );
453 switch( p_enc->i_fourcc )
455 case VLC_FOURCC( 's', '1', '6', 'b' ):
456 case VLC_FOURCC( 's', '1', '6', 'l' ):
457 case VLC_FOURCC( 'u', '8', ' ', ' ' ):
458 case VLC_FOURCC( 's', '8', ' ', ' ' ):
460 -> could be easyly done with table look up
461 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
462 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
470 p_enc->pf_header = NULL;
471 p_enc->pf_encode_audio = EncoderEncode;
472 p_enc->pf_encode_video = NULL;
473 p_enc->i_extra_data = 0;
474 p_enc->p_extra_data = NULL;
479 /*****************************************************************************
481 *****************************************************************************/
482 static void EncoderClose ( vlc_object_t *p_this )
487 /*****************************************************************************
489 *****************************************************************************/
490 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
492 block_t *p_block = NULL;
495 if( p_enc->i_fourcc == p_enc->format.audio.i_format )
497 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
499 memcpy( p_block->p_buffer, p_aout_buf->p_buffer, p_aout_buf->i_nb_bytes );
502 else if( p_enc->i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
504 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
506 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
507 int8_t *p_src = (int8_t*) p_aout_buf->p_buffer;
509 if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
514 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
516 *p_dst++ = *p_src + 128; p_src += 2;
520 else if( p_enc->i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
522 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
524 int8_t *p_dst = (int8_t*)p_block->p_buffer;
525 int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
527 if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
532 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
534 *p_dst++ = *p_src; p_src += 2;
540 /* endian swapping */
541 if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
543 uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
544 uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
546 for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
559 p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
560 p_block->i_length = (int64_t)p_aout_buf->i_nb_samples * (int64_t)1000000 /
561 p_enc->format.audio.i_rate;