audioadapter_sample/
sample.rs

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