contrib: soxr: enable by default
[vlc.git] / modules / codec / araw.c
blob605e4f382290aeb41b4f73d0663d080965b8ac1a
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.channel_type = p_dec->fmt_in.audio.channel_type;
278 p_dec->fmt_out.audio.i_format = format;
279 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
280 if( p_dec->fmt_in.audio.i_channels <= ARRAY_SIZE( pi_channels_maps ) - 1 )
282 if( p_dec->fmt_in.audio.i_physical_channels )
283 p_dec->fmt_out.audio.i_physical_channels =
284 p_dec->fmt_in.audio.i_physical_channels;
285 else
286 p_dec->fmt_out.audio.i_physical_channels =
287 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
289 else
291 /* Unknown channel map, let the aout/filters decide what to do */
292 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
293 p_dec->fmt_out.audio.i_physical_channels = 0;
295 aout_FormatPrepare( &p_dec->fmt_out.audio );
297 p_sys->decode = decode;
298 p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
299 assert( p_sys->framebits );
301 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
302 date_Set( &p_sys->end_date, 0 );
304 p_dec->pf_decode = DecodeBlock;
305 p_dec->pf_flush = Flush;
306 p_dec->p_sys = p_sys;
308 return VLC_SUCCESS;
311 /*****************************************************************************
312 * Flush:
313 *****************************************************************************/
314 static void Flush( decoder_t *p_dec )
316 decoder_sys_t *p_sys = p_dec->p_sys;
318 date_Set( &p_sys->end_date, 0 );
321 /****************************************************************************
322 * DecodeBlock: the whole thing
323 ****************************************************************************
324 * This function must be fed with whole samples (see nBlockAlign).
325 ****************************************************************************/
326 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
328 decoder_sys_t *p_sys = p_dec->p_sys;
329 if( p_block == NULL ) /* No Drain */
330 return VLCDEC_SUCCESS;
332 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
334 Flush( p_dec );
335 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
336 goto skip;
339 if( p_block->i_pts > VLC_TS_INVALID &&
340 p_block->i_pts != date_Get( &p_sys->end_date ) )
342 date_Set( &p_sys->end_date, p_block->i_pts );
344 else if( !date_Get( &p_sys->end_date ) )
345 /* We've just started the stream, wait for the first PTS. */
346 goto skip;
348 unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
349 if( samples == 0 )
350 goto skip;
352 if( p_sys->decode != NULL )
354 if( decoder_UpdateAudioFormat( p_dec ) )
355 goto skip;
356 block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
357 if( p_out == NULL )
358 goto skip;
360 p_sys->decode( p_out->p_buffer, p_block->p_buffer,
361 samples * p_dec->fmt_in.audio.i_channels );
362 block_Release( p_block );
363 p_block = p_out;
365 else
367 if( decoder_UpdateAudioFormat( p_dec ) )
368 goto skip;
369 p_block->i_nb_samples = samples;
370 p_block->i_buffer = samples * (p_sys->framebits / 8);
373 p_block->i_pts = date_Get( &p_sys->end_date );
374 p_block->i_length = date_Increment( &p_sys->end_date, samples )
375 - p_block->i_pts;
376 decoder_QueueAudio( p_dec, p_block );
377 return VLCDEC_SUCCESS;
378 skip:
379 block_Release( p_block );
380 return VLCDEC_SUCCESS;
383 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
385 uint8_t *out = outp;
387 for( size_t i = 0; i < samples; i++ )
388 out[i] = in[i] ^ 0x80;
391 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
393 uint16_t *out = outp;
395 for( size_t i = 0; i < samples; i++ )
397 *(out++) = GetWBE( in ) - 0x8000;
398 in += 2;
402 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
404 uint16_t *out = outp;
406 for( size_t i = 0; i < samples; i++ )
408 *(out++) = GetWLE( in ) - 0x8000;
409 in += 2;
413 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
415 swab( in, out, samples * 2 );
418 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
420 int32_t *out = outp;
422 while( samples >= 2 )
424 uint32_t dw = U32_AT(in);
425 in += 4;
426 *(out++) = dw & ~0xFFF;
427 *(out++) = (dw << 20) | (*in << 12);
428 in++;
429 samples -= 2;
432 /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
433 if( samples )
434 *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
437 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
439 uint32_t *out = outp;
441 for( size_t i = 0; i < samples; i++ )
443 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
444 *(out++) = s;
445 in += 3;
449 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
451 uint32_t *out = outp;
453 for( size_t i = 0; i < samples; i++ )
455 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
456 *(out++) = s;
457 in += 3;
461 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
463 uint32_t *out = outp;
465 for( size_t i = 0; i < samples; i++ )
467 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
468 *(out++) = s;
469 in += 3;
473 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
475 uint32_t *out = outp;
477 for( size_t i = 0; i < samples; i++ )
479 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
480 *(out++) = s;
481 in += 3;
485 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
487 uint32_t *out = outp;
489 for( size_t i = 0; i < samples; i++ )
491 *(out++) = GetDWBE( in ) << 8;
492 in += 4;
496 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
498 uint32_t *out = outp;
500 for( size_t i = 0; i < samples; i++ )
502 *(out++) = GetDWLE( in ) << 8;
503 in += 4;
507 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
509 uint32_t *out = outp;
511 for( size_t i = 0; i < samples; i++ )
513 *(out++) = GetDWBE( in ) - 0x80000000;
514 in += 4;
518 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
520 uint32_t *out = outp;
522 for( size_t i = 0; i < samples; i++ )
524 *(out++) = GetDWLE( in ) - 0x80000000;
525 in += 4;
529 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
531 int32_t *out = outp;
533 for( size_t i = 0; i < samples; i++ )
535 #ifdef WORDS_BIGENDIAN
536 *(out++) = GetDWLE( in );
537 #else
538 *(out++) = GetDWBE( in );
539 #endif
540 in += 4;
544 static void F32NDecode( void *outp, const uint8_t *in, unsigned samples )
546 float *out = outp;
548 for( size_t i = 0; i < samples; i++ )
550 memcpy( out, in, sizeof(float) );
551 if( unlikely(!isfinite(*out)) )
552 *out = 0.f;
553 out++;
554 in += sizeof(float);
558 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
560 float *out = outp;
562 for( size_t i = 0; i < samples; i++ )
564 union { float f; uint32_t u; } s;
566 #ifdef WORDS_BIGENDIAN
567 s.u = GetDWLE( in );
568 #else
569 s.u = GetDWBE( in );
570 #endif
571 if( unlikely(!isfinite(s.f)) )
572 s.f = 0.f;
573 *(out++) = s.f;
574 in += 4;
578 static void F64NDecode( void *outp, const uint8_t *in, unsigned samples )
580 double *out = outp;
582 for( size_t i = 0; i < samples; i++ )
584 memcpy( out, in, sizeof(double) );
585 if( unlikely(!isfinite( *out )) )
586 *out = 0.;
587 out++;
588 in += sizeof(double);
592 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
594 double *out = outp;
596 for( size_t i = 0; i < samples; i++ )
598 union { double d; uint64_t u; } s;
600 #ifdef WORDS_BIGENDIAN
601 s.u = GetQWLE( in );
602 #else
603 s.u = GetQWBE( in );
604 #endif
605 if( unlikely(!isfinite( s.d )) )
606 s.d = 0.;
607 *(out++) = s.d;
608 in += 8;
612 static int_fast16_t dat12tos16( uint_fast16_t y )
614 static const int16_t diff[16] = {
615 0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
616 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000,
618 static const uint8_t shift[16] = {
619 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0
622 assert(y < 0x1000);
624 int d = y >> 8;
625 return ((int)y - diff[d]) << shift[d];
628 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
630 int16_t *out = outp;
632 while( samples >= 2 )
634 *(out++) = dat12tos16(U16_AT(in) >> 4);
635 *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
636 in += 3;
637 samples -= 2;
640 if( samples )
641 *(out++) = dat12tos16(U16_AT(in) >> 4);
644 /*****************************************************************************
645 * DecoderClose: decoder destruction
646 *****************************************************************************/
647 static void DecoderClose( vlc_object_t *p_this )
649 decoder_t *p_dec = (decoder_t *)p_this;
651 free( p_dec->p_sys );
654 #ifdef ENABLE_SOUT
655 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
656 * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
657 * since decoded audio blocks must always be aligned. */
659 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
661 const uint16_t *in = (const uint16_t *)inp;
662 uint16_t *out = outp;
664 for( size_t i = 0; i < samples; i++ )
665 *(out++) = vlc_bswap16( *(in++) + 0x8000 );
668 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
670 const uint16_t *in = (const uint16_t *)inp;
671 uint16_t *out = outp;
673 for( size_t i = 0; i < samples; i++ )
674 *(out++) = *(in++) + 0x8000;
677 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
679 const uint32_t *in = (const uint32_t *)inp;
680 uint8_t *out = outp;
682 for( size_t i = 0; i < samples; i++ )
684 uint32_t s = *(in++);
685 *(out++) = (s >> 24) + 0x80;
686 *(out++) = (s >> 16);
687 *(out++) = (s >> 8);
691 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
693 const uint32_t *in = (const uint32_t *)inp;
694 uint8_t *out = outp;
696 for( size_t i = 0; i < samples; i++ )
698 uint32_t s = *(in++);
699 *(out++) = (s >> 8);
700 *(out++) = (s >> 16);
701 *(out++) = (s >> 24) + 0x80;
705 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
707 const uint32_t *in = (const uint32_t *)inp;
708 uint8_t *out = outp;
710 for( size_t i = 0; i < samples; i++ )
712 uint32_t s = *(in++);
713 *(out++) = (s >> 24);
714 *(out++) = (s >> 16);
715 *(out++) = (s >> 8);
719 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
721 const uint32_t *in = (const uint32_t *)inp;
722 uint8_t *out = outp;
724 for( size_t i = 0; i < samples; i++ )
726 uint32_t s = *(in++);
727 *(out++) = (s >> 8);
728 *(out++) = (s >> 16);
729 *(out++) = (s >> 24);
733 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
735 const uint32_t *in = (const uint32_t *)inp;
736 uint32_t *out = outp;
738 for( size_t i = 0; i < samples; i++ )
739 *(out++) = vlc_bswap32( *(in++) + 0x80000000 );
742 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
744 const uint32_t *in = (const uint32_t *)inp;
745 uint32_t *out = outp;
747 for( size_t i = 0; i < samples; i++ )
748 *(out++) = *(in++) + 0x80000000;
751 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
753 const int32_t *in = (const int32_t *)inp;
754 int32_t *out = outp;
756 for( size_t i = 0; i < samples; i++ )
757 *(out++) = vlc_bswap32( *(in++) );
760 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
762 const float *in = (const float *)inp;
763 uint8_t *out = outp;
765 for( size_t i = 0; i < samples; i++ )
767 union { float f; uint32_t u; char b[4]; } s;
769 s.f = *(in++);
770 s.u = vlc_bswap32( s.u );
771 memcpy( out, s.b, 4 );
772 out += 4;
776 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
778 const double *in = (const double *)inp;
779 uint8_t *out = outp;
781 for( size_t i = 0; i < samples; i++ )
783 union { double d; uint64_t u; char b[8]; } s;
785 s.d = *(in++);
786 s.u = vlc_bswap64( s.u );
787 memcpy( out, s.b, 8 );
788 out += 8;
792 static block_t *Encode( encoder_t *enc, block_t *in )
794 if( in == NULL )
795 return NULL;
797 block_t *out = block_Alloc( in->i_nb_samples
798 * enc->fmt_out.audio.i_bytes_per_frame );
799 if( unlikely(out == NULL) )
800 return NULL;
802 out->i_flags = in->i_flags;
803 out->i_nb_samples = in->i_nb_samples;
804 out->i_dts = in->i_dts;
805 out->i_pts = in->i_pts;
806 out->i_length = in->i_length;
808 void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
809 if( encode != NULL )
810 encode( out->p_buffer, in->p_buffer, in->i_nb_samples
811 * enc->fmt_out.audio.i_channels );
812 else {
813 assert( out->i_buffer >= in->i_buffer );
814 memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
816 return out;
820 * Probes the PCM audio encoder.
822 static int EncoderOpen( vlc_object_t *p_this )
824 encoder_t *p_enc = (encoder_t *)p_this;
825 void (*encode)(void *, const uint8_t *, unsigned) = NULL;
827 switch( p_enc->fmt_out.i_codec )
829 case VLC_CODEC_S8:
830 encode = S8Decode;
831 /* fall through */
832 case VLC_CODEC_U8:
833 p_enc->fmt_in.i_codec = VLC_CODEC_U8;
834 p_enc->fmt_out.audio.i_bitspersample = 8;
835 break;
836 case VLC_CODEC_U16I:
837 encode = U16IEncode;
838 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
839 p_enc->fmt_out.audio.i_bitspersample = 16;
840 break;
841 case VLC_CODEC_U16N:
842 encode = U16NEncode;
843 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
844 p_enc->fmt_out.audio.i_bitspersample = 16;
845 break;
846 case VLC_CODEC_S16I:
847 encode = S16IDecode;
848 /* fall through */
849 case VLC_CODEC_S16N:
850 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
851 p_enc->fmt_out.audio.i_bitspersample = 16;
852 break;
853 case VLC_CODEC_U24B:
854 encode = U24BEncode;
855 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
856 p_enc->fmt_out.audio.i_bitspersample = 24;
857 break;
858 case VLC_CODEC_U24L:
859 encode = U24LEncode;
860 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
861 p_enc->fmt_out.audio.i_bitspersample = 24;
862 break;
863 case VLC_CODEC_S24B:
864 encode = S24BEncode;
865 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
866 p_enc->fmt_out.audio.i_bitspersample = 24;
867 break;
868 case VLC_CODEC_S24L:
869 encode = S24LEncode;
870 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
871 p_enc->fmt_out.audio.i_bitspersample = 24;
872 break;
873 case VLC_CODEC_U32I:
874 encode = U32IEncode;
875 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
876 p_enc->fmt_out.audio.i_bitspersample = 32;
877 break;
878 case VLC_CODEC_U32N:
879 encode = U32NEncode;
880 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
881 p_enc->fmt_out.audio.i_bitspersample = 32;
882 break;
883 case VLC_CODEC_S32I:
884 encode = S32IEncode;
885 /* fall through */
886 case VLC_CODEC_S32N:
887 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
888 p_enc->fmt_out.audio.i_bitspersample = 32;
889 break;
890 #ifdef WORDS_BIGENDIAN
891 case VLC_CODEC_F32L:
892 #else
893 case VLC_CODEC_F32B:
894 #endif
895 encode = F32IEncode;
896 /* fall through */
897 case VLC_CODEC_FL32:
898 p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
899 p_enc->fmt_out.audio.i_bitspersample = 32;
900 break;
901 #ifdef WORDS_BIGENDIAN
902 case VLC_CODEC_F64L:
903 #else
904 case VLC_CODEC_F64B:
905 #endif
906 encode = F64IEncode;
907 /* fall through */
908 case VLC_CODEC_FL64:
909 p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
910 p_enc->fmt_out.audio.i_bitspersample = 64;
911 break;
912 default:
913 return VLC_EGENERIC;
916 p_enc->p_sys = (void *)encode;
917 p_enc->pf_encode_audio = Encode;
918 p_enc->fmt_out.audio.i_bytes_per_frame =
919 (p_enc->fmt_out.audio.i_bitspersample / 8) *
920 p_enc->fmt_in.audio.i_channels;
921 p_enc->fmt_out.i_bitrate =
922 p_enc->fmt_in.audio.i_channels *
923 p_enc->fmt_in.audio.i_rate *
924 p_enc->fmt_out.audio.i_bitspersample;
926 msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
927 p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
928 p_enc->fmt_out.audio.i_bitspersample );
930 return VLC_SUCCESS;
932 #endif /* ENABLE_SOUT */