es: replace i_original_channels with i_chan_mode
[vlc.git] / modules / codec / araw.c
blob3a653eed140c5ebb063464b60da5c7fa0bbd3bfa
1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <math.h>
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_aout.h>
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 static int DecoderOpen ( vlc_object_t * );
43 static void DecoderClose( vlc_object_t * );
45 #ifdef ENABLE_SOUT
46 static int EncoderOpen ( vlc_object_t * );
47 #endif
49 vlc_module_begin ()
50 /* audio decoder module */
51 set_description( N_("Raw/Log Audio decoder") )
52 set_capability( "audio decoder", 100 )
53 set_category( CAT_INPUT )
54 set_subcategory( SUBCAT_INPUT_ACODEC )
55 set_callbacks( DecoderOpen, DecoderClose )
57 #ifdef ENABLE_SOUT
58 /* audio encoder submodule */
59 add_submodule ()
60 set_description( N_("Raw audio encoder") )
61 set_capability( "encoder", 150 )
62 set_callbacks( EncoderOpen, NULL )
63 #endif
64 vlc_module_end ()
66 /*****************************************************************************
67 * Local prototypes
68 *****************************************************************************/
69 static int DecodeBlock( decoder_t *, block_t * );
70 static void Flush( decoder_t * );
72 struct decoder_sys_t
74 void (*decode) (void *, const uint8_t *, unsigned);
75 size_t framebits;
76 date_t end_date;
79 static const uint16_t pi_channels_maps[] =
82 AOUT_CHAN_CENTER, AOUT_CHANS_2_0, AOUT_CHANS_3_0,
83 AOUT_CHANS_4_0, AOUT_CHANS_5_0, AOUT_CHANS_5_1,
84 AOUT_CHANS_7_0, AOUT_CHANS_7_1, AOUT_CHANS_8_1,
86 static_assert( ARRAY_SIZE( pi_channels_maps ) - 1 <= AOUT_CHAN_MAX,
87 "channel count mismatch" );
89 static void S8Decode( void *, const uint8_t *, unsigned );
90 static void U16BDecode( void *, const uint8_t *, unsigned );
91 static void U16LDecode( void *, const uint8_t *, unsigned );
92 static void S16IDecode( void *, const uint8_t *, unsigned );
93 static void S20BDecode( void *, const uint8_t *, unsigned );
94 static void U24BDecode( void *, const uint8_t *, unsigned );
95 static void U24LDecode( void *, const uint8_t *, unsigned );
96 static void S24BDecode( void *, const uint8_t *, unsigned );
97 static void S24LDecode( void *, const uint8_t *, unsigned );
98 static void S24B32Decode( void *, const uint8_t *, unsigned );
99 static void S24L32Decode( void *, const uint8_t *, unsigned );
100 static void U32BDecode( void *, const uint8_t *, unsigned );
101 static void U32LDecode( void *, const uint8_t *, unsigned );
102 static void S32IDecode( void *, const uint8_t *, unsigned );
103 static void F32NDecode( void *, const uint8_t *, unsigned );
104 static void F32IDecode( void *, const uint8_t *, unsigned );
105 static void F64NDecode( void *, const uint8_t *, unsigned );
106 static void F64IDecode( void *, const uint8_t *, unsigned );
107 static void DAT12Decode( void *, const uint8_t *, unsigned );
109 /*****************************************************************************
110 * DecoderOpen: probe the decoder and return score
111 *****************************************************************************/
112 static int DecoderOpen( vlc_object_t *p_this )
114 decoder_t *p_dec = (decoder_t*)p_this;
115 vlc_fourcc_t format = p_dec->fmt_in.i_codec;
117 switch( p_dec->fmt_in.i_codec )
119 case VLC_FOURCC('a','r','a','w'):
120 case VLC_FOURCC('a','f','l','t'):
121 /* _signed_ big endian samples (mov) */
122 case VLC_FOURCC('t','w','o','s'):
123 /* _signed_ little endian samples (mov) */
124 case VLC_FOURCC('s','o','w','t'):
125 format =
126 vlc_fourcc_GetCodecAudio( p_dec->fmt_in.i_codec,
127 p_dec->fmt_in.audio.i_bitspersample );
128 if( !format )
130 msg_Err( p_dec, "bad parameters(bits/sample)" );
131 return VLC_EGENERIC;
133 break;
136 void (*decode) (void *, const uint8_t *, unsigned) = NULL;
137 uint_fast8_t bits;
139 switch( format )
141 #ifdef WORDS_BIGENDIAN
142 case VLC_CODEC_F64L:
143 #else
144 case VLC_CODEC_F64B:
145 #endif
146 format = VLC_CODEC_FL64;
147 decode = F64IDecode;
148 bits = 64;
149 break;
150 case VLC_CODEC_FL64:
151 decode = F64NDecode;
152 bits = 64;
153 break;
154 #ifdef WORDS_BIGENDIAN
155 case VLC_CODEC_F32L:
156 #else
157 case VLC_CODEC_F32B:
158 #endif
159 format = VLC_CODEC_FL32;
160 decode = F32IDecode;
161 bits = 32;
162 break;
163 case VLC_CODEC_FL32:
164 decode = F32NDecode;
165 bits = 32;
166 break;
167 case VLC_CODEC_U32B:
168 format = VLC_CODEC_S32N;
169 decode = U32BDecode;
170 bits = 32;
171 break;
172 case VLC_CODEC_U32L:
173 format = VLC_CODEC_S32N;
174 decode = U32LDecode;
175 bits = 32;
176 break;
177 case VLC_CODEC_S32I:
178 format = VLC_CODEC_S32N;
179 decode = S32IDecode;
180 /* fall through */
181 case VLC_CODEC_S32N:
182 bits = 32;
183 break;
184 case VLC_CODEC_S24B32:
185 format = VLC_CODEC_S32N;
186 decode = S24B32Decode;
187 bits = 32;
188 break;
189 case VLC_CODEC_S24L32:
190 format = VLC_CODEC_S32N;
191 decode = S24L32Decode;
192 bits = 32;
193 break;
194 case VLC_CODEC_U24B:
195 format = VLC_CODEC_S32N;
196 decode = U24BDecode;
197 bits = 24;
198 break;
199 case VLC_CODEC_U24L:
200 format = VLC_CODEC_S32N;
201 decode = U24LDecode;
202 bits = 24;
203 break;
204 case VLC_CODEC_S24B:
205 format = VLC_CODEC_S32N;
206 decode = S24BDecode;
207 bits = 24;
208 break;
209 case VLC_CODEC_S24L:
210 format = VLC_CODEC_S32N;
211 decode = S24LDecode;
212 bits = 24;
213 break;
214 case VLC_CODEC_S20B:
215 format = VLC_CODEC_S32N;
216 decode = S20BDecode;
217 bits = 20;
218 break;
219 case VLC_CODEC_U16B:
220 format = VLC_CODEC_S16N;
221 decode = U16BDecode;
222 bits = 16;
223 break;
224 case VLC_CODEC_U16L:
225 format = VLC_CODEC_S16N;
226 decode = U16LDecode;
227 bits = 16;
228 break;
229 case VLC_CODEC_S16I:
230 format = VLC_CODEC_S16N;
231 decode = S16IDecode;
232 /* fall through */
233 case VLC_CODEC_S16N:
234 bits = 16;
235 break;
236 case VLC_CODEC_DAT12:
237 format = VLC_CODEC_S16N;
238 decode = DAT12Decode;
239 bits = 12;
240 break;
241 case VLC_CODEC_S8:
242 decode = S8Decode;
243 format = VLC_CODEC_U8;
244 /* fall through */
245 case VLC_CODEC_U8:
246 bits = 8;
247 break;
248 default:
249 return VLC_EGENERIC;
252 if( p_dec->fmt_in.audio.i_channels == 0 ||
253 p_dec->fmt_in.audio.i_channels > INPUT_CHAN_MAX )
255 msg_Err( p_dec, "bad channels count (1-%i): %i",
256 AOUT_CHAN_MAX, p_dec->fmt_in.audio.i_channels );
257 return VLC_EGENERIC;
260 if( p_dec->fmt_in.audio.i_rate == 0 || p_dec->fmt_in.audio.i_rate > 384000 )
262 msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
263 return VLC_EGENERIC;
266 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
267 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
268 p_dec->fmt_in.audio.i_bitspersample );
270 /* Allocate the memory needed to store the decoder's structure */
271 decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
272 if( unlikely(p_sys == NULL) )
273 return VLC_ENOMEM;
275 /* Set output properties */
276 p_dec->fmt_out.i_codec = format;
277 p_dec->fmt_out.audio.i_format = format;
278 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
279 if( p_dec->fmt_in.audio.i_channels <= ARRAY_SIZE( pi_channels_maps ) - 1 )
281 if( p_dec->fmt_in.audio.i_physical_channels )
282 p_dec->fmt_out.audio.i_physical_channels =
283 p_dec->fmt_in.audio.i_physical_channels;
284 else
285 p_dec->fmt_out.audio.i_physical_channels =
286 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
288 else
290 /* Unknown channel map, let the aout/filters decide what to do */
291 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
292 p_dec->fmt_out.audio.i_physical_channels = 0;
294 aout_FormatPrepare( &p_dec->fmt_out.audio );
296 p_sys->decode = decode;
297 p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
298 assert( p_sys->framebits );
300 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
301 date_Set( &p_sys->end_date, 0 );
303 p_dec->pf_decode = DecodeBlock;
304 p_dec->pf_flush = Flush;
305 p_dec->p_sys = p_sys;
307 return VLC_SUCCESS;
310 /*****************************************************************************
311 * Flush:
312 *****************************************************************************/
313 static void Flush( decoder_t *p_dec )
315 decoder_sys_t *p_sys = p_dec->p_sys;
317 date_Set( &p_sys->end_date, 0 );
320 /****************************************************************************
321 * DecodeBlock: the whole thing
322 ****************************************************************************
323 * This function must be fed with whole samples (see nBlockAlign).
324 ****************************************************************************/
325 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
327 decoder_sys_t *p_sys = p_dec->p_sys;
328 if( p_block == NULL ) /* No Drain */
329 return VLCDEC_SUCCESS;
331 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
333 Flush( p_dec );
334 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
335 goto skip;
338 if( p_block->i_pts > VLC_TS_INVALID &&
339 p_block->i_pts != date_Get( &p_sys->end_date ) )
341 date_Set( &p_sys->end_date, p_block->i_pts );
343 else if( !date_Get( &p_sys->end_date ) )
344 /* We've just started the stream, wait for the first PTS. */
345 goto skip;
347 unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
348 if( samples == 0 )
349 goto skip;
351 if( p_sys->decode != NULL )
353 if( decoder_UpdateAudioFormat( p_dec ) )
354 goto skip;
355 block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
356 if( p_out == NULL )
357 goto skip;
359 p_sys->decode( p_out->p_buffer, p_block->p_buffer,
360 samples * p_dec->fmt_in.audio.i_channels );
361 block_Release( p_block );
362 p_block = p_out;
364 else
366 decoder_UpdateAudioFormat( p_dec );
367 p_block->i_nb_samples = samples;
368 p_block->i_buffer = samples * (p_sys->framebits / 8);
371 p_block->i_pts = date_Get( &p_sys->end_date );
372 p_block->i_length = date_Increment( &p_sys->end_date, samples )
373 - p_block->i_pts;
374 decoder_QueueAudio( p_dec, p_block );
375 return VLCDEC_SUCCESS;
376 skip:
377 block_Release( p_block );
378 return VLCDEC_SUCCESS;
381 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
383 uint8_t *out = outp;
385 for( size_t i = 0; i < samples; i++ )
386 out[i] = in[i] ^ 0x80;
389 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
391 uint16_t *out = outp;
393 for( size_t i = 0; i < samples; i++ )
395 *(out++) = GetWBE( in ) - 0x8000;
396 in += 2;
400 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
402 uint16_t *out = outp;
404 for( size_t i = 0; i < samples; i++ )
406 *(out++) = GetWLE( in ) - 0x8000;
407 in += 2;
411 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
413 swab( in, out, samples * 2 );
416 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
418 int32_t *out = outp;
420 while( samples >= 2 )
422 uint32_t dw = U32_AT(in);
423 in += 4;
424 *(out++) = dw & ~0xFFF;
425 *(out++) = (dw << 20) | (*in << 12);
426 in++;
427 samples -= 2;
430 /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
431 if( samples )
432 *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
435 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
437 uint32_t *out = outp;
439 for( size_t i = 0; i < samples; i++ )
441 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
442 *(out++) = s;
443 in += 3;
447 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
449 uint32_t *out = outp;
451 for( size_t i = 0; i < samples; i++ )
453 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
454 *(out++) = s;
455 in += 3;
459 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
461 uint32_t *out = outp;
463 for( size_t i = 0; i < samples; i++ )
465 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
466 *(out++) = s;
467 in += 3;
471 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
473 uint32_t *out = outp;
475 for( size_t i = 0; i < samples; i++ )
477 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
478 *(out++) = s;
479 in += 3;
483 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
485 uint32_t *out = outp;
487 for( size_t i = 0; i < samples; i++ )
489 *(out++) = GetDWBE( in ) << 8;
490 in += 4;
494 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
496 uint32_t *out = outp;
498 for( size_t i = 0; i < samples; i++ )
500 *(out++) = GetDWLE( in ) << 8;
501 in += 4;
505 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
507 uint32_t *out = outp;
509 for( size_t i = 0; i < samples; i++ )
511 *(out++) = GetDWBE( in ) - 0x80000000;
512 in += 4;
516 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
518 uint32_t *out = outp;
520 for( size_t i = 0; i < samples; i++ )
522 *(out++) = GetDWLE( in ) - 0x80000000;
523 in += 4;
527 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
529 int32_t *out = outp;
531 for( size_t i = 0; i < samples; i++ )
533 #ifdef WORDS_BIGENDIAN
534 *(out++) = GetDWLE( in );
535 #else
536 *(out++) = GetDWBE( in );
537 #endif
538 in += 4;
542 static void F32NDecode( void *outp, const uint8_t *in, unsigned samples )
544 float *out = outp;
546 for( size_t i = 0; i < samples; i++ )
548 memcpy( out, in, sizeof(float) );
549 if( unlikely(!isfinite(*out)) )
550 *out = 0.f;
551 out++;
552 in += sizeof(float);
556 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
558 float *out = outp;
560 for( size_t i = 0; i < samples; i++ )
562 union { float f; uint32_t u; } s;
564 #ifdef WORDS_BIGENDIAN
565 s.u = GetDWLE( in );
566 #else
567 s.u = GetDWBE( in );
568 #endif
569 if( unlikely(!isfinite(s.f)) )
570 s.f = 0.f;
571 *(out++) = s.f;
572 in += 4;
576 static void F64NDecode( void *outp, const uint8_t *in, unsigned samples )
578 double *out = outp;
580 for( size_t i = 0; i < samples; i++ )
582 memcpy( out, in, sizeof(double) );
583 if( unlikely(!isfinite( *out )) )
584 *out = 0.;
585 out++;
586 in += sizeof(double);
590 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
592 double *out = outp;
594 for( size_t i = 0; i < samples; i++ )
596 union { double d; uint64_t u; } s;
598 #ifdef WORDS_BIGENDIAN
599 s.u = GetQWLE( in );
600 #else
601 s.u = GetQWBE( in );
602 #endif
603 if( unlikely(!isfinite( s.d )) )
604 s.d = 0.;
605 *(out++) = s.d;
606 in += 8;
610 static int16_t dat12tos16( uint_fast16_t y )
612 static const uint16_t diff[16] = {
613 0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
614 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000 };
615 static const uint8_t shift[16] = {
616 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0 };
618 assert(y < 0x1000);
620 int d = y >> 8;
621 return (y - diff[d]) << shift[d];
624 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
626 int32_t *out = outp;
628 while( samples >= 2 )
630 *(out++) = dat12tos16(U16_AT(in) >> 4);
631 *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
632 in += 3;
633 samples -= 2;
636 if( samples )
637 *(out++) = dat12tos16(U16_AT(in) >> 4);
640 /*****************************************************************************
641 * DecoderClose: decoder destruction
642 *****************************************************************************/
643 static void DecoderClose( vlc_object_t *p_this )
645 decoder_t *p_dec = (decoder_t *)p_this;
647 free( p_dec->p_sys );
650 #ifdef ENABLE_SOUT
651 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
652 * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
653 * since decoded audio blocks must always be aligned. */
655 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
657 const uint16_t *in = (const uint16_t *)inp;
658 uint16_t *out = outp;
660 for( size_t i = 0; i < samples; i++ )
661 *(out++) = bswap16( *(in++) + 0x8000 );
664 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
666 const uint16_t *in = (const uint16_t *)inp;
667 uint16_t *out = outp;
669 for( size_t i = 0; i < samples; i++ )
670 *(out++) = *(in++) + 0x8000;
673 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
675 const uint32_t *in = (const uint32_t *)inp;
676 uint8_t *out = outp;
678 for( size_t i = 0; i < samples; i++ )
680 uint32_t s = *(in++);
681 *(out++) = (s >> 24) + 0x80;
682 *(out++) = (s >> 16);
683 *(out++) = (s >> 8);
687 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
689 const uint32_t *in = (const uint32_t *)inp;
690 uint8_t *out = outp;
692 for( size_t i = 0; i < samples; i++ )
694 uint32_t s = *(in++);
695 *(out++) = (s >> 8);
696 *(out++) = (s >> 16);
697 *(out++) = (s >> 24) + 0x80;
701 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
703 const uint32_t *in = (const uint32_t *)inp;
704 uint8_t *out = outp;
706 for( size_t i = 0; i < samples; i++ )
708 uint32_t s = *(in++);
709 *(out++) = (s >> 24);
710 *(out++) = (s >> 16);
711 *(out++) = (s >> 8);
715 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
717 const uint32_t *in = (const uint32_t *)inp;
718 uint8_t *out = outp;
720 for( size_t i = 0; i < samples; i++ )
722 uint32_t s = *(in++);
723 *(out++) = (s >> 8);
724 *(out++) = (s >> 16);
725 *(out++) = (s >> 24);
729 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
731 const uint32_t *in = (const uint32_t *)inp;
732 uint32_t *out = outp;
734 for( size_t i = 0; i < samples; i++ )
735 *(out++) = bswap32( *(in++) + 0x80000000 );
738 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
740 const uint32_t *in = (const uint32_t *)inp;
741 uint32_t *out = outp;
743 for( size_t i = 0; i < samples; i++ )
744 *(out++) = *(in++) + 0x80000000;
747 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
749 const int32_t *in = (const int32_t *)inp;
750 int32_t *out = outp;
752 for( size_t i = 0; i < samples; i++ )
753 *(out++) = bswap32( *(in++) );
756 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
758 const float *in = (const float *)inp;
759 uint8_t *out = outp;
761 for( size_t i = 0; i < samples; i++ )
763 union { float f; uint32_t u; char b[4]; } s;
765 s.f = *(in++);
766 s.u = bswap32( s.u );
767 memcpy( out, s.b, 4 );
768 out += 4;
772 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
774 const double *in = (const double *)inp;
775 uint8_t *out = outp;
777 for( size_t i = 0; i < samples; i++ )
779 union { double d; uint64_t u; char b[8]; } s;
781 s.d = *(in++);
782 s.u = bswap64( s.u );
783 memcpy( out, s.b, 8 );
784 out += 8;
788 static block_t *Encode( encoder_t *enc, block_t *in )
790 if( in == NULL )
791 return NULL;
793 block_t *out = block_Alloc( in->i_nb_samples
794 * enc->fmt_out.audio.i_bytes_per_frame );
795 if( unlikely(out == NULL) )
796 return NULL;
798 out->i_flags = in->i_flags;
799 out->i_nb_samples = in->i_nb_samples;
800 out->i_dts = in->i_dts;
801 out->i_pts = in->i_pts;
802 out->i_length = in->i_length;
804 void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
805 if( encode != NULL )
806 encode( out->p_buffer, in->p_buffer, in->i_nb_samples
807 * enc->fmt_out.audio.i_channels );
808 else {
809 assert( out->i_buffer >= in->i_buffer );
810 memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
812 return out;
816 * Probes the PCM audio encoder.
818 static int EncoderOpen( vlc_object_t *p_this )
820 encoder_t *p_enc = (encoder_t *)p_this;
821 void (*encode)(void *, const uint8_t *, unsigned) = NULL;
823 switch( p_enc->fmt_out.i_codec )
825 case VLC_CODEC_S8:
826 encode = S8Decode;
827 /* fall through */
828 case VLC_CODEC_U8:
829 p_enc->fmt_in.i_codec = VLC_CODEC_U8;
830 p_enc->fmt_out.audio.i_bitspersample = 8;
831 break;
832 case VLC_CODEC_U16I:
833 encode = U16IEncode;
834 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
835 p_enc->fmt_out.audio.i_bitspersample = 16;
836 break;
837 case VLC_CODEC_U16N:
838 encode = U16NEncode;
839 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
840 p_enc->fmt_out.audio.i_bitspersample = 16;
841 break;
842 case VLC_CODEC_S16I:
843 encode = S16IDecode;
844 /* fall through */
845 case VLC_CODEC_S16N:
846 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
847 p_enc->fmt_out.audio.i_bitspersample = 16;
848 break;
849 case VLC_CODEC_U24B:
850 encode = U24BEncode;
851 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
852 p_enc->fmt_out.audio.i_bitspersample = 24;
853 break;
854 case VLC_CODEC_U24L:
855 encode = U24LEncode;
856 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
857 p_enc->fmt_out.audio.i_bitspersample = 24;
858 break;
859 case VLC_CODEC_S24B:
860 encode = S24BEncode;
861 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
862 p_enc->fmt_out.audio.i_bitspersample = 24;
863 break;
864 case VLC_CODEC_S24L:
865 encode = S24LEncode;
866 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
867 p_enc->fmt_out.audio.i_bitspersample = 24;
868 break;
869 case VLC_CODEC_U32I:
870 encode = U32IEncode;
871 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
872 p_enc->fmt_out.audio.i_bitspersample = 32;
873 break;
874 case VLC_CODEC_U32N:
875 encode = U32NEncode;
876 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
877 p_enc->fmt_out.audio.i_bitspersample = 32;
878 break;
879 case VLC_CODEC_S32I:
880 encode = S32IEncode;
881 /* fall through */
882 case VLC_CODEC_S32N:
883 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
884 p_enc->fmt_out.audio.i_bitspersample = 32;
885 break;
886 #ifdef WORDS_BIGENDIAN
887 case VLC_CODEC_F32L:
888 #else
889 case VLC_CODEC_F32B:
890 #endif
891 encode = F32IEncode;
892 /* fall through */
893 case VLC_CODEC_FL32:
894 p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
895 p_enc->fmt_out.audio.i_bitspersample = 32;
896 break;
897 #ifdef WORDS_BIGENDIAN
898 case VLC_CODEC_F64L:
899 #else
900 case VLC_CODEC_F64B:
901 #endif
902 encode = F64IEncode;
903 /* fall through */
904 case VLC_CODEC_FL64:
905 p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
906 p_enc->fmt_out.audio.i_bitspersample = 64;
907 break;
908 default:
909 return VLC_EGENERIC;
912 p_enc->p_sys = (void *)encode;
913 p_enc->pf_encode_audio = Encode;
914 p_enc->fmt_out.audio.i_bytes_per_frame =
915 (p_enc->fmt_out.audio.i_bitspersample / 8) *
916 p_enc->fmt_in.audio.i_channels;
917 p_enc->fmt_out.i_bitrate =
918 p_enc->fmt_in.audio.i_channels *
919 p_enc->fmt_in.audio.i_rate *
920 p_enc->fmt_out.audio.i_bitspersample;
922 msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
923 p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
924 p_enc->fmt_out.audio.i_bitspersample );
926 return VLC_SUCCESS;
928 #endif /* ENABLE_SOUT */