Skip to main content

audioadapter_sample/
sample.rs

1#![allow(non_camel_case_types)]
2
3use audio_codec_algorithms::{decode_alaw, decode_ulaw, encode_alaw, encode_ulaw};
4use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
5
6// ------ 8-bit integer formats ------
7
8/// 8 bit signed integer. Stored as 1 byte.
9/// A single byte has no byte order,
10/// so there are no little endian and big endian variants.
11#[derive(Debug, Clone, Copy)]
12#[repr(transparent)]
13pub struct I8([u8; 1]);
14
15/// 8 bit unsigned integer. Stored as 1 byte.
16/// A single byte has no byte order,
17/// so there are no little endian and big endian variants.
18#[derive(Debug, Clone, Copy)]
19#[repr(transparent)]
20pub struct U8([u8; 1]);
21
22// ------ 16-bit integer formats ------
23
24/// 16 bit signed integer, little endian. Stored as 2 bytes.
25#[derive(Debug, Clone, Copy)]
26#[repr(transparent)]
27pub struct I16_LE([u8; 2]);
28
29/// 16 bit signed integer, big endian. Stored as 2 bytes.
30#[derive(Debug, Clone, Copy)]
31#[repr(transparent)]
32pub struct I16_BE([u8; 2]);
33
34/// 16 bit unsigned integer, little endian. Stored as 2 bytes.
35#[derive(Debug, Clone, Copy)]
36#[repr(transparent)]
37pub struct U16_LE([u8; 2]);
38
39/// 16 bit unsigned integer, big endian. Stored as 2 bytes.
40#[derive(Debug, Clone, Copy)]
41#[repr(transparent)]
42pub struct U16_BE([u8; 2]);
43
44// ----- 24-bit formats -----
45
46/// 24 bit signed integer, little endian. Stored as 3 bytes.
47#[derive(Debug, Clone, Copy)]
48#[repr(transparent)]
49pub struct I24_LE([u8; 3]);
50
51/// 24 bit signed integer, little endian. Stored as 4 bytes left justified.
52/// The 24 data bits are stored in the three most significant bytes,
53/// while the least significant byte is unused padding.
54#[derive(Debug, Clone, Copy)]
55#[repr(transparent)]
56pub struct I24_4LJ_LE([u8; 4]);
57
58/// 24 bit signed integer, little endian. Stored as 4 bytes right justified.
59/// The 24 data bits are stored in the three least significant bytes,
60/// while the most significant byte is unused padding.
61#[derive(Debug, Clone, Copy)]
62#[repr(transparent)]
63pub struct I24_4RJ_LE([u8; 4]);
64
65/// 24 bit signed integer, big endian. Stored as 3 bytes.
66#[derive(Debug, Clone, Copy)]
67#[repr(transparent)]
68pub struct I24_BE([u8; 3]);
69
70/// 24 bit signed integer, big endian. Stored as 4 bytes left justified.
71/// The 24 data bits are stored in the three most significant bytes,
72/// while the least significant byte is unused padding.
73#[derive(Debug, Clone, Copy)]
74#[repr(transparent)]
75pub struct I24_4LJ_BE([u8; 4]);
76
77/// 24 bit signed integer, big endian. Stored as 4 bytes right justified.
78/// The 24 data bits are stored in the three least significant bytes,
79/// while the most significant byte is unused padding.
80#[derive(Debug, Clone, Copy)]
81#[repr(transparent)]
82pub struct I24_4RJ_BE([u8; 4]);
83
84/// 24 bit unsigned integer, little endian. Stored as 3 bytes.
85#[derive(Debug, Clone, Copy)]
86#[repr(transparent)]
87pub struct U24_LE([u8; 3]);
88
89/// 24 bit unsigned integer, little endian. Stored as 4 bytes left justified.
90/// The 24 data bits are stored in the three most significant bytes,
91/// while the least significant byte is unused padding.
92#[derive(Debug, Clone, Copy)]
93#[repr(transparent)]
94pub struct U24_4LJ_LE([u8; 4]);
95
96/// 24 bit unsigned integer, little endian. Stored as 4 bytes right justified.
97/// The 24 data bits are stored in the three least significant bytes,
98/// while the most significant byte is unused padding.
99#[derive(Debug, Clone, Copy)]
100#[repr(transparent)]
101pub struct U24_4RJ_LE([u8; 4]);
102
103/// 24 bit unsigned integer, big endian. Stored as 3 bytes.
104#[derive(Debug, Clone, Copy)]
105#[repr(transparent)]
106pub struct U24_BE([u8; 3]);
107
108/// 24 bit unsigned integer, big endian. Stored as 4 bytes left justified.
109/// The 24 data bits are stored in the three most significant bytes,
110/// while the least significant byte is unused padding.
111#[derive(Debug, Clone, Copy)]
112#[repr(transparent)]
113pub struct U24_4LJ_BE([u8; 4]);
114
115/// 24 bit unsigned integer, big endian. Stored as 4 bytes right justified.
116/// The 24 data bits are stored in the three least significant bytes,
117/// while the most significant byte is unused padding.
118#[derive(Debug, Clone, Copy)]
119#[repr(transparent)]
120pub struct U24_4RJ_BE([u8; 4]);
121
122// ------ 32-bit integer formats ------
123
124/// 32 bit signed integer, little endian. Stored as 4 bytes.
125#[derive(Debug, Clone, Copy)]
126#[repr(transparent)]
127pub struct I32_LE([u8; 4]);
128
129/// 32 bit signed integer, big endian. Stored as 4 bytes.
130#[derive(Debug, Clone, Copy)]
131#[repr(transparent)]
132pub struct I32_BE([u8; 4]);
133
134/// 32 bit unsigned integer, little endian. Stored as 4 bytes.
135#[derive(Debug, Clone, Copy)]
136#[repr(transparent)]
137pub struct U32_LE([u8; 4]);
138
139/// 32 bit unsigned integer, big endian. Stored as 4 bytes.
140#[derive(Debug, Clone, Copy)]
141#[repr(transparent)]
142pub struct U32_BE([u8; 4]);
143
144// ----- 64-bit integer formats ------
145
146/// 64 bit signed integer, little endian. Stored as 8 bytes.
147#[derive(Debug, Clone, Copy)]
148#[repr(transparent)]
149pub struct I64_LE([u8; 8]);
150
151/// 64 bit signed integer, big endian. Stored as 8 bytes.
152#[derive(Debug, Clone, Copy)]
153#[repr(transparent)]
154pub struct I64_BE([u8; 8]);
155
156/// 64 bit unsigned integer, little endian. Stored as 8 bytes.
157#[derive(Debug, Clone, Copy)]
158#[repr(transparent)]
159pub struct U64_LE([u8; 8]);
160
161/// 64 bit unsigned integer, big endian. Stored as 8 bytes.
162#[derive(Debug, Clone, Copy)]
163#[repr(transparent)]
164pub struct U64_BE([u8; 8]);
165
166// ----- floating point formats -----
167
168/// 32 bit floating point, little endian. Stored as 4 bytes.
169#[derive(Debug, Clone, Copy)]
170#[repr(transparent)]
171pub struct F32_LE([u8; 4]);
172
173/// 32 bit floating point, big endian. Stored as 4 bytes.
174#[derive(Debug, Clone, Copy)]
175#[repr(transparent)]
176pub struct F32_BE([u8; 4]);
177
178/// 64 bit floating point, little endian. Stored as 8 bytes.
179#[derive(Debug, Clone, Copy)]
180#[repr(transparent)]
181pub struct F64_LE([u8; 8]);
182
183/// 64 bit floating point, big endian. Stored as 8 bytes.
184#[derive(Debug, Clone, Copy)]
185#[repr(transparent)]
186pub struct F64_BE([u8; 8]);
187
188// ----- G.711 companded formats -----
189
190/// A-law companded sample, as defined by ITU-T G.711. Stored as 1 byte.
191/// A single byte has no byte order,
192/// so there are no little endian and big endian variants.
193///
194/// A-law fits the dynamic range of a 13 bit linear value into 8 bits,
195/// using a piecewise linear approximation of a logarithmic curve.
196/// The closest numeric type is [i16], and the decoded values are scaled
197/// to that range. The largest representable magnitude is 32256,
198/// so the range does not quite reach the limits of an [i16].
199/// A-law has no code for exact silence, the two smallest magnitudes
200/// are +8 and -8.
201///
202/// Note that [i16] is wider than the 256 values this format can represent,
203/// so unlike the linear formats, [`from_number`](BytesSample::from_number)
204/// quantizes and a number does not survive a roundtrip unchanged.
205/// Quantizing an already quantized value changes nothing further.
206///
207/// Note that a byte value of zero is not silence. It decodes to -5504.
208/// The A-law code for the smallest positive value is `0xD5`.
209///
210/// This is the format used for telephony in Europe and most of the world.
211/// It appears as `WAVE_FORMAT_ALAW` in wav files, as `PCMA` in RTP streams,
212/// and as `SND_PCM_FORMAT_A_LAW` in ALSA.
213#[derive(Debug, Clone, Copy)]
214#[repr(transparent)]
215pub struct ALAW([u8; 1]);
216
217/// Mu-law companded sample, as defined by ITU-T G.711. Stored as 1 byte.
218/// A single byte has no byte order,
219/// so there are no little endian and big endian variants.
220///
221/// Mu-law fits the dynamic range of a 14 bit linear value into 8 bits,
222/// using a piecewise linear approximation of a logarithmic curve.
223/// The closest numeric type is [i16], and the decoded values are scaled
224/// to that range. The largest representable magnitude is 32124,
225/// so the range does not quite reach the limits of an [i16].
226///
227/// Note that [i16] is wider than the 256 values this format can represent,
228/// so unlike the linear formats, [`from_number`](BytesSample::from_number)
229/// quantizes and a number does not survive a roundtrip unchanged.
230/// Quantizing an already quantized value changes nothing further.
231///
232/// Note that a byte value of zero is not silence. It decodes to -32124.
233/// The mu-law code for silence is `0xFF`.
234///
235/// This is the format used for telephony in North America and Japan.
236/// It appears as `WAVE_FORMAT_MULAW` in wav files, as `PCMU` in RTP streams,
237/// and as `SND_PCM_FORMAT_MU_LAW` in ALSA.
238#[derive(Debug, Clone, Copy)]
239#[repr(transparent)]
240pub struct MULAW([u8; 1]);
241
242/// Convert a float to an integer, clamp at the min and max limits of the integer.
243fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
244    value: T,
245    converted: Option<U>,
246) -> ConversionResult<U> {
247    if let Some(val) = converted {
248        return ConversionResult {
249            clipped: false,
250            value: val,
251        };
252    }
253    if value.is_nan() {
254        return ConversionResult {
255            clipped: true,
256            value: U::zero(),
257        };
258    }
259    if value > T::zero() {
260        return ConversionResult {
261            clipped: true,
262            value: U::max_value(),
263        };
264    }
265    ConversionResult {
266        clipped: true,
267        value: U::min_value(),
268    }
269}
270
271/// A conversion result, containing the resulting value as `value`
272/// and a boolean `clipped` indicating if the value was clipped during conversion.
273pub struct ConversionResult<T> {
274    pub clipped: bool,
275    pub value: T,
276}
277
278/// A trait for converting a given sample type to and from floating point values.
279/// The floating point values use the range -1.0 to +1.0.
280/// When converting to/from signed integers, the range does not include +1.0.
281/// For example, an 8-bit signed integer supports the range -128 to +127.
282/// When these values are converted to float, 0 becomes 0.0,
283/// -128 becomes -1.0, and 127 becomes 127/128 ≈ 0.992.
284/// Unsigned integers are also converted to the same -1.0 to +1.0 range.
285/// For an 8-but unsigned integer, 128 is the center point and becomes 0.0.
286/// The value 0 becomes -1.0, and 255 becomes 127/128 ≈ 0.992.
287pub trait RawSample
288where
289    Self: Sized,
290{
291    /// Convert the sample value to a float in the range -1.0 .. +1.0.
292    fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
293
294    /// Convert a float in the range -1.0 .. +1.0 to a sample value.
295    ///
296    /// For integer formats, values outside the allowed range are clipped to the
297    /// nearest limit and the returned `clipped` flag is set.
298    /// Floating point formats are not range-limited: values outside -1.0 .. +1.0
299    /// are valid headroom, are passed through unchanged, and never set `clipped`.
300    fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
301}
302
303/// A trait for converting samples stored as raw bytes into a numerical type.
304/// Each implementation defines the associated type `NumericType`,
305/// which is the nearest matching numeric type for the original format.
306/// If a direct match exists, this is used.
307/// For example signed 16 bit integer samples use [i16].
308/// For formats that don't have a direct match,
309/// the next larger numeric type is used.
310/// For example for 24 bit signed integers,
311/// this means [i32].
312/// The values are scaled to use the full range of the `NumericType`
313/// associated type.
314pub trait BytesSample {
315    /// The closest matching numeric type.
316    type NumericType: Copy;
317
318    /// The number of bytes making up each sample value.
319    const BYTES_PER_SAMPLE: usize;
320
321    /// Create a sample with all bytes set to zero.
322    ///
323    /// This gives a correctly sized, valid value whose bytes can then be
324    /// overwritten, for example via [`as_mut_slice`](Self::as_mut_slice) when
325    /// reading from a stream.
326    fn zero() -> Self;
327
328    /// Create a new ByteSample from a slice of raw bytes.
329    /// The slice length must be at least the number of bytes
330    /// for a sample value.
331    fn from_slice(bytes: &[u8]) -> Self;
332
333    /// Return the raw bytes as a slice.
334    fn as_slice(&self) -> &[u8];
335
336    /// Return the raw bytes as a mutable slice.
337    fn as_mut_slice(&mut self) -> &mut [u8];
338
339    /// Convert the raw bytes to a numerical value.
340    fn to_number(&self) -> Self::NumericType;
341
342    /// Convert a numerical value to raw bytes.
343    fn from_number(value: Self::NumericType) -> Self;
344}
345
346macro_rules! rawsample_for_int {
347    ($type:ident, $to:ident) => {
348        impl RawSample for $type {
349            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
350                T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
351            }
352
353            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
354                let scaled = value * (T::from($type::MAX).unwrap() + T::one());
355                let converted = scaled.$to();
356                to_clamped_int(scaled, converted)
357            }
358        }
359    };
360}
361
362rawsample_for_int!(i8, to_i8);
363rawsample_for_int!(i16, to_i16);
364rawsample_for_int!(i32, to_i32);
365rawsample_for_int!(i64, to_i64);
366
367macro_rules! rawsample_for_uint {
368    ($type:ident, $to:ident) => {
369        impl RawSample for $type {
370            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
371                let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
372                (T::from(*self).unwrap() - max_ampl) / max_ampl
373            }
374
375            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
376                let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
377                let scaled = value * max_ampl + max_ampl;
378                let converted = scaled.$to();
379                to_clamped_int(scaled, converted)
380            }
381        }
382    };
383}
384
385rawsample_for_uint!(u8, to_u8);
386rawsample_for_uint!(u16, to_u16);
387rawsample_for_uint!(u32, to_u32);
388rawsample_for_uint!(u64, to_u64);
389
390macro_rules! rawsample_for_float {
391    ($type:ident, $to:ident) => {
392        impl RawSample for $type {
393            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
394                T::from(*self).unwrap_or(T::zero())
395            }
396
397            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
398                // Floating point formats are not range-limited. Values outside
399                // -1.0..1.0 are valid headroom and pass through unchanged, so no
400                // clipping is applied and `clipped` is always false.
401                ConversionResult {
402                    clipped: false,
403                    value: value.$to().unwrap_or(0.0),
404                }
405            }
406        }
407    };
408}
409
410rawsample_for_float!(f32, to_f32);
411rawsample_for_float!(f64, to_f64);
412
413// 24 bit formats, needs more work than others
414// because they don't map directly to a normal numerical type,
415
416/// 24 bit signed integer, little endian, stored as 4 bytes right justified.
417/// The data is in the lower 3 bytes and the most significant byte is padding.
418impl BytesSample for I24_4RJ_LE {
419    type NumericType = i32;
420    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
421
422    fn zero() -> Self {
423        Self(Default::default())
424    }
425
426    fn from_slice(bytes: &[u8]) -> Self {
427        Self(bytes[0..4].try_into().unwrap())
428    }
429
430    fn as_slice(&self) -> &[u8] {
431        &self.0
432    }
433
434    fn as_mut_slice(&mut self) -> &mut [u8] {
435        &mut self.0
436    }
437
438    fn to_number(&self) -> Self::NumericType {
439        let padded = [0, self.0[0], self.0[1], self.0[2]];
440        i32::from_le_bytes(padded)
441    }
442
443    fn from_number(value: Self::NumericType) -> Self {
444        let bytes = value.to_le_bytes();
445        Self([bytes[1], bytes[2], bytes[3], 0])
446    }
447}
448
449/// 24 bit signed integer, little endian, stored as 4 bytes left justified.
450/// The data is in the upper 3 bytes and the least significant byte is padding.
451impl BytesSample for I24_4LJ_LE {
452    type NumericType = i32;
453    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
454
455    fn zero() -> Self {
456        Self(Default::default())
457    }
458
459    fn from_slice(bytes: &[u8]) -> Self {
460        Self(bytes[0..4].try_into().unwrap())
461    }
462
463    fn as_slice(&self) -> &[u8] {
464        &self.0
465    }
466
467    fn as_mut_slice(&mut self) -> &mut [u8] {
468        &mut self.0
469    }
470
471    fn to_number(&self) -> Self::NumericType {
472        let padded = [0, self.0[1], self.0[2], self.0[3]];
473        i32::from_le_bytes(padded)
474    }
475
476    fn from_number(value: Self::NumericType) -> Self {
477        let bytes = value.to_le_bytes();
478        Self([0, bytes[1], bytes[2], bytes[3]])
479    }
480}
481
482/// 24 bit signed integer, little endian, stored as 3 bytes without padding.
483impl BytesSample for I24_LE {
484    type NumericType = i32;
485    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
486
487    fn zero() -> Self {
488        Self(Default::default())
489    }
490
491    fn from_slice(bytes: &[u8]) -> Self {
492        Self(bytes[0..3].try_into().unwrap())
493    }
494
495    fn as_slice(&self) -> &[u8] {
496        &self.0
497    }
498
499    fn as_mut_slice(&mut self) -> &mut [u8] {
500        &mut self.0
501    }
502
503    fn to_number(&self) -> Self::NumericType {
504        let padded = [0, self.0[0], self.0[1], self.0[2]];
505        i32::from_le_bytes(padded)
506    }
507
508    fn from_number(value: Self::NumericType) -> Self {
509        let bytes = value.to_le_bytes();
510        Self([bytes[1], bytes[2], bytes[3]])
511    }
512}
513
514/// 24 bit signed integer, big endian, stored as 4 bytes right justified.
515/// The data is in the lower 3 bytes and the most significant byte is padding.
516impl BytesSample for I24_4RJ_BE {
517    type NumericType = i32;
518    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
519
520    fn zero() -> Self {
521        Self(Default::default())
522    }
523
524    fn from_slice(bytes: &[u8]) -> Self {
525        Self(bytes[0..4].try_into().unwrap())
526    }
527
528    fn as_slice(&self) -> &[u8] {
529        &self.0
530    }
531
532    fn as_mut_slice(&mut self) -> &mut [u8] {
533        &mut self.0
534    }
535
536    fn to_number(&self) -> Self::NumericType {
537        let padded = [self.0[1], self.0[2], self.0[3], 0];
538        i32::from_be_bytes(padded)
539    }
540
541    fn from_number(value: Self::NumericType) -> Self {
542        let bytes = value.to_be_bytes();
543        Self([0, bytes[0], bytes[1], bytes[2]])
544    }
545}
546
547/// 24 bit signed integer, big endian, stored as 4 bytes left justified.
548/// The data is in the upper 3 bytes and the least significant byte is padding.
549impl BytesSample for I24_4LJ_BE {
550    type NumericType = i32;
551    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
552
553    fn zero() -> Self {
554        Self(Default::default())
555    }
556
557    fn from_slice(bytes: &[u8]) -> Self {
558        Self(bytes[0..4].try_into().unwrap())
559    }
560
561    fn as_slice(&self) -> &[u8] {
562        &self.0
563    }
564
565    fn as_mut_slice(&mut self) -> &mut [u8] {
566        &mut self.0
567    }
568
569    fn to_number(&self) -> Self::NumericType {
570        let padded = [self.0[0], self.0[1], self.0[2], 0];
571        i32::from_be_bytes(padded)
572    }
573
574    fn from_number(value: Self::NumericType) -> Self {
575        let bytes = value.to_be_bytes();
576        Self([bytes[0], bytes[1], bytes[2], 0])
577    }
578}
579
580/// 24 bit signed integer, big endian, stored as 3 bytes without padding.
581impl BytesSample for I24_BE {
582    type NumericType = i32;
583    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
584
585    fn zero() -> Self {
586        Self(Default::default())
587    }
588
589    fn from_slice(bytes: &[u8]) -> Self {
590        Self(bytes[0..3].try_into().unwrap())
591    }
592
593    fn as_slice(&self) -> &[u8] {
594        &self.0
595    }
596
597    fn as_mut_slice(&mut self) -> &mut [u8] {
598        &mut self.0
599    }
600
601    fn to_number(&self) -> Self::NumericType {
602        let padded = [self.0[0], self.0[1], self.0[2], 0];
603        i32::from_be_bytes(padded)
604    }
605
606    fn from_number(value: Self::NumericType) -> Self {
607        let bytes = value.to_be_bytes();
608        Self([bytes[0], bytes[1], bytes[2]])
609    }
610}
611
612/// 24 bit unsigned integer, little endian, stored as 4 bytes right justified.
613/// The data is in the lower 3 bytes and the most significant byte is padding.
614impl BytesSample for U24_4RJ_LE {
615    type NumericType = u32;
616    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
617
618    fn zero() -> Self {
619        Self(Default::default())
620    }
621
622    fn from_slice(bytes: &[u8]) -> Self {
623        Self(bytes[0..4].try_into().unwrap())
624    }
625
626    fn as_slice(&self) -> &[u8] {
627        &self.0
628    }
629
630    fn as_mut_slice(&mut self) -> &mut [u8] {
631        &mut self.0
632    }
633
634    fn to_number(&self) -> Self::NumericType {
635        let padded = [0, self.0[0], self.0[1], self.0[2]];
636        u32::from_le_bytes(padded)
637    }
638
639    fn from_number(value: Self::NumericType) -> Self {
640        let bytes = value.to_le_bytes();
641        Self([bytes[1], bytes[2], bytes[3], 0])
642    }
643}
644
645/// 24 bit unsigned integer, little endian, stored as 4 bytes left justified.
646/// The data is in the upper 3 bytes and the least significant byte is padding.
647impl BytesSample for U24_4LJ_LE {
648    type NumericType = u32;
649    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
650
651    fn zero() -> Self {
652        Self(Default::default())
653    }
654
655    fn from_slice(bytes: &[u8]) -> Self {
656        Self(bytes[0..4].try_into().unwrap())
657    }
658
659    fn as_slice(&self) -> &[u8] {
660        &self.0
661    }
662
663    fn as_mut_slice(&mut self) -> &mut [u8] {
664        &mut self.0
665    }
666
667    fn to_number(&self) -> Self::NumericType {
668        let padded = [0, self.0[1], self.0[2], self.0[3]];
669        u32::from_le_bytes(padded)
670    }
671
672    fn from_number(value: Self::NumericType) -> Self {
673        let bytes = value.to_le_bytes();
674        Self([0, bytes[1], bytes[2], bytes[3]])
675    }
676}
677
678/// 24 bit unsigned integer, little endian, stored as 3 bytes without padding.
679impl BytesSample for U24_LE {
680    type NumericType = u32;
681    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
682
683    fn zero() -> Self {
684        Self(Default::default())
685    }
686
687    fn from_slice(bytes: &[u8]) -> Self {
688        Self(bytes[0..3].try_into().unwrap())
689    }
690
691    fn as_slice(&self) -> &[u8] {
692        &self.0
693    }
694
695    fn as_mut_slice(&mut self) -> &mut [u8] {
696        &mut self.0
697    }
698
699    fn to_number(&self) -> Self::NumericType {
700        let padded = [0, self.0[0], self.0[1], self.0[2]];
701        u32::from_le_bytes(padded)
702    }
703
704    fn from_number(value: Self::NumericType) -> Self {
705        let bytes = value.to_le_bytes();
706        Self([bytes[1], bytes[2], bytes[3]])
707    }
708}
709
710/// 24 bit unsigned integer, big endian, stored as 4 bytes right justified.
711/// The data is in the lower 3 bytes and the most significant byte is padding.
712impl BytesSample for U24_4RJ_BE {
713    type NumericType = u32;
714    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
715
716    fn zero() -> Self {
717        Self(Default::default())
718    }
719
720    fn from_slice(bytes: &[u8]) -> Self {
721        Self(bytes[0..4].try_into().unwrap())
722    }
723
724    fn as_slice(&self) -> &[u8] {
725        &self.0
726    }
727
728    fn as_mut_slice(&mut self) -> &mut [u8] {
729        &mut self.0
730    }
731
732    fn to_number(&self) -> Self::NumericType {
733        let padded = [self.0[1], self.0[2], self.0[3], 0];
734        u32::from_be_bytes(padded)
735    }
736
737    fn from_number(value: Self::NumericType) -> Self {
738        let bytes = value.to_be_bytes();
739        Self([0, bytes[0], bytes[1], bytes[2]])
740    }
741}
742
743/// 24 bit unsigned integer, big endian, stored as 4 bytes left justified.
744/// The data is in the upper 3 bytes and the least significant byte is padding.
745impl BytesSample for U24_4LJ_BE {
746    type NumericType = u32;
747    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
748
749    fn zero() -> Self {
750        Self(Default::default())
751    }
752
753    fn from_slice(bytes: &[u8]) -> Self {
754        Self(bytes[0..4].try_into().unwrap())
755    }
756
757    fn as_slice(&self) -> &[u8] {
758        &self.0
759    }
760
761    fn as_mut_slice(&mut self) -> &mut [u8] {
762        &mut self.0
763    }
764
765    fn to_number(&self) -> Self::NumericType {
766        let padded = [self.0[0], self.0[1], self.0[2], 0];
767        u32::from_be_bytes(padded)
768    }
769
770    fn from_number(value: Self::NumericType) -> Self {
771        let bytes = value.to_be_bytes();
772        Self([bytes[0], bytes[1], bytes[2], 0])
773    }
774}
775
776/// 24 bit unsigned integer, big endian, stored as 3 bytes without padding.
777impl BytesSample for U24_BE {
778    type NumericType = u32;
779    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
780
781    fn zero() -> Self {
782        Self(Default::default())
783    }
784
785    fn from_slice(bytes: &[u8]) -> Self {
786        Self(bytes[0..3].try_into().unwrap())
787    }
788
789    fn as_slice(&self) -> &[u8] {
790        &self.0
791    }
792
793    fn as_mut_slice(&mut self) -> &mut [u8] {
794        &mut self.0
795    }
796
797    fn to_number(&self) -> Self::NumericType {
798        let padded = [self.0[0], self.0[1], self.0[2], 0];
799        u32::from_be_bytes(padded)
800    }
801
802    fn from_number(value: Self::NumericType) -> Self {
803        let bytes = value.to_be_bytes();
804        Self([bytes[0], bytes[1], bytes[2]])
805    }
806}
807
808macro_rules! bytessample_for_newtype {
809    ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
810        impl BytesSample for $newtype {
811            type NumericType = $type;
812            const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
813
814            fn zero() -> Self {
815                Self(Default::default())
816            }
817
818            fn from_slice(bytes: &[u8]) -> Self {
819                Self(bytes.try_into().unwrap())
820            }
821
822            fn as_slice(&self) -> &[u8] {
823                &self.0
824            }
825
826            fn as_mut_slice(&mut self) -> &mut [u8] {
827                &mut self.0
828            }
829
830            fn to_number(&self) -> Self::NumericType {
831                $type::$from(self.0)
832            }
833
834            fn from_number(value: Self::NumericType) -> Self {
835                Self(value.$to())
836            }
837        }
838    };
839}
840
841// Single byte formats, where the endianness of the conversion is irrelevant.
842bytessample_for_newtype!(i8, I8, from_le_bytes, to_le_bytes);
843bytessample_for_newtype!(u8, U8, from_le_bytes, to_le_bytes);
844
845bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
846bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
847bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
848bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
849
850bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
851bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
852bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
853bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
854
855bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
856bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
857bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
858bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
859
860bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
861bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
862bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
863bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
864
865// ----- G.711 companded formats -----
866//
867// The conversions themselves are done by the `audio-codec-algorithms` crate.
868// Its decoding tables and test vectors come from the ITU-T G.191 reference
869// tools, and it verifies its encoders against them for every possible input.
870//
871// Both formats store the code word inverted, A-law with every other bit
872// flipped and mu-law fully complemented. This dates back to the analogue
873// telephone network, where it keeps the number of transitions on the line
874// high enough for clock recovery.
875
876macro_rules! bytessample_for_g711 {
877    ($newtype:ident, $decode:ident, $encode:ident) => {
878        impl BytesSample for $newtype {
879            type NumericType = i16;
880            const BYTES_PER_SAMPLE: usize = 1;
881
882            fn zero() -> Self {
883                Self(Default::default())
884            }
885
886            fn from_slice(bytes: &[u8]) -> Self {
887                Self(bytes[0..1].try_into().unwrap())
888            }
889
890            fn as_slice(&self) -> &[u8] {
891                &self.0
892            }
893
894            fn as_mut_slice(&mut self) -> &mut [u8] {
895                &mut self.0
896            }
897
898            fn to_number(&self) -> Self::NumericType {
899                $decode(self.0[0])
900            }
901
902            fn from_number(value: Self::NumericType) -> Self {
903                Self([$encode(value)])
904            }
905        }
906    };
907}
908
909bytessample_for_g711!(ALAW, decode_alaw, encode_alaw);
910bytessample_for_g711!(MULAW, decode_ulaw, encode_ulaw);
911
912impl<V> RawSample for V
913where
914    V: BytesSample,
915    <V as BytesSample>::NumericType: RawSample,
916{
917    fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
918        let value = self.to_number();
919        value.to_scaled_float()
920    }
921
922    fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
923        let value = <V as BytesSample>::NumericType::from_scaled_float(value);
924        ConversionResult {
925            clipped: value.clipped,
926            value: V::from_number(value.value),
927        }
928    }
929}
930
931#[cfg(test)]
932mod tests {
933    use super::*;
934
935    macro_rules! assert_conversion_eq {
936        ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
937            assert_eq!($result.value, $value, $desc);
938            assert_eq!($result.clipped, $clipped, $desc);
939        };
940    }
941
942    macro_rules! test_to_signed_int {
943        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
944            #[test]
945            fn $fname() {
946                let val: $float = 0.25;
947                assert_conversion_eq!(
948                    $int::from_scaled_float(val),
949                    1 << ($bits - 3),
950                    false,
951                    "check +0.25"
952                );
953                let val: $float = -0.25;
954                assert_conversion_eq!(
955                    $int::from_scaled_float(val),
956                    -1 << ($bits - 3),
957                    false,
958                    "check -0.25"
959                );
960                let val: $float = 1.1;
961                assert_conversion_eq!(
962                    $int::from_scaled_float(val),
963                    $int::MAX,
964                    true,
965                    "clipped positive"
966                );
967                let val: $float = -1.1;
968                assert_conversion_eq!(
969                    $int::from_scaled_float(val),
970                    $int::MIN,
971                    true,
972                    "clipped negative"
973                );
974            }
975        };
976    }
977
978    macro_rules! test_to_unsigned_int {
979        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
980            #[test]
981            fn $fname() {
982                let val: $float = -0.5;
983                assert_conversion_eq!(
984                    $int::from_scaled_float(val),
985                    1 << ($bits - 2),
986                    false,
987                    "check -0.5"
988                );
989                let val: $float = 0.5;
990                assert_conversion_eq!(
991                    $int::from_scaled_float(val),
992                    $int::MAX - (1 << ($bits - 2)) + 1,
993                    false,
994                    "check 0.5"
995                );
996                let val: $float = 1.1;
997                assert_conversion_eq!(
998                    $int::from_scaled_float(val),
999                    $int::MAX,
1000                    true,
1001                    "clipped positive"
1002                );
1003                let val: $float = -1.1;
1004                assert_conversion_eq!(
1005                    $int::from_scaled_float(val),
1006                    $int::MIN,
1007                    true,
1008                    "clipped negative"
1009                );
1010            }
1011        };
1012    }
1013
1014    test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
1015    test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
1016    test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
1017    test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
1018    test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
1019    test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
1020    test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
1021    test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
1022
1023    test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
1024    test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
1025    test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
1026    test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
1027    test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
1028    test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
1029    test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
1030    test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
1031
1032    macro_rules! test_from_signed_int {
1033        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
1034            #[test]
1035            fn $fname() {
1036                let val: $int = -1 << ($bits - 2);
1037                assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
1038                let val: $int = 1 << ($bits - 2);
1039                assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
1040                let val: $int = $int::MIN;
1041                assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
1042            }
1043        };
1044    }
1045
1046    macro_rules! test_from_unsigned_int {
1047        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
1048            #[test]
1049            fn $fname() {
1050                let val: $int = 1 << ($bits - 2);
1051                assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
1052                let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
1053                assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
1054                let val: $int = 0;
1055                assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
1056            }
1057        };
1058    }
1059
1060    test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
1061    test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
1062    test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
1063    test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
1064    test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
1065    test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
1066    test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
1067    test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
1068
1069    test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
1070    test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
1071    test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
1072    test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
1073    test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
1074    test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
1075    test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
1076    test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
1077
1078    #[test]
1079    fn test_to_clamped_int() {
1080        let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
1081        assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
1082
1083        let converted = to_clamped_int::<f32, i32>(1.0e10, None);
1084        assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
1085
1086        let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
1087        assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
1088
1089        let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
1090        assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
1091
1092        let converted = to_clamped_int::<f64, i32>(1.0e10, None);
1093        assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
1094
1095        let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
1096        assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
1097    }
1098
1099    #[test]
1100    fn test_to_clamped_uint() {
1101        let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
1102        assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
1103
1104        let converted = to_clamped_int::<f32, u32>(1.0e10, None);
1105        assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
1106
1107        let converted = to_clamped_int::<f32, u32>(-1.0, None);
1108        assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
1109
1110        let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
1111        assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
1112
1113        let converted = to_clamped_int::<f64, u32>(1.0e10, None);
1114        assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
1115
1116        let converted = to_clamped_int::<f64, u32>(-1.0, None);
1117        assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
1118    }
1119
1120    macro_rules! test_simple_int_bytes {
1121        ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1122            #[test]
1123            #[allow(non_snake_case)]
1124            fn $fname() {
1125                let number: $number = <$number>::MAX / 5 * 4;
1126                let wrapped = $wrapper(number.$to_bytes_fn());
1127                assert_eq!(number, wrapped.to_number());
1128            }
1129        };
1130    }
1131
1132    macro_rules! test_float_bytes {
1133        ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1134            #[test]
1135            #[allow(non_snake_case)]
1136            fn $fname() {
1137                let number: $number = 12345.0;
1138                let wrapped = $wrapper(number.$to_bytes_fn());
1139                assert_eq!(number, wrapped.to_number());
1140            }
1141        };
1142    }
1143
1144    test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
1145    test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
1146    test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
1147    test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
1148    test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
1149    test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1150
1151    test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1152    test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1153    test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1154    test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1155    test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1156    test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1157
1158    test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1159    test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1160    test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1161    test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1162
1163    #[test]
1164    #[allow(non_snake_case)]
1165    fn test_I8() {
1166        assert_eq!(I8::BYTES_PER_SAMPLE, 1);
1167        assert_eq!(I8::zero().to_number(), 0);
1168        assert_eq!(I8::from_slice(&[0x80]).to_number(), i8::MIN);
1169
1170        for number in [0, 1, -1, 100, i8::MIN, i8::MAX] {
1171            let wrapped = I8::from_number(number);
1172            assert_eq!(
1173                wrapped.as_slice(),
1174                number.to_le_bytes(),
1175                "bytes for {number}"
1176            );
1177            assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1178        }
1179    }
1180
1181    #[test]
1182    #[allow(non_snake_case)]
1183    fn test_U8() {
1184        assert_eq!(U8::BYTES_PER_SAMPLE, 1);
1185        assert_eq!(U8::zero().to_number(), 0);
1186        assert_eq!(U8::from_slice(&[0x80]).to_number(), 128);
1187
1188        for number in [0, 1, 128, 200, u8::MAX] {
1189            let wrapped = U8::from_number(number);
1190            assert_eq!(
1191                wrapped.as_slice(),
1192                number.to_le_bytes(),
1193                "bytes for {number}"
1194            );
1195            assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1196        }
1197    }
1198
1199    #[test]
1200    #[allow(non_snake_case)]
1201    fn convert_I8_to_and_from_float() {
1202        assert_eq!(I8::from_slice(&[0]).to_scaled_float::<f32>(), 0.0);
1203        assert_eq!(I8::from_slice(&[0x80]).to_scaled_float::<f32>(), -1.0);
1204        assert_eq!(I8::from_slice(&[0x40]).to_scaled_float::<f32>(), 0.5);
1205        assert_eq!(I8::from_slice(&[0xC0]).to_scaled_float::<f32>(), -0.5);
1206
1207        let converted = I8::from_scaled_float(0.5f32);
1208        assert_eq!(converted.value.as_slice(), [0x40]);
1209        assert!(!converted.clipped);
1210
1211        let converted = I8::from_scaled_float(-1.0f32);
1212        assert_eq!(converted.value.as_slice(), [0x80]);
1213        assert!(!converted.clipped);
1214
1215        // Values outside -1.0 .. +1.0 clip at the limits of an i8.
1216        let converted = I8::from_scaled_float(1.5f32);
1217        assert_eq!(converted.value.to_number(), i8::MAX);
1218        assert!(converted.clipped);
1219
1220        let converted = I8::from_scaled_float(-1.5f32);
1221        assert_eq!(converted.value.to_number(), i8::MIN);
1222        assert!(converted.clipped);
1223    }
1224
1225    #[test]
1226    #[allow(non_snake_case)]
1227    fn convert_U8_to_and_from_float() {
1228        // Unsigned samples are centered at 128.
1229        assert_eq!(U8::from_slice(&[128]).to_scaled_float::<f32>(), 0.0);
1230        assert_eq!(U8::from_slice(&[0]).to_scaled_float::<f32>(), -1.0);
1231        assert_eq!(U8::from_slice(&[192]).to_scaled_float::<f32>(), 0.5);
1232        assert_eq!(U8::from_slice(&[64]).to_scaled_float::<f32>(), -0.5);
1233
1234        let converted = U8::from_scaled_float(0.5f32);
1235        assert_eq!(converted.value.as_slice(), [192]);
1236        assert!(!converted.clipped);
1237
1238        let converted = U8::from_scaled_float(-1.0f32);
1239        assert_eq!(converted.value.as_slice(), [0]);
1240        assert!(!converted.clipped);
1241
1242        // Values outside -1.0 .. +1.0 clip at the limits of a u8.
1243        let converted = U8::from_scaled_float(1.5f32);
1244        assert_eq!(converted.value.to_number(), u8::MAX);
1245        assert!(converted.clipped);
1246
1247        let converted = U8::from_scaled_float(-1.5f32);
1248        assert_eq!(converted.value.to_number(), u8::MIN);
1249        assert!(converted.clipped);
1250    }
1251
1252    #[test]
1253    #[allow(non_snake_case)]
1254    fn test_I24_LE() {
1255        let number = i32::MAX / 5 * 4;
1256
1257        // make sure LSB is zero
1258        let number = number >> 8;
1259        let number = number << 8;
1260
1261        let allbytes = number.to_le_bytes();
1262        // Little-endian stores the LSB at the smallest address.
1263        // Drop the LSB!
1264        let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1265
1266        let wrapped = I24_LE(bytes);
1267        assert_eq!(number, wrapped.to_number());
1268    }
1269
1270    #[test]
1271    #[allow(non_snake_case)]
1272    fn test_I24_BE() {
1273        let number = i32::MAX / 5 * 4;
1274
1275        // make sure LSB is zero
1276        let number = number >> 8;
1277        let number = number << 8;
1278
1279        let allbytes = number.to_be_bytes();
1280        // Big-endian stores the LSB at the largest address.
1281        // Drop the LSB!
1282        let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1283
1284        let wrapped = I24_BE(bytes);
1285        assert_eq!(number, wrapped.to_number());
1286    }
1287
1288    #[test]
1289    #[allow(non_snake_case)]
1290    fn test_I24_4RJ_LE() {
1291        let number = i32::MAX / 5 * 4;
1292
1293        // make sure LSB is zero
1294        let number = number >> 8;
1295        let number = number << 8;
1296
1297        let allbytes = number.to_le_bytes();
1298        // Little-endian stores the LSB at the smallest address.
1299        // Drop the LSB and insert padding at MSB!
1300        let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1301
1302        let wrapped = I24_4RJ_LE(bytes);
1303        assert_eq!(number, wrapped.to_number());
1304    }
1305
1306    #[test]
1307    #[allow(non_snake_case)]
1308    fn test_I24_4RJ_BE() {
1309        let number = i32::MAX / 5 * 4;
1310
1311        // make sure LSB is zero
1312        let number = number >> 8;
1313        let number = number << 8;
1314
1315        let allbytes = number.to_be_bytes();
1316        // Big-endian stores the LSB at the largest address.
1317        // Drop the LSB and insert padding at MSB!
1318        let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1319
1320        let wrapped = I24_4RJ_BE(bytes);
1321        assert_eq!(number, wrapped.to_number());
1322    }
1323
1324    #[test]
1325    #[allow(non_snake_case)]
1326    fn test_I24_4LJ_LE() {
1327        let number = i32::MAX / 5 * 4;
1328
1329        // make sure LSB is zero
1330        let number = number >> 8;
1331        let number = number << 8;
1332
1333        let allbytes = number.to_le_bytes();
1334        // Little-endian stores the LSB at the smallest address.
1335        // Put a zero at LSB and keep the rest unchanged.
1336        let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1337
1338        let wrapped = I24_4LJ_LE(bytes);
1339        assert_eq!(number, wrapped.to_number());
1340    }
1341
1342    #[test]
1343    #[allow(non_snake_case)]
1344    fn test_I24_4LJ_BE() {
1345        let number = i32::MAX / 5 * 4;
1346
1347        // make sure LSB is zero
1348        let number = number >> 8;
1349        let number = number << 8;
1350
1351        let allbytes = number.to_be_bytes();
1352        // Big-endian stores the LSB at the largest address.
1353        // Put a zero at LSB and keep the rest unchanged.
1354        let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1355
1356        let wrapped = I24_4LJ_BE(bytes);
1357        assert_eq!(number, wrapped.to_number());
1358    }
1359
1360    #[test]
1361    #[allow(non_snake_case)]
1362    fn test_U24_LE() {
1363        let number = u32::MAX / 5 * 4;
1364
1365        // make sure LSB is zero
1366        let number = number >> 8;
1367        let number = number << 8;
1368
1369        let allbytes = number.to_le_bytes();
1370        // Little-endian stores the LSB at the smallest address.
1371        // Drop the LSB!
1372        let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1373
1374        let wrapped = U24_LE(bytes);
1375        assert_eq!(number, wrapped.to_number());
1376    }
1377
1378    #[test]
1379    #[allow(non_snake_case)]
1380    fn test_U24_BE() {
1381        let number = u32::MAX / 5 * 4;
1382
1383        // make sure LSB is zero
1384        let number = number >> 8;
1385        let number = number << 8;
1386
1387        let allbytes = number.to_be_bytes();
1388        // Big-endian stores the LSB at the largest address.
1389        // Drop the LSB!
1390        let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1391
1392        let wrapped = U24_BE(bytes);
1393        assert_eq!(number, wrapped.to_number());
1394    }
1395
1396    #[test]
1397    #[allow(non_snake_case)]
1398    fn test_U24_4RJ_LE() {
1399        let number = u32::MAX / 5 * 4;
1400
1401        // make sure LSB is zero
1402        let number = number >> 8;
1403        let number = number << 8;
1404
1405        let allbytes = number.to_le_bytes();
1406        // Little-endian stores the LSB at the smallest address.
1407        // Drop the LSB and insert padding at MSB!
1408        let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1409
1410        let wrapped = U24_4RJ_LE(bytes);
1411        assert_eq!(number, wrapped.to_number());
1412    }
1413
1414    #[test]
1415    #[allow(non_snake_case)]
1416    fn test_U24_4RJ_BE() {
1417        let number = u32::MAX / 5 * 4;
1418
1419        // make sure LSB is zero
1420        let number = number >> 8;
1421        let number = number << 8;
1422
1423        let allbytes = number.to_be_bytes();
1424        // Big-endian stores the LSB at the largest address.
1425        // Drop the LSB and insert padding at MSB!
1426        let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1427
1428        let wrapped = U24_4RJ_BE(bytes);
1429        assert_eq!(number, wrapped.to_number());
1430    }
1431
1432    #[test]
1433    #[allow(non_snake_case)]
1434    fn test_U24_4LJ_LE() {
1435        let number = u32::MAX / 5 * 4;
1436
1437        // make sure LSB is zero
1438        let number = number >> 8;
1439        let number = number << 8;
1440
1441        let allbytes = number.to_le_bytes();
1442        // Little-endian stores the LSB at the smallest address.
1443        // Put a zero at LSB and keep the rest unchanged.
1444        let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1445
1446        let wrapped = U24_4LJ_LE(bytes);
1447        assert_eq!(number, wrapped.to_number());
1448    }
1449
1450    #[test]
1451    #[allow(non_snake_case)]
1452    fn test_U24_4LJ_BE() {
1453        let number = u32::MAX / 5 * 4;
1454
1455        // make sure LSB is zero
1456        let number = number >> 8;
1457        let number = number << 8;
1458
1459        let allbytes = number.to_be_bytes();
1460        // Big-endian stores the LSB at the largest address.
1461        // Put a zero at LSB and keep the rest unchanged.
1462        let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1463
1464        let wrapped = U24_4LJ_BE(bytes);
1465        assert_eq!(number, wrapped.to_number());
1466    }
1467
1468    // ----- G.711 companded formats -----
1469    //
1470    // The numeric type is wider than these formats, so the roundtrip property
1471    // of the linear formats does not apply. A number does not survive a
1472    // roundtrip unless it happens to be one of the 256 representable values.
1473    // What does hold is that encoding is idempotent, and that every code word
1474    // survives a roundtrip through its numeric value.
1475
1476    #[test]
1477    #[allow(non_snake_case)]
1478    fn test_ALAW() {
1479        assert_eq!(ALAW::BYTES_PER_SAMPLE, 1);
1480
1481        // A-law has no code for exact silence, the smallest magnitudes are +-8.
1482        assert_eq!(ALAW::from_slice(&[0xd5]).to_number(), 8);
1483        assert_eq!(ALAW::from_slice(&[0x55]).to_number(), -8);
1484        assert_eq!(ALAW::from_number(0).as_slice(), [0xd5]);
1485
1486        // The largest representable magnitudes.
1487        assert_eq!(ALAW::from_slice(&[0xaa]).to_number(), 32256);
1488        assert_eq!(ALAW::from_slice(&[0x2a]).to_number(), -32256);
1489
1490        // An all zero byte is a valid code word, but it is not silence.
1491        assert_eq!(ALAW::zero().to_number(), -5504);
1492    }
1493
1494    #[test]
1495    #[allow(non_snake_case)]
1496    fn test_MULAW() {
1497        assert_eq!(MULAW::BYTES_PER_SAMPLE, 1);
1498
1499        // Mu-law has two codes for silence, one per sign.
1500        assert_eq!(MULAW::from_slice(&[0xff]).to_number(), 0);
1501        assert_eq!(MULAW::from_slice(&[0x7f]).to_number(), 0);
1502        assert_eq!(MULAW::from_number(0).as_slice(), [0xff]);
1503
1504        // The largest representable magnitudes. Note that the sign bit means
1505        // the opposite of what it means in A-law.
1506        assert_eq!(MULAW::from_slice(&[0x80]).to_number(), 32124);
1507        assert_eq!(MULAW::from_slice(&[0x00]).to_number(), -32124);
1508
1509        // An all zero byte is a valid code word, but it is not silence.
1510        assert_eq!(MULAW::zero().to_number(), -32124);
1511    }
1512
1513    macro_rules! test_g711_roundtrips {
1514        ($name:ident, $type:ident, $maxmagnitude:expr, $aliases:expr) => {
1515            #[test]
1516            #[allow(non_snake_case)]
1517            fn $name() {
1518                // Every code word survives a roundtrip via its numeric value,
1519                // apart from any duplicate encoding of the same value.
1520                for byte in 0..=u8::MAX {
1521                    if $aliases.contains(&byte) {
1522                        continue;
1523                    }
1524                    let number = $type::from_slice(&[byte]).to_number();
1525                    assert_eq!(
1526                        $type::from_number(number).as_slice(),
1527                        [byte],
1528                        "code word {byte:#04x} decoded to {number}"
1529                    );
1530                }
1531
1532                // Encoding is idempotent. Quantizing an already quantized
1533                // value leaves it unchanged.
1534                for number in (i16::MIN..=i16::MAX).step_by(7) {
1535                    let once = $type::from_number(number).to_number();
1536                    let twice = $type::from_number(once).to_number();
1537                    assert_eq!(once, twice, "quantizing {number} is not stable");
1538                }
1539
1540                // The decoded values never exceed the documented magnitude,
1541                // and the format is symmetric around zero.
1542                for byte in 0..=u8::MAX {
1543                    let number = $type::from_slice(&[byte]).to_number();
1544                    assert!(
1545                        number.abs() <= $maxmagnitude,
1546                        "code word {byte:#04x} decoded to {number}"
1547                    );
1548                    let mirrored = $type::from_slice(&[byte ^ 0x80]).to_number();
1549                    assert_eq!(number, -mirrored, "code word {byte:#04x} is not symmetric");
1550                }
1551            }
1552        };
1553    }
1554
1555    // A-law encodes every value exactly once. Mu-law has two codes for zero,
1556    // and `0xff` is the one that encoding produces.
1557    test_g711_roundtrips!(roundtrip_ALAW, ALAW, 32256, []);
1558    test_g711_roundtrips!(roundtrip_MULAW, MULAW, 32124, [0x7f]);
1559
1560    #[test]
1561    #[allow(non_snake_case)]
1562    fn convert_ALAW_to_and_from_float() {
1563        assert_eq!(
1564            ALAW::from_slice(&[0xaa]).to_scaled_float::<f32>(),
1565            32256.0 / 32768.0
1566        );
1567        assert_eq!(
1568            ALAW::from_slice(&[0x2a]).to_scaled_float::<f32>(),
1569            -32256.0 / 32768.0
1570        );
1571        assert!(ALAW::from_slice(&[0xd5]).to_scaled_float::<f32>().abs() < 0.001);
1572
1573        // Values outside -1.0 .. +1.0 clip, and land on the largest magnitude.
1574        let converted = ALAW::from_scaled_float(1.5f32);
1575        assert_eq!(converted.value.to_number(), 32256);
1576        assert!(converted.clipped);
1577
1578        let converted = ALAW::from_scaled_float(-1.5f32);
1579        assert_eq!(converted.value.to_number(), -32256);
1580        assert!(converted.clipped);
1581    }
1582
1583    #[test]
1584    #[allow(non_snake_case)]
1585    fn convert_MULAW_to_and_from_float() {
1586        assert_eq!(
1587            MULAW::from_slice(&[0x80]).to_scaled_float::<f32>(),
1588            32124.0 / 32768.0
1589        );
1590        assert_eq!(
1591            MULAW::from_slice(&[0x00]).to_scaled_float::<f32>(),
1592            -32124.0 / 32768.0
1593        );
1594        assert_eq!(MULAW::from_slice(&[0xff]).to_scaled_float::<f32>(), 0.0);
1595
1596        // Values outside -1.0 .. +1.0 clip, and land on the largest magnitude.
1597        let converted = MULAW::from_scaled_float(1.5f32);
1598        assert_eq!(converted.value.to_number(), 32124);
1599        assert!(converted.clipped);
1600
1601        let converted = MULAW::from_scaled_float(-1.5f32);
1602        assert_eq!(converted.value.to_number(), -32124);
1603        assert!(converted.clipped);
1604    }
1605
1606    /// Check that the companding curve really is logarithmic, by verifying that
1607    /// the error stays proportional to the value instead of being a fixed step.
1608    ///
1609    /// This only holds above the bottom of the range. Both curves have a linear
1610    /// section around zero, where the step size stops shrinking and the relative
1611    /// error grows without bound. That part is checked as an absolute error.
1612    macro_rules! test_g711_accuracy {
1613        ($name:ident, $type:ident, $smallerror:expr) => {
1614            #[test]
1615            #[allow(non_snake_case)]
1616            fn $name() {
1617                for value in (i16::MIN..=i16::MAX).step_by(3) {
1618                    let encoded = $type::from_number(value).to_number();
1619                    let error = (i32::from(encoded) - i32::from(value)).abs();
1620                    if value.unsigned_abs() >= 1000 {
1621                        let relative = f64::from(error) / f64::from(value.unsigned_abs());
1622                        assert!(
1623                            relative < 0.05,
1624                            "relative error {relative} at {value} is too large, got {encoded}"
1625                        );
1626                    } else {
1627                        assert!(
1628                            error <= $smallerror,
1629                            "error {error} at {value} is too large, got {encoded}"
1630                        );
1631                    }
1632                }
1633            }
1634        };
1635    }
1636
1637    // The measured worst cases are 16 and 32, so these are the exact bounds.
1638    test_g711_accuracy!(accuracy_ALAW, ALAW, 16);
1639    test_g711_accuracy!(accuracy_MULAW, MULAW, 32);
1640}