Skip to main content

audioadapter_sample/
sample.rs

1#![allow(non_camel_case_types)]
2
3use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
4
5#[cfg(feature = "audio")]
6use audio_core::Sample;
7
8// ------ 16-bit integer formats ------
9
10/// 16 bit signed integer, little endian. Stored as 2 bytes.
11#[derive(Debug, Clone, Copy)]
12pub struct I16_LE([u8; 2]);
13
14/// 16 bit signed integer, big endian. Stored as 2 bytes.
15#[derive(Debug, Clone, Copy)]
16pub struct I16_BE([u8; 2]);
17
18/// 16 bit unsigned integer, little endian. Stored as 2 bytes.
19#[derive(Debug, Clone, Copy)]
20pub struct U16_LE([u8; 2]);
21
22/// 16 bit unsigned integer, big endian. Stored as 2 bytes.
23#[derive(Debug, Clone, Copy)]
24pub struct U16_BE([u8; 2]);
25
26// ----- 24-bit formats -----
27
28/// 24 bit signed integer, little endian. Stored as 3 bytes.
29#[derive(Debug, Clone, Copy)]
30pub struct I24_LE([u8; 3]);
31
32/// 24 bit signed integer, little endian. Stored as 4 bytes left justified.
33/// The 24 data bits are stored in the three most significant bytes,
34/// while the least significant byte is unused padding.
35#[derive(Debug, Clone, Copy)]
36pub struct I24_4LJ_LE([u8; 4]);
37
38/// 24 bit signed integer, little endian. Stored as 4 bytes right justified.
39/// The 24 data bits are stored in the three least significant bytes,
40/// while the most significant byte is unused padding.
41#[derive(Debug, Clone, Copy)]
42pub struct I24_4RJ_LE([u8; 4]);
43
44/// 24 bit signed integer, big endian. Stored as 3 bytes.
45#[derive(Debug, Clone, Copy)]
46pub struct I24_BE([u8; 3]);
47
48/// 24 bit signed integer, big endian. Stored as 4 bytes left justified.
49/// The 24 data bits are stored in the three most significant bytes,
50/// while the least significant byte is unused padding.
51#[derive(Debug, Clone, Copy)]
52pub struct I24_4LJ_BE([u8; 4]);
53
54/// 24 bit signed integer, big endian. Stored as 4 bytes right justified.
55/// The 24 data bits are stored in the three least significant bytes,
56/// while the most significant byte is unused padding.
57#[derive(Debug, Clone, Copy)]
58pub struct I24_4RJ_BE([u8; 4]);
59
60/// 24 bit unsigned integer, little endian. Stored as 3 bytes.
61#[derive(Debug, Clone, Copy)]
62pub struct U24_LE([u8; 3]);
63
64/// 24 bit unsigned integer, little endian. Stored as 4 bytes left justified.
65/// The 24 data bits are stored in the three most significant bytes,
66/// while the least significant byte is unused padding.
67#[derive(Debug, Clone, Copy)]
68pub struct U24_4LJ_LE([u8; 4]);
69
70/// 24 bit unsigned integer, little endian. Stored as 4 bytes right justified.
71/// The 24 data bits are stored in the three least significant bytes,
72/// while the most significant byte is unused padding.
73#[derive(Debug, Clone, Copy)]
74pub struct U24_4RJ_LE([u8; 4]);
75
76/// 24 bit unsigned integer, big endian. Stored as 3 bytes.
77#[derive(Debug, Clone, Copy)]
78pub struct U24_BE([u8; 3]);
79
80/// 24 bit unsigned integer, big endian. Stored as 4 bytes left justified.
81/// The 24 data bits are stored in the three most significant bytes,
82/// while the least significant byte is unused padding.
83#[derive(Debug, Clone, Copy)]
84pub struct U24_4LJ_BE([u8; 4]);
85
86/// 24 bit unsigned integer, big endian. Stored as 4 bytes right justified.
87/// The 24 data bits are stored in the three least significant bytes,
88/// while the most significant byte is unused padding.
89#[derive(Debug, Clone, Copy)]
90pub struct U24_4RJ_BE([u8; 4]);
91
92// ------ 32-bit integer formats ------
93
94/// 32 bit signed integer, little endian. Stored as 4 bytes.
95#[derive(Debug, Clone, Copy)]
96pub struct I32_LE([u8; 4]);
97
98/// 32 bit signed integer, big endian. Stored as 4 bytes.
99#[derive(Debug, Clone, Copy)]
100pub struct I32_BE([u8; 4]);
101
102/// 32 bit unsigned integer, little endian. Stored as 4 bytes.
103#[derive(Debug, Clone, Copy)]
104pub struct U32_LE([u8; 4]);
105
106/// 32 bit unsigned integer, big endian. Stored as 4 bytes.
107#[derive(Debug, Clone, Copy)]
108pub struct U32_BE([u8; 4]);
109
110// ----- 64-bit integer formats ------
111
112/// 64 bit signed integer, little endian. Stored as 8 bytes.
113#[derive(Debug, Clone, Copy)]
114pub struct I64_LE([u8; 8]);
115
116/// 64 bit signed integer, big endian. Stored as 8 bytes.
117#[derive(Debug, Clone, Copy)]
118pub struct I64_BE([u8; 8]);
119
120/// 64 bit unsigned integer, little endian. Stored as 8 bytes.
121#[derive(Debug, Clone, Copy)]
122pub struct U64_LE([u8; 8]);
123
124/// 64 bit unsigned integer, big endian. Stored as 8 bytes.
125#[derive(Debug, Clone, Copy)]
126pub struct U64_BE([u8; 8]);
127
128// ----- floating point formats -----
129
130/// 32 bit floating point, little endian. Stored as 4 bytes.
131#[derive(Debug, Clone, Copy)]
132pub struct F32_LE([u8; 4]);
133
134/// 32 bit floating point, big endian. Stored as 4 bytes.
135#[derive(Debug, Clone, Copy)]
136pub struct F32_BE([u8; 4]);
137
138/// 64 bit floating point, little endian. Stored as 8 bytes.
139#[derive(Debug, Clone, Copy)]
140pub struct F64_LE([u8; 8]);
141
142/// 64 bit floating point, big endian. Stored as 8 bytes.
143#[derive(Debug, Clone, Copy)]
144pub struct F64_BE([u8; 8]);
145
146/// Convert a float to an integer, clamp at the min and max limits of the integer.
147fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
148    value: T,
149    converted: Option<U>,
150) -> ConversionResult<U> {
151    if let Some(val) = converted {
152        return ConversionResult {
153            clipped: false,
154            value: val,
155        };
156    }
157    if value.is_nan() {
158        return ConversionResult {
159            clipped: true,
160            value: U::zero(),
161        };
162    }
163    if value > T::zero() {
164        return ConversionResult {
165            clipped: true,
166            value: U::max_value(),
167        };
168    }
169    ConversionResult {
170        clipped: true,
171        value: U::min_value(),
172    }
173}
174
175/// A conversion result, containing the resulting value as `value`
176/// and a boolean `clipped` indicating if the value was clipped during conversion.
177pub struct ConversionResult<T> {
178    pub clipped: bool,
179    pub value: T,
180}
181
182/// A trait for converting a given sample type to and from floating point values.
183/// The floating point values use the range -1.0 to +1.0.
184/// When converting to/from signed integers, the range does not include +1.0.
185/// For example, an 8-bit signed integer supports the range -128 to +127.
186/// When these values are converted to float, 0 becomes 0.0,
187/// -128 becomes -1.0, and 127 becomes 127/128 ≈ 0.992.
188/// Unsigned integers are also converted to the same -1.0 to +1.0 range.
189/// For an 8-but unsigned integer, 128 is the center point and becomes 0.0.
190/// The value 0 becomes -1.0, and 255 becomes 127/128 ≈ 0.992.
191pub trait RawSample
192where
193    Self: Sized,
194{
195    /// Convert the sample value to a float in the range -1.0 .. +1.0.
196    fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
197
198    /// Convert a float in the range -1.0 .. +1.0 to a sample value.
199    /// Values outside the allowed range are clipped to the nearest limit.
200    fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
201}
202
203/// A trait for converting samples stored as raw bytes into a numerical type.
204/// Each implementation defines the associated type `NumericType`,
205/// which is the nearest matching numeric type for the original format.
206/// If a direct match exists, this is used.
207/// For example signed 16 bit integer samples use [i16].
208/// For formats that don't have a direct match,
209/// the next larger numeric type is used.
210/// For example for 24 bit signed integers,
211/// this means [i32].
212/// The values are scaled to use the full range of the `NumericType`
213/// associated type.
214pub trait BytesSample {
215    /// The closest matching numeric type.
216    type NumericType: Copy;
217
218    /// The number of bytes making up each sample value.
219    const BYTES_PER_SAMPLE: usize;
220
221    /// Create a new ByteSample from a slice of raw bytes.
222    /// The slice length must be at least the number of bytes
223    /// for a sample value.
224    fn from_slice(bytes: &[u8]) -> Self;
225
226    /// Return the raw bytes as a slice.
227    fn as_slice(&self) -> &[u8];
228
229    /// Return the raw bytes as a mutable slice.
230    fn as_mut_slice(&mut self) -> &mut [u8];
231
232    /// Convert the raw bytes to a numerical value.
233    fn to_number(&self) -> Self::NumericType;
234
235    /// Convert a numerical value to raw bytes.
236    fn from_number(value: Self::NumericType) -> Self;
237}
238
239macro_rules! rawsample_for_int {
240    ($type:ident, $to:ident) => {
241        impl RawSample for $type {
242            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
243                T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
244            }
245
246            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
247                let scaled = value * (T::from($type::MAX).unwrap() + T::one());
248                let converted = scaled.$to();
249                to_clamped_int(scaled, converted)
250            }
251        }
252    };
253}
254
255rawsample_for_int!(i8, to_i8);
256rawsample_for_int!(i16, to_i16);
257rawsample_for_int!(i32, to_i32);
258rawsample_for_int!(i64, to_i64);
259
260macro_rules! rawsample_for_uint {
261    ($type:ident, $to:ident) => {
262        impl RawSample for $type {
263            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
264                let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
265                (T::from(*self).unwrap() - max_ampl) / max_ampl
266            }
267
268            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
269                let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
270                let scaled = value * max_ampl + max_ampl;
271                let converted = scaled.$to();
272                to_clamped_int(scaled, converted)
273            }
274        }
275    };
276}
277
278rawsample_for_uint!(u8, to_u8);
279rawsample_for_uint!(u16, to_u16);
280rawsample_for_uint!(u32, to_u32);
281rawsample_for_uint!(u64, to_u64);
282
283macro_rules! rawsample_for_float {
284    ($type:ident, $to:ident) => {
285        impl RawSample for $type {
286            fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
287                T::from(*self).unwrap_or(T::zero())
288            }
289
290            fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
291                // TODO clip here
292                ConversionResult {
293                    clipped: false,
294                    value: value.$to().unwrap_or(0.0),
295                }
296            }
297        }
298    };
299}
300
301rawsample_for_float!(f32, to_f32);
302rawsample_for_float!(f64, to_f64);
303
304// 24 bit formats, needs more work than others
305// because they don't map directly to a normal numerical type,
306
307/// 24 bit signed integer, little endian, stored as 4 bytes right justified.
308/// The data is in the lower 3 bytes and the most significant byte is padding.
309impl BytesSample for I24_4RJ_LE {
310    type NumericType = i32;
311    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
312
313    fn from_slice(bytes: &[u8]) -> Self {
314        Self(bytes[0..4].try_into().unwrap())
315    }
316
317    fn as_slice(&self) -> &[u8] {
318        &self.0
319    }
320
321    fn as_mut_slice(&mut self) -> &mut [u8] {
322        &mut self.0
323    }
324
325    fn to_number(&self) -> Self::NumericType {
326        let padded = [0, self.0[0], self.0[1], self.0[2]];
327        i32::from_le_bytes(padded)
328    }
329
330    fn from_number(value: Self::NumericType) -> Self {
331        let bytes = value.to_le_bytes();
332        Self([bytes[1], bytes[2], bytes[3], 0])
333    }
334}
335
336/// 24 bit signed integer, little endian, stored as 4 bytes left justified.
337/// The data is in the upper 3 bytes and the least significant byte is padding.
338impl BytesSample for I24_4LJ_LE {
339    type NumericType = i32;
340    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
341
342    fn from_slice(bytes: &[u8]) -> Self {
343        Self(bytes[0..4].try_into().unwrap())
344    }
345
346    fn as_slice(&self) -> &[u8] {
347        &self.0
348    }
349
350    fn as_mut_slice(&mut self) -> &mut [u8] {
351        &mut self.0
352    }
353
354    fn to_number(&self) -> Self::NumericType {
355        let padded = [0, self.0[1], self.0[2], self.0[3]];
356        i32::from_le_bytes(padded)
357    }
358
359    fn from_number(value: Self::NumericType) -> Self {
360        let bytes = value.to_le_bytes();
361        Self([0, bytes[1], bytes[2], bytes[3]])
362    }
363}
364
365/// 24 bit signed integer, little endian, stored as 3 bytes without padding.
366impl BytesSample for I24_LE {
367    type NumericType = i32;
368    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
369
370    fn from_slice(bytes: &[u8]) -> Self {
371        Self(bytes[0..3].try_into().unwrap())
372    }
373
374    fn as_slice(&self) -> &[u8] {
375        &self.0
376    }
377
378    fn as_mut_slice(&mut self) -> &mut [u8] {
379        &mut self.0
380    }
381
382    fn to_number(&self) -> Self::NumericType {
383        let padded = [0, self.0[0], self.0[1], self.0[2]];
384        i32::from_le_bytes(padded)
385    }
386
387    fn from_number(value: Self::NumericType) -> Self {
388        let bytes = value.to_le_bytes();
389        Self([bytes[1], bytes[2], bytes[3]])
390    }
391}
392
393/// 24 bit signed integer, big endian, stored as 4 bytes right justified.
394/// The data is in the lower 3 bytes and the most significant byte is padding.
395impl BytesSample for I24_4RJ_BE {
396    type NumericType = i32;
397    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
398
399    fn from_slice(bytes: &[u8]) -> Self {
400        Self(bytes[0..4].try_into().unwrap())
401    }
402
403    fn as_slice(&self) -> &[u8] {
404        &self.0
405    }
406
407    fn as_mut_slice(&mut self) -> &mut [u8] {
408        &mut self.0
409    }
410
411    fn to_number(&self) -> Self::NumericType {
412        let padded = [self.0[1], self.0[2], self.0[3], 0];
413        i32::from_be_bytes(padded)
414    }
415
416    fn from_number(value: Self::NumericType) -> Self {
417        let bytes = value.to_be_bytes();
418        Self([0, bytes[0], bytes[1], bytes[2]])
419    }
420}
421
422/// 24 bit signed integer, big endian, stored as 4 bytes left justified.
423/// The data is in the upper 3 bytes and the least significant byte is padding.
424impl BytesSample for I24_4LJ_BE {
425    type NumericType = i32;
426    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
427
428    fn from_slice(bytes: &[u8]) -> Self {
429        Self(bytes[0..4].try_into().unwrap())
430    }
431
432    fn as_slice(&self) -> &[u8] {
433        &self.0
434    }
435
436    fn as_mut_slice(&mut self) -> &mut [u8] {
437        &mut self.0
438    }
439
440    fn to_number(&self) -> Self::NumericType {
441        let padded = [self.0[0], self.0[1], self.0[2], 0];
442        i32::from_be_bytes(padded)
443    }
444
445    fn from_number(value: Self::NumericType) -> Self {
446        let bytes = value.to_be_bytes();
447        Self([bytes[0], bytes[1], bytes[2], 0])
448    }
449}
450
451/// 24 bit signed integer, big endian, stored as 3 bytes without padding.
452impl BytesSample for I24_BE {
453    type NumericType = i32;
454    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
455
456    fn from_slice(bytes: &[u8]) -> Self {
457        Self(bytes[0..3].try_into().unwrap())
458    }
459
460    fn as_slice(&self) -> &[u8] {
461        &self.0
462    }
463
464    fn as_mut_slice(&mut self) -> &mut [u8] {
465        &mut self.0
466    }
467
468    fn to_number(&self) -> Self::NumericType {
469        let padded = [self.0[0], self.0[1], self.0[2], 0];
470        i32::from_be_bytes(padded)
471    }
472
473    fn from_number(value: Self::NumericType) -> Self {
474        let bytes = value.to_be_bytes();
475        Self([bytes[0], bytes[1], bytes[2]])
476    }
477}
478
479/// 24 bit unsigned integer, little endian, stored as 4 bytes right justified.
480/// The data is in the lower 3 bytes and the most significant byte is padding.
481impl BytesSample for U24_4RJ_LE {
482    type NumericType = u32;
483    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
484
485    fn from_slice(bytes: &[u8]) -> Self {
486        Self(bytes[0..4].try_into().unwrap())
487    }
488
489    fn as_slice(&self) -> &[u8] {
490        &self.0
491    }
492
493    fn as_mut_slice(&mut self) -> &mut [u8] {
494        &mut self.0
495    }
496
497    fn to_number(&self) -> Self::NumericType {
498        let padded = [0, self.0[0], self.0[1], self.0[2]];
499        u32::from_le_bytes(padded)
500    }
501
502    fn from_number(value: Self::NumericType) -> Self {
503        let bytes = value.to_le_bytes();
504        Self([bytes[1], bytes[2], bytes[3], 0])
505    }
506}
507
508/// 24 bit unsigned integer, little endian, stored as 4 bytes left justified.
509/// The data is in the upper 3 bytes and the least significant byte is padding.
510impl BytesSample for U24_4LJ_LE {
511    type NumericType = u32;
512    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
513
514    fn from_slice(bytes: &[u8]) -> Self {
515        Self(bytes[0..4].try_into().unwrap())
516    }
517
518    fn as_slice(&self) -> &[u8] {
519        &self.0
520    }
521
522    fn as_mut_slice(&mut self) -> &mut [u8] {
523        &mut self.0
524    }
525
526    fn to_number(&self) -> Self::NumericType {
527        let padded = [0, self.0[1], self.0[2], self.0[3]];
528        u32::from_le_bytes(padded)
529    }
530
531    fn from_number(value: Self::NumericType) -> Self {
532        let bytes = value.to_le_bytes();
533        Self([0, bytes[1], bytes[2], bytes[3]])
534    }
535}
536
537/// 24 bit unsigned integer, little endian, stored as 3 bytes without padding.
538impl BytesSample for U24_LE {
539    type NumericType = u32;
540    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
541
542    fn from_slice(bytes: &[u8]) -> Self {
543        Self(bytes[0..3].try_into().unwrap())
544    }
545
546    fn as_slice(&self) -> &[u8] {
547        &self.0
548    }
549
550    fn as_mut_slice(&mut self) -> &mut [u8] {
551        &mut self.0
552    }
553
554    fn to_number(&self) -> Self::NumericType {
555        let padded = [0, self.0[0], self.0[1], self.0[2]];
556        u32::from_le_bytes(padded)
557    }
558
559    fn from_number(value: Self::NumericType) -> Self {
560        let bytes = value.to_le_bytes();
561        Self([bytes[1], bytes[2], bytes[3]])
562    }
563}
564
565/// 24 bit unsigned integer, big endian, stored as 4 bytes right justified.
566/// The data is in the lower 3 bytes and the most significant byte is padding.
567impl BytesSample for U24_4RJ_BE {
568    type NumericType = u32;
569    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
570
571    fn from_slice(bytes: &[u8]) -> Self {
572        Self(bytes[0..4].try_into().unwrap())
573    }
574
575    fn as_slice(&self) -> &[u8] {
576        &self.0
577    }
578
579    fn as_mut_slice(&mut self) -> &mut [u8] {
580        &mut self.0
581    }
582
583    fn to_number(&self) -> Self::NumericType {
584        let padded = [self.0[1], self.0[2], self.0[3], 0];
585        u32::from_be_bytes(padded)
586    }
587
588    fn from_number(value: Self::NumericType) -> Self {
589        let bytes = value.to_be_bytes();
590        Self([0, bytes[0], bytes[1], bytes[2]])
591    }
592}
593
594/// 24 bit unsigned integer, big endian, stored as 4 bytes left justified.
595/// The data is in the upper 3 bytes and the least significant byte is padding.
596impl BytesSample for U24_4LJ_BE {
597    type NumericType = u32;
598    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
599
600    fn from_slice(bytes: &[u8]) -> Self {
601        Self(bytes[0..4].try_into().unwrap())
602    }
603
604    fn as_slice(&self) -> &[u8] {
605        &self.0
606    }
607
608    fn as_mut_slice(&mut self) -> &mut [u8] {
609        &mut self.0
610    }
611
612    fn to_number(&self) -> Self::NumericType {
613        let padded = [self.0[0], self.0[1], self.0[2], 0];
614        u32::from_be_bytes(padded)
615    }
616
617    fn from_number(value: Self::NumericType) -> Self {
618        let bytes = value.to_be_bytes();
619        Self([bytes[0], bytes[1], bytes[2], 0])
620    }
621}
622
623/// 24 bit unsigned integer, big endian, stored as 3 bytes without padding.
624impl BytesSample for U24_BE {
625    type NumericType = u32;
626    const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
627
628    fn from_slice(bytes: &[u8]) -> Self {
629        Self(bytes[0..3].try_into().unwrap())
630    }
631
632    fn as_slice(&self) -> &[u8] {
633        &self.0
634    }
635
636    fn as_mut_slice(&mut self) -> &mut [u8] {
637        &mut self.0
638    }
639
640    fn to_number(&self) -> Self::NumericType {
641        let padded = [self.0[0], self.0[1], self.0[2], 0];
642        u32::from_be_bytes(padded)
643    }
644
645    fn from_number(value: Self::NumericType) -> Self {
646        let bytes = value.to_be_bytes();
647        Self([bytes[0], bytes[1], bytes[2]])
648    }
649}
650
651macro_rules! bytessample_for_newtype {
652    ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
653        impl BytesSample for $newtype {
654            type NumericType = $type;
655            const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
656
657            fn from_slice(bytes: &[u8]) -> Self {
658                Self(bytes.try_into().unwrap())
659            }
660
661            fn as_slice(&self) -> &[u8] {
662                &self.0
663            }
664
665            fn as_mut_slice(&mut self) -> &mut [u8] {
666                &mut self.0
667            }
668
669            fn to_number(&self) -> Self::NumericType {
670                $type::$from(self.0)
671            }
672
673            fn from_number(value: Self::NumericType) -> Self {
674                Self(value.$to())
675            }
676        }
677    };
678}
679
680bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
681bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
682bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
683bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
684
685bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
686bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
687bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
688bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
689
690bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
691bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
692bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
693bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
694
695bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
696bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
697bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
698bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
699
700impl<V> RawSample for V
701where
702    V: BytesSample,
703    <V as BytesSample>::NumericType: RawSample,
704{
705    fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
706        let value = self.to_number();
707        value.to_scaled_float()
708    }
709
710    fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
711        let value = <V as BytesSample>::NumericType::from_scaled_float(value);
712        ConversionResult {
713            clipped: value.clipped,
714            value: V::from_number(value.value),
715        }
716    }
717}
718
719// Implement Sample for the audioadapter types
720#[cfg(feature = "audio")]
721macro_rules! impl_sample_for_newtype {
722    ($newtype:ident, $bytes:expr) => {
723        unsafe impl Sample for $newtype {
724            const ZERO: $newtype = $newtype([0; $bytes]);
725        }
726    };
727}
728
729#[cfg(feature = "audio")]
730impl_sample_for_newtype!(I16_LE, 2);
731#[cfg(feature = "audio")]
732impl_sample_for_newtype!(U16_LE, 2);
733#[cfg(feature = "audio")]
734impl_sample_for_newtype!(I16_BE, 2);
735#[cfg(feature = "audio")]
736impl_sample_for_newtype!(U16_BE, 2);
737#[cfg(feature = "audio")]
738impl_sample_for_newtype!(I24_LE, 3);
739#[cfg(feature = "audio")]
740impl_sample_for_newtype!(I24_4LJ_LE, 4);
741#[cfg(feature = "audio")]
742impl_sample_for_newtype!(I24_4RJ_LE, 4);
743#[cfg(feature = "audio")]
744impl_sample_for_newtype!(U24_LE, 3);
745#[cfg(feature = "audio")]
746impl_sample_for_newtype!(U24_4LJ_LE, 4);
747#[cfg(feature = "audio")]
748impl_sample_for_newtype!(U24_4RJ_LE, 4);
749#[cfg(feature = "audio")]
750impl_sample_for_newtype!(I24_BE, 3);
751#[cfg(feature = "audio")]
752impl_sample_for_newtype!(I24_4LJ_BE, 4);
753#[cfg(feature = "audio")]
754impl_sample_for_newtype!(I24_4RJ_BE, 4);
755#[cfg(feature = "audio")]
756impl_sample_for_newtype!(U24_BE, 3);
757#[cfg(feature = "audio")]
758impl_sample_for_newtype!(U24_4LJ_BE, 4);
759#[cfg(feature = "audio")]
760impl_sample_for_newtype!(U24_4RJ_BE, 4);
761#[cfg(feature = "audio")]
762impl_sample_for_newtype!(I32_LE, 4);
763#[cfg(feature = "audio")]
764impl_sample_for_newtype!(U32_LE, 4);
765#[cfg(feature = "audio")]
766impl_sample_for_newtype!(I32_BE, 4);
767#[cfg(feature = "audio")]
768impl_sample_for_newtype!(U32_BE, 4);
769#[cfg(feature = "audio")]
770impl_sample_for_newtype!(I64_LE, 8);
771#[cfg(feature = "audio")]
772impl_sample_for_newtype!(U64_LE, 8);
773#[cfg(feature = "audio")]
774impl_sample_for_newtype!(I64_BE, 8);
775#[cfg(feature = "audio")]
776impl_sample_for_newtype!(U64_BE, 8);
777#[cfg(feature = "audio")]
778impl_sample_for_newtype!(F32_LE, 4);
779#[cfg(feature = "audio")]
780impl_sample_for_newtype!(F32_BE, 4);
781#[cfg(feature = "audio")]
782impl_sample_for_newtype!(F64_LE, 8);
783#[cfg(feature = "audio")]
784impl_sample_for_newtype!(F64_BE, 8);
785
786#[cfg(test)]
787mod tests {
788    use super::*;
789
790    macro_rules! assert_conversion_eq {
791        ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
792            assert_eq!($result.value, $value, $desc);
793            assert_eq!($result.clipped, $clipped, $desc);
794        };
795    }
796
797    macro_rules! test_to_signed_int {
798        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
799            #[test]
800            fn $fname() {
801                let val: $float = 0.25;
802                assert_conversion_eq!(
803                    $int::from_scaled_float(val),
804                    1 << ($bits - 3),
805                    false,
806                    "check +0.25"
807                );
808                let val: $float = -0.25;
809                assert_conversion_eq!(
810                    $int::from_scaled_float(val),
811                    -1 << ($bits - 3),
812                    false,
813                    "check -0.25"
814                );
815                let val: $float = 1.1;
816                assert_conversion_eq!(
817                    $int::from_scaled_float(val),
818                    $int::MAX,
819                    true,
820                    "clipped positive"
821                );
822                let val: $float = -1.1;
823                assert_conversion_eq!(
824                    $int::from_scaled_float(val),
825                    $int::MIN,
826                    true,
827                    "clipped negative"
828                );
829            }
830        };
831    }
832
833    macro_rules! test_to_unsigned_int {
834        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
835            #[test]
836            fn $fname() {
837                let val: $float = -0.5;
838                assert_conversion_eq!(
839                    $int::from_scaled_float(val),
840                    1 << ($bits - 2),
841                    false,
842                    "check -0.5"
843                );
844                let val: $float = 0.5;
845                assert_conversion_eq!(
846                    $int::from_scaled_float(val),
847                    $int::MAX - (1 << ($bits - 2)) + 1,
848                    false,
849                    "check 0.5"
850                );
851                let val: $float = 1.1;
852                assert_conversion_eq!(
853                    $int::from_scaled_float(val),
854                    $int::MAX,
855                    true,
856                    "clipped positive"
857                );
858                let val: $float = -1.1;
859                assert_conversion_eq!(
860                    $int::from_scaled_float(val),
861                    $int::MIN,
862                    true,
863                    "clipped negative"
864                );
865            }
866        };
867    }
868
869    test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
870    test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
871    test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
872    test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
873    test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
874    test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
875    test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
876    test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
877
878    test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
879    test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
880    test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
881    test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
882    test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
883    test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
884    test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
885    test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
886
887    macro_rules! test_from_signed_int {
888        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
889            #[test]
890            fn $fname() {
891                let val: $int = -1 << ($bits - 2);
892                assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
893                let val: $int = 1 << ($bits - 2);
894                assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
895                let val: $int = $int::MIN;
896                assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
897            }
898        };
899    }
900
901    macro_rules! test_from_unsigned_int {
902        ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
903            #[test]
904            fn $fname() {
905                let val: $int = 1 << ($bits - 2);
906                assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
907                let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
908                assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
909                let val: $int = 0;
910                assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
911            }
912        };
913    }
914
915    test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
916    test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
917    test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
918    test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
919    test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
920    test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
921    test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
922    test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
923
924    test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
925    test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
926    test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
927    test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
928    test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
929    test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
930    test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
931    test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
932
933    #[test]
934    fn test_to_clamped_int() {
935        let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
936        assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
937
938        let converted = to_clamped_int::<f32, i32>(1.0e10, None);
939        assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
940
941        let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
942        assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
943
944        let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
945        assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
946
947        let converted = to_clamped_int::<f64, i32>(1.0e10, None);
948        assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
949
950        let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
951        assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
952    }
953
954    #[test]
955    fn test_to_clamped_uint() {
956        let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
957        assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
958
959        let converted = to_clamped_int::<f32, u32>(1.0e10, None);
960        assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
961
962        let converted = to_clamped_int::<f32, u32>(-1.0, None);
963        assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
964
965        let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
966        assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
967
968        let converted = to_clamped_int::<f64, u32>(1.0e10, None);
969        assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
970
971        let converted = to_clamped_int::<f64, u32>(-1.0, None);
972        assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
973    }
974
975    macro_rules! test_simple_int_bytes {
976        ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
977            #[test]
978            #[allow(non_snake_case)]
979            fn $fname() {
980                let number: $number = <$number>::MAX / 5 * 4;
981                let wrapped = $wrapper(number.$to_bytes_fn());
982                assert_eq!(number, wrapped.to_number());
983            }
984        };
985    }
986
987    macro_rules! test_float_bytes {
988        ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
989            #[test]
990            #[allow(non_snake_case)]
991            fn $fname() {
992                let number: $number = 12345.0;
993                let wrapped = $wrapper(number.$to_bytes_fn());
994                assert_eq!(number, wrapped.to_number());
995            }
996        };
997    }
998
999    test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
1000    test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
1001    test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
1002    test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
1003    test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
1004    test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1005
1006    test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1007    test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1008    test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1009    test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1010    test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1011    test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1012
1013    test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1014    test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1015    test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1016    test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1017
1018    #[test]
1019    #[allow(non_snake_case)]
1020    fn test_I24_LE() {
1021        let number = i32::MAX / 5 * 4;
1022
1023        // make sure LSB is zero
1024        let number = number >> 8;
1025        let number = number << 8;
1026
1027        let allbytes = number.to_le_bytes();
1028        // Little-endian stores the LSB at the smallest address.
1029        // Drop the LSB!
1030        let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1031
1032        let wrapped = I24_LE(bytes);
1033        assert_eq!(number, wrapped.to_number());
1034    }
1035
1036    #[test]
1037    #[allow(non_snake_case)]
1038    fn test_I24_BE() {
1039        let number = i32::MAX / 5 * 4;
1040
1041        // make sure LSB is zero
1042        let number = number >> 8;
1043        let number = number << 8;
1044
1045        let allbytes = number.to_be_bytes();
1046        // Big-endian stores the LSB at the largest address.
1047        // Drop the LSB!
1048        let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1049
1050        let wrapped = I24_BE(bytes);
1051        assert_eq!(number, wrapped.to_number());
1052    }
1053
1054    #[test]
1055    #[allow(non_snake_case)]
1056    fn test_I24_4RJ_LE() {
1057        let number = i32::MAX / 5 * 4;
1058
1059        // make sure LSB is zero
1060        let number = number >> 8;
1061        let number = number << 8;
1062
1063        let allbytes = number.to_le_bytes();
1064        // Little-endian stores the LSB at the smallest address.
1065        // Drop the LSB and insert padding at MSB!
1066        let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1067
1068        let wrapped = I24_4RJ_LE(bytes);
1069        assert_eq!(number, wrapped.to_number());
1070    }
1071
1072    #[test]
1073    #[allow(non_snake_case)]
1074    fn test_I24_4RJ_BE() {
1075        let number = i32::MAX / 5 * 4;
1076
1077        // make sure LSB is zero
1078        let number = number >> 8;
1079        let number = number << 8;
1080
1081        let allbytes = number.to_be_bytes();
1082        // Big-endian stores the LSB at the largest address.
1083        // Drop the LSB and insert padding at MSB!
1084        let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1085
1086        let wrapped = I24_4RJ_BE(bytes);
1087        assert_eq!(number, wrapped.to_number());
1088    }
1089
1090    #[test]
1091    #[allow(non_snake_case)]
1092    fn test_I24_4LJ_LE() {
1093        let number = i32::MAX / 5 * 4;
1094
1095        // make sure LSB is zero
1096        let number = number >> 8;
1097        let number = number << 8;
1098
1099        let allbytes = number.to_le_bytes();
1100        // Little-endian stores the LSB at the smallest address.
1101        // Put a zero at LSB and keep the rest unchanged.
1102        let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1103
1104        let wrapped = I24_4LJ_LE(bytes);
1105        assert_eq!(number, wrapped.to_number());
1106    }
1107
1108    #[test]
1109    #[allow(non_snake_case)]
1110    fn test_I24_4LJ_BE() {
1111        let number = i32::MAX / 5 * 4;
1112
1113        // make sure LSB is zero
1114        let number = number >> 8;
1115        let number = number << 8;
1116
1117        let allbytes = number.to_be_bytes();
1118        // Big-endian stores the LSB at the largest address.
1119        // Put a zero at LSB and keep the rest unchanged.
1120        let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1121
1122        let wrapped = I24_4LJ_BE(bytes);
1123        assert_eq!(number, wrapped.to_number());
1124    }
1125
1126    #[test]
1127    #[allow(non_snake_case)]
1128    fn test_U24_LE() {
1129        let number = u32::MAX / 5 * 4;
1130
1131        // make sure LSB is zero
1132        let number = number >> 8;
1133        let number = number << 8;
1134
1135        let allbytes = number.to_le_bytes();
1136        // Little-endian stores the LSB at the smallest address.
1137        // Drop the LSB!
1138        let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1139
1140        let wrapped = U24_LE(bytes);
1141        assert_eq!(number, wrapped.to_number());
1142    }
1143
1144    #[test]
1145    #[allow(non_snake_case)]
1146    fn test_U24_BE() {
1147        let number = u32::MAX / 5 * 4;
1148
1149        // make sure LSB is zero
1150        let number = number >> 8;
1151        let number = number << 8;
1152
1153        let allbytes = number.to_be_bytes();
1154        // Big-endian stores the LSB at the largest address.
1155        // Drop the LSB!
1156        let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1157
1158        let wrapped = U24_BE(bytes);
1159        assert_eq!(number, wrapped.to_number());
1160    }
1161
1162    #[test]
1163    #[allow(non_snake_case)]
1164    fn test_U24_4RJ_LE() {
1165        let number = u32::MAX / 5 * 4;
1166
1167        // make sure LSB is zero
1168        let number = number >> 8;
1169        let number = number << 8;
1170
1171        let allbytes = number.to_le_bytes();
1172        // Little-endian stores the LSB at the smallest address.
1173        // Drop the LSB and insert padding at MSB!
1174        let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1175
1176        let wrapped = U24_4RJ_LE(bytes);
1177        assert_eq!(number, wrapped.to_number());
1178    }
1179
1180    #[test]
1181    #[allow(non_snake_case)]
1182    fn test_U24_4RJ_BE() {
1183        let number = u32::MAX / 5 * 4;
1184
1185        // make sure LSB is zero
1186        let number = number >> 8;
1187        let number = number << 8;
1188
1189        let allbytes = number.to_be_bytes();
1190        // Big-endian stores the LSB at the largest address.
1191        // Drop the LSB and insert padding at MSB!
1192        let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1193
1194        let wrapped = U24_4RJ_BE(bytes);
1195        assert_eq!(number, wrapped.to_number());
1196    }
1197
1198    #[test]
1199    #[allow(non_snake_case)]
1200    fn test_U24_4LJ_LE() {
1201        let number = u32::MAX / 5 * 4;
1202
1203        // make sure LSB is zero
1204        let number = number >> 8;
1205        let number = number << 8;
1206
1207        let allbytes = number.to_le_bytes();
1208        // Little-endian stores the LSB at the smallest address.
1209        // Put a zero at LSB and keep the rest unchanged.
1210        let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1211
1212        let wrapped = U24_4LJ_LE(bytes);
1213        assert_eq!(number, wrapped.to_number());
1214    }
1215
1216    #[test]
1217    #[allow(non_snake_case)]
1218    fn test_U24_4LJ_BE() {
1219        let number = u32::MAX / 5 * 4;
1220
1221        // make sure LSB is zero
1222        let number = number >> 8;
1223        let number = number << 8;
1224
1225        let allbytes = number.to_be_bytes();
1226        // Big-endian stores the LSB at the largest address.
1227        // Put a zero at LSB and keep the rest unchanged.
1228        let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1229
1230        let wrapped = U24_4LJ_BE(bytes);
1231        assert_eq!(number, wrapped.to_number());
1232    }
1233}