1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VLC authors and VideoLAN
5 * $Id: 0d8145527a02fbc18f478a1b76736e4e769595db $
6 *
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 *
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.
13 *
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.
18 *
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 *****************************************************************************/
23
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <math.h>
32 #include <assert.h>
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_aout.h>
38
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 static int DecoderOpen ( vlc_object_t * );
43 static void DecoderClose( vlc_object_t * );
44
45 #ifdef ENABLE_SOUT
46 static int EncoderOpen ( vlc_object_t * );
47 #endif
48
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 )
56
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 ()
65
66 /*****************************************************************************
67 * Local prototypes
68 *****************************************************************************/
69 static int DecodeBlock( decoder_t *, block_t * );
70 static void Flush( decoder_t * );
71
72 struct decoder_sys_t
73 {
74 void (*decode) (void *, const uint8_t *, unsigned);
75 size_t framebits;
76 date_t end_date;
77 };
78
79 static const uint16_t pi_channels_maps[] =
80 {
81 0,
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,
85 };
86 static_assert( ARRAY_SIZE( pi_channels_maps ) - 1 <= AOUT_CHAN_MAX,
87 "channel count mismatch" );
88
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 );
108
109 /*****************************************************************************
110 * DecoderOpen: probe the decoder and return score
111 *****************************************************************************/
DecoderOpen(vlc_object_t * p_this)112 static int DecoderOpen( vlc_object_t *p_this )
113 {
114 decoder_t *p_dec = (decoder_t*)p_this;
115 vlc_fourcc_t format = p_dec->fmt_in.i_codec;
116
117 switch( p_dec->fmt_in.i_codec )
118 {
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 )
129 {
130 msg_Err( p_dec, "bad parameters(bits/sample)" );
131 return VLC_EGENERIC;
132 }
133 break;
134 }
135
136 void (*decode) (void *, const uint8_t *, unsigned) = NULL;
137 uint_fast8_t bits;
138
139 switch( format )
140 {
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;
250 }
251
252 if( p_dec->fmt_in.audio.i_channels == 0 ||
253 p_dec->fmt_in.audio.i_channels > INPUT_CHAN_MAX )
254 {
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;
258 }
259
260 if( p_dec->fmt_in.audio.i_rate == 0 || p_dec->fmt_in.audio.i_rate > 384000 )
261 {
262 msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
263 return VLC_EGENERIC;
264 }
265
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 );
269
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;
274
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 )
281 {
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];
288 }
289 else
290 {
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;
294 }
295 aout_FormatPrepare( &p_dec->fmt_out.audio );
296
297 p_sys->decode = decode;
298 p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
299 assert( p_sys->framebits );
300
301 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
302 date_Set( &p_sys->end_date, 0 );
303
304 p_dec->pf_decode = DecodeBlock;
305 p_dec->pf_flush = Flush;
306 p_dec->p_sys = p_sys;
307
308 return VLC_SUCCESS;
309 }
310
311 /*****************************************************************************
312 * Flush:
313 *****************************************************************************/
Flush(decoder_t * p_dec)314 static void Flush( decoder_t *p_dec )
315 {
316 decoder_sys_t *p_sys = p_dec->p_sys;
317
318 date_Set( &p_sys->end_date, 0 );
319 }
320
321 /****************************************************************************
322 * DecodeBlock: the whole thing
323 ****************************************************************************
324 * This function must be fed with whole samples (see nBlockAlign).
325 ****************************************************************************/
DecodeBlock(decoder_t * p_dec,block_t * p_block)326 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
327 {
328 decoder_sys_t *p_sys = p_dec->p_sys;
329 if( p_block == NULL ) /* No Drain */
330 return VLCDEC_SUCCESS;
331
332 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
333 {
334 Flush( p_dec );
335 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
336 goto skip;
337 }
338
339 if( p_block->i_pts > VLC_TS_INVALID &&
340 p_block->i_pts != date_Get( &p_sys->end_date ) )
341 {
342 date_Set( &p_sys->end_date, p_block->i_pts );
343 }
344 else if( !date_Get( &p_sys->end_date ) )
345 /* We've just started the stream, wait for the first PTS. */
346 goto skip;
347
348 unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
349 if( samples == 0 )
350 goto skip;
351
352 if( p_sys->decode != NULL )
353 {
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;
359
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;
364 }
365 else
366 {
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);
371 }
372
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;
381 }
382
S8Decode(void * outp,const uint8_t * in,unsigned samples)383 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
384 {
385 uint8_t *out = outp;
386
387 for( size_t i = 0; i < samples; i++ )
388 out[i] = in[i] ^ 0x80;
389 }
390
U16BDecode(void * outp,const uint8_t * in,unsigned samples)391 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
392 {
393 uint16_t *out = outp;
394
395 for( size_t i = 0; i < samples; i++ )
396 {
397 *(out++) = GetWBE( in ) - 0x8000;
398 in += 2;
399 }
400 }
401
U16LDecode(void * outp,const uint8_t * in,unsigned samples)402 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
403 {
404 uint16_t *out = outp;
405
406 for( size_t i = 0; i < samples; i++ )
407 {
408 *(out++) = GetWLE( in ) - 0x8000;
409 in += 2;
410 }
411 }
412
S16IDecode(void * out,const uint8_t * in,unsigned samples)413 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
414 {
415 swab( in, out, samples * 2 );
416 }
417
S20BDecode(void * outp,const uint8_t * in,unsigned samples)418 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
419 {
420 int32_t *out = outp;
421
422 while( samples >= 2 )
423 {
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;
430 }
431
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);
435 }
436
U24BDecode(void * outp,const uint8_t * in,unsigned samples)437 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
438 {
439 uint32_t *out = outp;
440
441 for( size_t i = 0; i < samples; i++ )
442 {
443 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
444 *(out++) = s;
445 in += 3;
446 }
447 }
448
U24LDecode(void * outp,const uint8_t * in,unsigned samples)449 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
450 {
451 uint32_t *out = outp;
452
453 for( size_t i = 0; i < samples; i++ )
454 {
455 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
456 *(out++) = s;
457 in += 3;
458 }
459 }
460
S24BDecode(void * outp,const uint8_t * in,unsigned samples)461 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
462 {
463 uint32_t *out = outp;
464
465 for( size_t i = 0; i < samples; i++ )
466 {
467 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
468 *(out++) = s;
469 in += 3;
470 }
471 }
472
S24LDecode(void * outp,const uint8_t * in,unsigned samples)473 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
474 {
475 uint32_t *out = outp;
476
477 for( size_t i = 0; i < samples; i++ )
478 {
479 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
480 *(out++) = s;
481 in += 3;
482 }
483 }
484
S24B32Decode(void * outp,const uint8_t * in,unsigned samples)485 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
486 {
487 uint32_t *out = outp;
488
489 for( size_t i = 0; i < samples; i++ )
490 {
491 *(out++) = GetDWBE( in ) << 8;
492 in += 4;
493 }
494 }
495
S24L32Decode(void * outp,const uint8_t * in,unsigned samples)496 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
497 {
498 uint32_t *out = outp;
499
500 for( size_t i = 0; i < samples; i++ )
501 {
502 *(out++) = GetDWLE( in ) << 8;
503 in += 4;
504 }
505 }
506
U32BDecode(void * outp,const uint8_t * in,unsigned samples)507 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
508 {
509 uint32_t *out = outp;
510
511 for( size_t i = 0; i < samples; i++ )
512 {
513 *(out++) = GetDWBE( in ) - 0x80000000;
514 in += 4;
515 }
516 }
517
U32LDecode(void * outp,const uint8_t * in,unsigned samples)518 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
519 {
520 uint32_t *out = outp;
521
522 for( size_t i = 0; i < samples; i++ )
523 {
524 *(out++) = GetDWLE( in ) - 0x80000000;
525 in += 4;
526 }
527 }
528
S32IDecode(void * outp,const uint8_t * in,unsigned samples)529 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
530 {
531 int32_t *out = outp;
532
533 for( size_t i = 0; i < samples; i++ )
534 {
535 #ifdef WORDS_BIGENDIAN
536 *(out++) = GetDWLE( in );
537 #else
538 *(out++) = GetDWBE( in );
539 #endif
540 in += 4;
541 }
542 }
543
F32NDecode(void * outp,const uint8_t * in,unsigned samples)544 static void F32NDecode( void *outp, const uint8_t *in, unsigned samples )
545 {
546 float *out = outp;
547
548 for( size_t i = 0; i < samples; i++ )
549 {
550 memcpy( out, in, sizeof(float) );
551 if( unlikely(!isfinite(*out)) )
552 *out = 0.f;
553 out++;
554 in += sizeof(float);
555 }
556 }
557
F32IDecode(void * outp,const uint8_t * in,unsigned samples)558 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
559 {
560 float *out = outp;
561
562 for( size_t i = 0; i < samples; i++ )
563 {
564 union { float f; uint32_t u; } s;
565
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;
575 }
576 }
577
F64NDecode(void * outp,const uint8_t * in,unsigned samples)578 static void F64NDecode( void *outp, const uint8_t *in, unsigned samples )
579 {
580 double *out = outp;
581
582 for( size_t i = 0; i < samples; i++ )
583 {
584 memcpy( out, in, sizeof(double) );
585 if( unlikely(!isfinite( *out )) )
586 *out = 0.;
587 out++;
588 in += sizeof(double);
589 }
590 }
591
F64IDecode(void * outp,const uint8_t * in,unsigned samples)592 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
593 {
594 double *out = outp;
595
596 for( size_t i = 0; i < samples; i++ )
597 {
598 union { double d; uint64_t u; } s;
599
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;
609 }
610 }
611
dat12tos16(uint_fast16_t y)612 static int_fast16_t dat12tos16( uint_fast16_t y )
613 {
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,
617 };
618 static const uint8_t shift[16] = {
619 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0
620 };
621
622 assert(y < 0x1000);
623
624 int d = y >> 8;
625 return ((int)y - diff[d]) << shift[d];
626 }
627
DAT12Decode(void * outp,const uint8_t * in,unsigned samples)628 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
629 {
630 int16_t *out = outp;
631
632 while( samples >= 2 )
633 {
634 *(out++) = dat12tos16(U16_AT(in) >> 4);
635 *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
636 in += 3;
637 samples -= 2;
638 }
639
640 if( samples )
641 *(out++) = dat12tos16(U16_AT(in) >> 4);
642 }
643
644 /*****************************************************************************
645 * DecoderClose: decoder destruction
646 *****************************************************************************/
DecoderClose(vlc_object_t * p_this)647 static void DecoderClose( vlc_object_t *p_this )
648 {
649 decoder_t *p_dec = (decoder_t *)p_this;
650
651 free( p_dec->p_sys );
652 }
653
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. */
658
U16IEncode(void * outp,const uint8_t * inp,unsigned samples)659 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
660 {
661 const uint16_t *in = (const uint16_t *)inp;
662 uint16_t *out = outp;
663
664 for( size_t i = 0; i < samples; i++ )
665 *(out++) = bswap16( *(in++) + 0x8000 );
666 }
667
U16NEncode(void * outp,const uint8_t * inp,unsigned samples)668 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
669 {
670 const uint16_t *in = (const uint16_t *)inp;
671 uint16_t *out = outp;
672
673 for( size_t i = 0; i < samples; i++ )
674 *(out++) = *(in++) + 0x8000;
675 }
676
U24BEncode(void * outp,const uint8_t * inp,unsigned samples)677 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
678 {
679 const uint32_t *in = (const uint32_t *)inp;
680 uint8_t *out = outp;
681
682 for( size_t i = 0; i < samples; i++ )
683 {
684 uint32_t s = *(in++);
685 *(out++) = (s >> 24) + 0x80;
686 *(out++) = (s >> 16);
687 *(out++) = (s >> 8);
688 }
689 }
690
U24LEncode(void * outp,const uint8_t * inp,unsigned samples)691 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
692 {
693 const uint32_t *in = (const uint32_t *)inp;
694 uint8_t *out = outp;
695
696 for( size_t i = 0; i < samples; i++ )
697 {
698 uint32_t s = *(in++);
699 *(out++) = (s >> 8);
700 *(out++) = (s >> 16);
701 *(out++) = (s >> 24) + 0x80;
702 }
703 }
704
S24BEncode(void * outp,const uint8_t * inp,unsigned samples)705 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
706 {
707 const uint32_t *in = (const uint32_t *)inp;
708 uint8_t *out = outp;
709
710 for( size_t i = 0; i < samples; i++ )
711 {
712 uint32_t s = *(in++);
713 *(out++) = (s >> 24);
714 *(out++) = (s >> 16);
715 *(out++) = (s >> 8);
716 }
717 }
718
S24LEncode(void * outp,const uint8_t * inp,unsigned samples)719 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
720 {
721 const uint32_t *in = (const uint32_t *)inp;
722 uint8_t *out = outp;
723
724 for( size_t i = 0; i < samples; i++ )
725 {
726 uint32_t s = *(in++);
727 *(out++) = (s >> 8);
728 *(out++) = (s >> 16);
729 *(out++) = (s >> 24);
730 }
731 }
732
U32IEncode(void * outp,const uint8_t * inp,unsigned samples)733 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
734 {
735 const uint32_t *in = (const uint32_t *)inp;
736 uint32_t *out = outp;
737
738 for( size_t i = 0; i < samples; i++ )
739 *(out++) = bswap32( *(in++) + 0x80000000 );
740 }
741
U32NEncode(void * outp,const uint8_t * inp,unsigned samples)742 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
743 {
744 const uint32_t *in = (const uint32_t *)inp;
745 uint32_t *out = outp;
746
747 for( size_t i = 0; i < samples; i++ )
748 *(out++) = *(in++) + 0x80000000;
749 }
750
S32IEncode(void * outp,const uint8_t * inp,unsigned samples)751 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
752 {
753 const int32_t *in = (const int32_t *)inp;
754 int32_t *out = outp;
755
756 for( size_t i = 0; i < samples; i++ )
757 *(out++) = bswap32( *(in++) );
758 }
759
F32IEncode(void * outp,const uint8_t * inp,unsigned samples)760 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
761 {
762 const float *in = (const float *)inp;
763 uint8_t *out = outp;
764
765 for( size_t i = 0; i < samples; i++ )
766 {
767 union { float f; uint32_t u; char b[4]; } s;
768
769 s.f = *(in++);
770 s.u = bswap32( s.u );
771 memcpy( out, s.b, 4 );
772 out += 4;
773 }
774 }
775
F64IEncode(void * outp,const uint8_t * inp,unsigned samples)776 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
777 {
778 const double *in = (const double *)inp;
779 uint8_t *out = outp;
780
781 for( size_t i = 0; i < samples; i++ )
782 {
783 union { double d; uint64_t u; char b[8]; } s;
784
785 s.d = *(in++);
786 s.u = bswap64( s.u );
787 memcpy( out, s.b, 8 );
788 out += 8;
789 }
790 }
791
Encode(encoder_t * enc,block_t * in)792 static block_t *Encode( encoder_t *enc, block_t *in )
793 {
794 if( in == NULL )
795 return NULL;
796
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;
801
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;
807
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 );
815 }
816 return out;
817 }
818
819 /**
820 * Probes the PCM audio encoder.
821 */
EncoderOpen(vlc_object_t * p_this)822 static int EncoderOpen( vlc_object_t *p_this )
823 {
824 encoder_t *p_enc = (encoder_t *)p_this;
825 void (*encode)(void *, const uint8_t *, unsigned) = NULL;
826
827 switch( p_enc->fmt_out.i_codec )
828 {
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;
914 }
915
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;
925
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 );
929
930 return VLC_SUCCESS;
931 }
932 #endif /* ENABLE_SOUT */
933