1#![warn(rust_2018_idioms)]
9#![forbid(unsafe_code)]
10#![allow(clippy::comparison_chain)]
13#![allow(clippy::excessive_precision)]
14#![allow(clippy::identity_op)]
15#![allow(clippy::manual_range_contains)]
16
17use symphonia_core::support_codec;
18
19use symphonia_core::audio::{AsAudioBufferRef, AudioBuffer, AudioBufferRef, Signal, SignalSpec};
20use symphonia_core::codecs::{CodecDescriptor, CodecParameters, CodecType};
21use symphonia_core::codecs::{Decoder, DecoderOptions, FinalizeResult};
22use symphonia_core::codecs::{CODEC_TYPE_PCM_S16BE, CODEC_TYPE_PCM_S24BE, CODEC_TYPE_PCM_S32BE};
24use symphonia_core::codecs::{CODEC_TYPE_PCM_S16LE, CODEC_TYPE_PCM_S8};
25use symphonia_core::codecs::{CODEC_TYPE_PCM_S24LE, CODEC_TYPE_PCM_S32LE};
26use symphonia_core::codecs::{CODEC_TYPE_PCM_U16BE, CODEC_TYPE_PCM_U24BE, CODEC_TYPE_PCM_U32BE};
28use symphonia_core::codecs::{CODEC_TYPE_PCM_U16LE, CODEC_TYPE_PCM_U8};
29use symphonia_core::codecs::{CODEC_TYPE_PCM_U24LE, CODEC_TYPE_PCM_U32LE};
30use symphonia_core::codecs::{CODEC_TYPE_PCM_F32BE, CODEC_TYPE_PCM_F32LE};
32use symphonia_core::codecs::{CODEC_TYPE_PCM_F64BE, CODEC_TYPE_PCM_F64LE};
33use symphonia_core::codecs::{CODEC_TYPE_PCM_ALAW, CODEC_TYPE_PCM_MULAW};
35use symphonia_core::conv::IntoSample;
36use symphonia_core::errors::{decode_error, unsupported_error, Result};
37use symphonia_core::formats::Packet;
38use symphonia_core::io::ReadBytes;
39use symphonia_core::sample::{i24, u24, SampleFormat};
40use symphonia_core::units::Duration;
41
42macro_rules! impl_generic_audio_buffer_func {
43 ($generic:expr, $buf:ident, $expr:expr) => {
44 match $generic {
45 GenericAudioBuffer::U8($buf) => $expr,
46 GenericAudioBuffer::U16($buf) => $expr,
47 GenericAudioBuffer::U24($buf) => $expr,
48 GenericAudioBuffer::U32($buf) => $expr,
49 GenericAudioBuffer::S8($buf) => $expr,
50 GenericAudioBuffer::S16($buf) => $expr,
51 GenericAudioBuffer::S24($buf) => $expr,
52 GenericAudioBuffer::S32($buf) => $expr,
53 GenericAudioBuffer::F32($buf) => $expr,
54 GenericAudioBuffer::F64($buf) => $expr,
55 }
56 };
57}
58
59pub enum GenericAudioBuffer {
62 U8(AudioBuffer<u8>),
63 U16(AudioBuffer<u16>),
64 U24(AudioBuffer<u24>),
65 U32(AudioBuffer<u32>),
66 S8(AudioBuffer<i8>),
67 S16(AudioBuffer<i16>),
68 S24(AudioBuffer<i24>),
69 S32(AudioBuffer<i32>),
70 F32(AudioBuffer<f32>),
71 F64(AudioBuffer<f64>),
72}
73
74impl GenericAudioBuffer {
75 fn new(format: SampleFormat, duration: Duration, spec: SignalSpec) -> Self {
76 match format {
77 SampleFormat::U8 => GenericAudioBuffer::U8(AudioBuffer::new(duration, spec)),
78 SampleFormat::U16 => GenericAudioBuffer::U16(AudioBuffer::new(duration, spec)),
79 SampleFormat::U24 => GenericAudioBuffer::U24(AudioBuffer::new(duration, spec)),
80 SampleFormat::U32 => GenericAudioBuffer::U32(AudioBuffer::new(duration, spec)),
81 SampleFormat::S8 => GenericAudioBuffer::S8(AudioBuffer::new(duration, spec)),
82 SampleFormat::S16 => GenericAudioBuffer::S16(AudioBuffer::new(duration, spec)),
83 SampleFormat::S24 => GenericAudioBuffer::S24(AudioBuffer::new(duration, spec)),
84 SampleFormat::S32 => GenericAudioBuffer::S32(AudioBuffer::new(duration, spec)),
85 SampleFormat::F32 => GenericAudioBuffer::F32(AudioBuffer::new(duration, spec)),
86 SampleFormat::F64 => GenericAudioBuffer::F64(AudioBuffer::new(duration, spec)),
87 }
88 }
89
90 fn clear(&mut self) {
91 impl_generic_audio_buffer_func!(self, buf, buf.clear());
92 }
93}
94
95impl AsAudioBufferRef for GenericAudioBuffer {
96 fn as_audio_buffer_ref(&self) -> AudioBufferRef<'_> {
97 impl_generic_audio_buffer_func!(self, buf, buf.as_audio_buffer_ref())
98 }
99}
100
101macro_rules! read_pcm_signed {
102 ($buf:expr, $fmt:tt, $read:expr, $width:expr, $coded_width:expr) => {
103 match $buf {
105 GenericAudioBuffer::$fmt(ref mut buf) => {
106 let shift = $width - $coded_width;
108 buf.fill(|audio_planes, idx| -> Result<()> {
109 for plane in audio_planes.planes() {
110 plane[idx] = ($read << shift).into_sample();
111 }
112 Ok(())
113 })
114 }
115 _ => unreachable!(),
116 }
117 };
118}
119
120macro_rules! read_pcm_unsigned {
121 ($buf:expr, $fmt:tt, $read:expr, $width:expr, $coded_width:expr) => {
122 match $buf {
124 GenericAudioBuffer::$fmt(ref mut buf) => {
125 let shift = $width - $coded_width;
127 buf.fill(|audio_planes, idx| -> Result<()> {
128 for plane in audio_planes.planes() {
129 plane[idx] = ($read << shift).into_sample();
130 }
131 Ok(())
132 })
133 }
134 _ => unreachable!(),
135 }
136 };
137}
138
139macro_rules! read_pcm_floating {
140 ($buf:expr, $fmt:tt, $read:expr) => {
141 match $buf {
143 GenericAudioBuffer::$fmt(ref mut buf) => {
144 buf.fill(|audio_planes, idx| -> Result<()> {
146 for plane in audio_planes.planes() {
147 plane[idx] = $read;
148 }
149 Ok(())
150 })
151 }
152 _ => unreachable!(),
153 }
154 };
155}
156
157macro_rules! read_pcm_transfer_func {
158 ($buf:expr, $fmt:tt, $func:expr) => {
159 match $buf {
161 GenericAudioBuffer::$fmt(ref mut buf) => {
162 buf.fill(|audio_planes, idx| -> Result<()> {
164 for plane in audio_planes.planes() {
165 plane[idx] = $func;
166 }
167 Ok(())
168 })
169 }
170 _ => unreachable!(),
171 }
172 };
173}
174
175const XLAW_QUANT_MASK: u8 = 0x0f;
204const XLAW_SEG_MASK: u8 = 0x70;
205const XLAW_SEG_SHIFT: u32 = 4;
206
207fn alaw_to_linear(mut a_val: u8) -> i16 {
208 a_val ^= 0x55;
209
210 let mut t = i16::from((a_val & XLAW_QUANT_MASK) << 4);
211 let seg = (a_val & XLAW_SEG_MASK) >> XLAW_SEG_SHIFT;
212
213 match seg {
214 0 => t += 0x8,
215 1 => t += 0x108,
216 _ => t = (t + 0x108) << (seg - 1),
217 }
218
219 if a_val & 0x80 == 0x80 {
220 t
221 }
222 else {
223 -t
224 }
225}
226
227fn mulaw_to_linear(mut mu_val: u8) -> i16 {
228 const BIAS: i16 = 0x84;
229
230 mu_val = !mu_val;
232
233 let mut t = i16::from((mu_val & XLAW_QUANT_MASK) << 3) + BIAS;
236 t <<= (mu_val & XLAW_SEG_MASK) >> XLAW_SEG_SHIFT;
237
238 if mu_val & 0x80 == 0x80 {
239 BIAS - t
240 }
241 else {
242 t - BIAS
243 }
244}
245
246fn is_supported_pcm_codec(codec_type: CodecType) -> bool {
247 matches!(
248 codec_type,
249 CODEC_TYPE_PCM_S32LE
250 | CODEC_TYPE_PCM_S32BE
251 | CODEC_TYPE_PCM_S24LE
252 | CODEC_TYPE_PCM_S24BE
253 | CODEC_TYPE_PCM_S16LE
254 | CODEC_TYPE_PCM_S16BE
255 | CODEC_TYPE_PCM_S8
256 | CODEC_TYPE_PCM_U32LE
257 | CODEC_TYPE_PCM_U32BE
258 | CODEC_TYPE_PCM_U24LE
259 | CODEC_TYPE_PCM_U24BE
260 | CODEC_TYPE_PCM_U16LE
261 | CODEC_TYPE_PCM_U16BE
262 | CODEC_TYPE_PCM_U8
263 | CODEC_TYPE_PCM_F32LE
264 | CODEC_TYPE_PCM_F32BE
265 | CODEC_TYPE_PCM_F64LE
266 | CODEC_TYPE_PCM_F64BE
267 | CODEC_TYPE_PCM_ALAW
268 | CODEC_TYPE_PCM_MULAW
269 )
270}
271
272pub struct PcmDecoder {
274 params: CodecParameters,
275 coded_width: u32,
276 buf: GenericAudioBuffer,
277}
278
279impl PcmDecoder {
280 fn decode_inner(&mut self, packet: &Packet) -> Result<()> {
281 let mut reader = packet.as_buf_reader();
282
283 let _ = match self.params.codec {
284 CODEC_TYPE_PCM_S32LE => {
285 read_pcm_signed!(self.buf, S32, reader.read_i32()?, 32, self.coded_width)
286 }
287 CODEC_TYPE_PCM_S32BE => {
288 read_pcm_signed!(self.buf, S32, reader.read_be_i32()?, 32, self.coded_width)
289 }
290 CODEC_TYPE_PCM_S24LE => {
291 read_pcm_signed!(self.buf, S24, reader.read_i24()? << 8, 24, self.coded_width)
292 }
293 CODEC_TYPE_PCM_S24BE => {
294 read_pcm_signed!(self.buf, S24, reader.read_be_i24()? << 8, 24, self.coded_width)
295 }
296 CODEC_TYPE_PCM_S16LE => {
297 read_pcm_signed!(self.buf, S16, reader.read_i16()?, 16, self.coded_width)
298 }
299 CODEC_TYPE_PCM_S16BE => {
300 read_pcm_signed!(self.buf, S16, reader.read_be_i16()?, 16, self.coded_width)
301 }
302 CODEC_TYPE_PCM_S8 => {
303 read_pcm_signed!(self.buf, S8, reader.read_i8()?, 8, self.coded_width)
304 }
305 CODEC_TYPE_PCM_U32LE => {
306 read_pcm_unsigned!(self.buf, U32, reader.read_u32()?, 32, self.coded_width)
307 }
308 CODEC_TYPE_PCM_U32BE => {
309 read_pcm_unsigned!(self.buf, U32, reader.read_be_u32()?, 32, self.coded_width)
310 }
311 CODEC_TYPE_PCM_U24LE => {
312 read_pcm_unsigned!(self.buf, U24, reader.read_u24()? << 8, 24, self.coded_width)
313 }
314 CODEC_TYPE_PCM_U24BE => {
315 read_pcm_unsigned!(self.buf, U24, reader.read_be_u24()? << 8, 24, self.coded_width)
316 }
317 CODEC_TYPE_PCM_U16LE => {
318 read_pcm_unsigned!(self.buf, U16, reader.read_u16()?, 16, self.coded_width)
319 }
320 CODEC_TYPE_PCM_U16BE => {
321 read_pcm_unsigned!(self.buf, U16, reader.read_be_u16()?, 16, self.coded_width)
322 }
323 CODEC_TYPE_PCM_U8 => {
324 read_pcm_unsigned!(self.buf, U8, reader.read_u8()?, 8, self.coded_width)
325 }
326 CODEC_TYPE_PCM_F32LE => {
327 read_pcm_floating!(self.buf, F32, reader.read_f32()?)
328 }
329 CODEC_TYPE_PCM_F32BE => {
330 read_pcm_floating!(self.buf, F32, reader.read_be_f32()?)
331 }
332 CODEC_TYPE_PCM_F64LE => {
333 read_pcm_floating!(self.buf, F64, reader.read_f64()?)
334 }
335 CODEC_TYPE_PCM_F64BE => {
336 read_pcm_floating!(self.buf, F64, reader.read_be_f64()?)
337 }
338 CODEC_TYPE_PCM_ALAW => {
339 read_pcm_transfer_func!(self.buf, S16, alaw_to_linear(reader.read_u8()?))
340 }
341 CODEC_TYPE_PCM_MULAW => {
342 read_pcm_transfer_func!(self.buf, S16, mulaw_to_linear(reader.read_u8()?))
343 }
344 _ => unsupported_error("pcm: codec is unsupported"),
363 };
364
365 Ok(())
366 }
367}
368
369impl Decoder for PcmDecoder {
370 fn try_new(params: &CodecParameters, _options: &DecoderOptions) -> Result<Self> {
371 if !is_supported_pcm_codec(params.codec) {
373 return unsupported_error("pcm: invalid codec type");
374 }
375
376 let frames = match params.max_frames_per_packet {
377 Some(frames) => frames,
378 _ => return unsupported_error("pcm: maximum frames per packet is required"),
379 };
380
381 let rate = match params.sample_rate {
382 Some(rate) => rate,
383 _ => return unsupported_error("pcm: sample rate is required"),
384 };
385
386 let spec = if let Some(channels) = params.channels {
387 if channels.count() < 1 {
389 return unsupported_error("pcm: number of channels cannot be 0");
390 }
391
392 SignalSpec::new(rate, channels)
393 }
394 else if let Some(layout) = params.channel_layout {
395 SignalSpec::new_with_layout(rate, layout)
396 }
397 else {
398 return unsupported_error("pcm: channels or channel_layout is required");
399 };
400
401 let (sample_format, sample_format_width) = match params.codec {
403 CODEC_TYPE_PCM_S32LE | CODEC_TYPE_PCM_S32BE => (SampleFormat::S32, 32),
404 CODEC_TYPE_PCM_S24LE | CODEC_TYPE_PCM_S24BE => (SampleFormat::S24, 24),
405 CODEC_TYPE_PCM_S16LE | CODEC_TYPE_PCM_S16BE => (SampleFormat::S16, 16),
406 CODEC_TYPE_PCM_S8 => (SampleFormat::S8, 8),
407 CODEC_TYPE_PCM_U32LE | CODEC_TYPE_PCM_U32BE => (SampleFormat::U32, 32),
408 CODEC_TYPE_PCM_U24LE | CODEC_TYPE_PCM_U24BE => (SampleFormat::U24, 24),
409 CODEC_TYPE_PCM_U16LE | CODEC_TYPE_PCM_U16BE => (SampleFormat::U16, 16),
410 CODEC_TYPE_PCM_U8 => (SampleFormat::U8, 8),
411 CODEC_TYPE_PCM_F32LE | CODEC_TYPE_PCM_F32BE => (SampleFormat::F32, 32),
412 CODEC_TYPE_PCM_F64LE | CODEC_TYPE_PCM_F64BE => (SampleFormat::F64, 64),
413 CODEC_TYPE_PCM_ALAW => (SampleFormat::S16, 16),
414 CODEC_TYPE_PCM_MULAW => (SampleFormat::S16, 16),
415 _ => unreachable!(),
416 };
417
418 let coded_width =
423 params.bits_per_coded_sample.unwrap_or_else(|| params.bits_per_sample.unwrap_or(0));
424
425 if coded_width == 0 {
428 match params.codec {
431 CODEC_TYPE_PCM_F32LE | CODEC_TYPE_PCM_F32BE => (),
432 CODEC_TYPE_PCM_F64LE | CODEC_TYPE_PCM_F64BE => (),
433 CODEC_TYPE_PCM_ALAW | CODEC_TYPE_PCM_MULAW => (),
434 _ => return unsupported_error("pcm: unknown bits per (coded) sample"),
435 }
436 }
437 else if coded_width > sample_format_width {
438 return decode_error("pcm: coded bits per sample is greater than the sample format");
441 }
442
443 let buf = GenericAudioBuffer::new(sample_format, frames, spec);
445
446 Ok(PcmDecoder { params: params.clone(), coded_width, buf })
447 }
448
449 fn supported_codecs() -> &'static [CodecDescriptor] {
450 &[
451 support_codec!(
452 CODEC_TYPE_PCM_S32LE,
453 "pcm_s32le",
454 "PCM Signed 32-bit Little-Endian Interleaved"
455 ),
456 support_codec!(
457 CODEC_TYPE_PCM_S32BE,
458 "pcm_s32be",
459 "PCM Signed 32-bit Big-Endian Interleaved"
460 ),
461 support_codec!(
462 CODEC_TYPE_PCM_S24LE,
463 "pcm_s24le",
464 "PCM Signed 24-bit Little-Endian Interleaved"
465 ),
466 support_codec!(
467 CODEC_TYPE_PCM_S24BE,
468 "pcm_s24be",
469 "PCM Signed 24-bit Big-Endian Interleaved"
470 ),
471 support_codec!(
472 CODEC_TYPE_PCM_S16LE,
473 "pcm_s16le",
474 "PCM Signed 16-bit Little-Endian Interleaved"
475 ),
476 support_codec!(
477 CODEC_TYPE_PCM_S16BE,
478 "pcm_s16be",
479 "PCM Signed 16-bit Big-Endian Interleaved"
480 ),
481 support_codec!(CODEC_TYPE_PCM_S8, "pcm_s8", "PCM Signed 8-bit Interleaved"),
482 support_codec!(
483 CODEC_TYPE_PCM_U32LE,
484 "pcm_u32le",
485 "PCM Unsigned 32-bit Little-Endian Interleaved"
486 ),
487 support_codec!(
488 CODEC_TYPE_PCM_U32BE,
489 "pcm_u32be",
490 "PCM Unsigned 32-bit Big-Endian Interleaved"
491 ),
492 support_codec!(
493 CODEC_TYPE_PCM_U24LE,
494 "pcm_u24le",
495 "PCM Unsigned 24-bit Little-Endian Interleaved"
496 ),
497 support_codec!(
498 CODEC_TYPE_PCM_U24BE,
499 "pcm_u24be",
500 "PCM Unsigned 24-bit Big-Endian Interleaved"
501 ),
502 support_codec!(
503 CODEC_TYPE_PCM_U16LE,
504 "pcm_u16le",
505 "PCM Unsigned 16-bit Little-Endian Interleaved"
506 ),
507 support_codec!(
508 CODEC_TYPE_PCM_U16BE,
509 "pcm_u16be",
510 "PCM Unsigned 16-bit Big-Endian Interleaved"
511 ),
512 support_codec!(CODEC_TYPE_PCM_U8, "pcm_u8", "PCM Unsigned 8-bit Interleaved"),
513 support_codec!(
514 CODEC_TYPE_PCM_F32LE,
515 "pcm_f32le",
516 "PCM 32-bit Little-Endian Floating Point Interleaved"
517 ),
518 support_codec!(
519 CODEC_TYPE_PCM_F32BE,
520 "pcm_f32be",
521 "PCM 32-bit Big-Endian Floating Point Interleaved"
522 ),
523 support_codec!(
524 CODEC_TYPE_PCM_F64LE,
525 "pcm_f64le",
526 "PCM 64-bit Little-Endian Floating Point Interleaved"
527 ),
528 support_codec!(
529 CODEC_TYPE_PCM_F64BE,
530 "pcm_f64be",
531 "PCM 64-bit Big-Endian Floating Point Interleaved"
532 ),
533 support_codec!(CODEC_TYPE_PCM_ALAW, "pcm_alaw", "PCM A-law"),
534 support_codec!(CODEC_TYPE_PCM_MULAW, "pcm_mulaw", "PCM Mu-law"),
535 ]
626 }
627
628 fn reset(&mut self) {
629 }
631
632 fn codec_params(&self) -> &CodecParameters {
633 &self.params
634 }
635
636 fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef<'_>> {
637 if let Err(e) = self.decode_inner(packet) {
638 self.buf.clear();
639 Err(e)
640 }
641 else {
642 Ok(self.buf.as_audio_buffer_ref())
643 }
644 }
645
646 fn finalize(&mut self) -> FinalizeResult {
647 Default::default()
648 }
649
650 fn last_decoded(&self) -> AudioBufferRef<'_> {
651 self.buf.as_audio_buffer_ref()
652 }
653}