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