1#![allow(non_camel_case_types)]
2
3use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
4
5#[derive(Debug, Clone, Copy)]
11#[repr(transparent)]
12pub struct I8([u8; 1]);
13
14#[derive(Debug, Clone, Copy)]
18#[repr(transparent)]
19pub struct U8([u8; 1]);
20
21#[derive(Debug, Clone, Copy)]
25#[repr(transparent)]
26pub struct I16_LE([u8; 2]);
27
28#[derive(Debug, Clone, Copy)]
30#[repr(transparent)]
31pub struct I16_BE([u8; 2]);
32
33#[derive(Debug, Clone, Copy)]
35#[repr(transparent)]
36pub struct U16_LE([u8; 2]);
37
38#[derive(Debug, Clone, Copy)]
40#[repr(transparent)]
41pub struct U16_BE([u8; 2]);
42
43#[derive(Debug, Clone, Copy)]
47#[repr(transparent)]
48pub struct I24_LE([u8; 3]);
49
50#[derive(Debug, Clone, Copy)]
54#[repr(transparent)]
55pub struct I24_4LJ_LE([u8; 4]);
56
57#[derive(Debug, Clone, Copy)]
61#[repr(transparent)]
62pub struct I24_4RJ_LE([u8; 4]);
63
64#[derive(Debug, Clone, Copy)]
66#[repr(transparent)]
67pub struct I24_BE([u8; 3]);
68
69#[derive(Debug, Clone, Copy)]
73#[repr(transparent)]
74pub struct I24_4LJ_BE([u8; 4]);
75
76#[derive(Debug, Clone, Copy)]
80#[repr(transparent)]
81pub struct I24_4RJ_BE([u8; 4]);
82
83#[derive(Debug, Clone, Copy)]
85#[repr(transparent)]
86pub struct U24_LE([u8; 3]);
87
88#[derive(Debug, Clone, Copy)]
92#[repr(transparent)]
93pub struct U24_4LJ_LE([u8; 4]);
94
95#[derive(Debug, Clone, Copy)]
99#[repr(transparent)]
100pub struct U24_4RJ_LE([u8; 4]);
101
102#[derive(Debug, Clone, Copy)]
104#[repr(transparent)]
105pub struct U24_BE([u8; 3]);
106
107#[derive(Debug, Clone, Copy)]
111#[repr(transparent)]
112pub struct U24_4LJ_BE([u8; 4]);
113
114#[derive(Debug, Clone, Copy)]
118#[repr(transparent)]
119pub struct U24_4RJ_BE([u8; 4]);
120
121#[derive(Debug, Clone, Copy)]
125#[repr(transparent)]
126pub struct I32_LE([u8; 4]);
127
128#[derive(Debug, Clone, Copy)]
130#[repr(transparent)]
131pub struct I32_BE([u8; 4]);
132
133#[derive(Debug, Clone, Copy)]
135#[repr(transparent)]
136pub struct U32_LE([u8; 4]);
137
138#[derive(Debug, Clone, Copy)]
140#[repr(transparent)]
141pub struct U32_BE([u8; 4]);
142
143#[derive(Debug, Clone, Copy)]
147#[repr(transparent)]
148pub struct I64_LE([u8; 8]);
149
150#[derive(Debug, Clone, Copy)]
152#[repr(transparent)]
153pub struct I64_BE([u8; 8]);
154
155#[derive(Debug, Clone, Copy)]
157#[repr(transparent)]
158pub struct U64_LE([u8; 8]);
159
160#[derive(Debug, Clone, Copy)]
162#[repr(transparent)]
163pub struct U64_BE([u8; 8]);
164
165#[derive(Debug, Clone, Copy)]
169#[repr(transparent)]
170pub struct F32_LE([u8; 4]);
171
172#[derive(Debug, Clone, Copy)]
174#[repr(transparent)]
175pub struct F32_BE([u8; 4]);
176
177#[derive(Debug, Clone, Copy)]
179#[repr(transparent)]
180pub struct F64_LE([u8; 8]);
181
182#[derive(Debug, Clone, Copy)]
184#[repr(transparent)]
185pub struct F64_BE([u8; 8]);
186
187fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
189 value: T,
190 converted: Option<U>,
191) -> ConversionResult<U> {
192 if let Some(val) = converted {
193 return ConversionResult {
194 clipped: false,
195 value: val,
196 };
197 }
198 if value.is_nan() {
199 return ConversionResult {
200 clipped: true,
201 value: U::zero(),
202 };
203 }
204 if value > T::zero() {
205 return ConversionResult {
206 clipped: true,
207 value: U::max_value(),
208 };
209 }
210 ConversionResult {
211 clipped: true,
212 value: U::min_value(),
213 }
214}
215
216pub struct ConversionResult<T> {
219 pub clipped: bool,
220 pub value: T,
221}
222
223pub trait RawSample
233where
234 Self: Sized,
235{
236 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
238
239 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
246}
247
248pub trait BytesSample {
260 type NumericType: Copy;
262
263 const BYTES_PER_SAMPLE: usize;
265
266 fn zero() -> Self;
272
273 fn from_slice(bytes: &[u8]) -> Self;
277
278 fn as_slice(&self) -> &[u8];
280
281 fn as_mut_slice(&mut self) -> &mut [u8];
283
284 fn to_number(&self) -> Self::NumericType;
286
287 fn from_number(value: Self::NumericType) -> Self;
289}
290
291macro_rules! rawsample_for_int {
292 ($type:ident, $to:ident) => {
293 impl RawSample for $type {
294 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
295 T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
296 }
297
298 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
299 let scaled = value * (T::from($type::MAX).unwrap() + T::one());
300 let converted = scaled.$to();
301 to_clamped_int(scaled, converted)
302 }
303 }
304 };
305}
306
307rawsample_for_int!(i8, to_i8);
308rawsample_for_int!(i16, to_i16);
309rawsample_for_int!(i32, to_i32);
310rawsample_for_int!(i64, to_i64);
311
312macro_rules! rawsample_for_uint {
313 ($type:ident, $to:ident) => {
314 impl RawSample for $type {
315 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
316 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
317 (T::from(*self).unwrap() - max_ampl) / max_ampl
318 }
319
320 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
321 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
322 let scaled = value * max_ampl + max_ampl;
323 let converted = scaled.$to();
324 to_clamped_int(scaled, converted)
325 }
326 }
327 };
328}
329
330rawsample_for_uint!(u8, to_u8);
331rawsample_for_uint!(u16, to_u16);
332rawsample_for_uint!(u32, to_u32);
333rawsample_for_uint!(u64, to_u64);
334
335macro_rules! rawsample_for_float {
336 ($type:ident, $to:ident) => {
337 impl RawSample for $type {
338 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
339 T::from(*self).unwrap_or(T::zero())
340 }
341
342 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
343 ConversionResult {
347 clipped: false,
348 value: value.$to().unwrap_or(0.0),
349 }
350 }
351 }
352 };
353}
354
355rawsample_for_float!(f32, to_f32);
356rawsample_for_float!(f64, to_f64);
357
358impl BytesSample for I24_4RJ_LE {
364 type NumericType = i32;
365 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
366
367 fn zero() -> Self {
368 Self(Default::default())
369 }
370
371 fn from_slice(bytes: &[u8]) -> Self {
372 Self(bytes[0..4].try_into().unwrap())
373 }
374
375 fn as_slice(&self) -> &[u8] {
376 &self.0
377 }
378
379 fn as_mut_slice(&mut self) -> &mut [u8] {
380 &mut self.0
381 }
382
383 fn to_number(&self) -> Self::NumericType {
384 let padded = [0, self.0[0], self.0[1], self.0[2]];
385 i32::from_le_bytes(padded)
386 }
387
388 fn from_number(value: Self::NumericType) -> Self {
389 let bytes = value.to_le_bytes();
390 Self([bytes[1], bytes[2], bytes[3], 0])
391 }
392}
393
394impl BytesSample for I24_4LJ_LE {
397 type NumericType = i32;
398 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
399
400 fn zero() -> Self {
401 Self(Default::default())
402 }
403
404 fn from_slice(bytes: &[u8]) -> Self {
405 Self(bytes[0..4].try_into().unwrap())
406 }
407
408 fn as_slice(&self) -> &[u8] {
409 &self.0
410 }
411
412 fn as_mut_slice(&mut self) -> &mut [u8] {
413 &mut self.0
414 }
415
416 fn to_number(&self) -> Self::NumericType {
417 let padded = [0, self.0[1], self.0[2], self.0[3]];
418 i32::from_le_bytes(padded)
419 }
420
421 fn from_number(value: Self::NumericType) -> Self {
422 let bytes = value.to_le_bytes();
423 Self([0, bytes[1], bytes[2], bytes[3]])
424 }
425}
426
427impl BytesSample for I24_LE {
429 type NumericType = i32;
430 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
431
432 fn zero() -> Self {
433 Self(Default::default())
434 }
435
436 fn from_slice(bytes: &[u8]) -> Self {
437 Self(bytes[0..3].try_into().unwrap())
438 }
439
440 fn as_slice(&self) -> &[u8] {
441 &self.0
442 }
443
444 fn as_mut_slice(&mut self) -> &mut [u8] {
445 &mut self.0
446 }
447
448 fn to_number(&self) -> Self::NumericType {
449 let padded = [0, self.0[0], self.0[1], self.0[2]];
450 i32::from_le_bytes(padded)
451 }
452
453 fn from_number(value: Self::NumericType) -> Self {
454 let bytes = value.to_le_bytes();
455 Self([bytes[1], bytes[2], bytes[3]])
456 }
457}
458
459impl BytesSample for I24_4RJ_BE {
462 type NumericType = i32;
463 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
464
465 fn zero() -> Self {
466 Self(Default::default())
467 }
468
469 fn from_slice(bytes: &[u8]) -> Self {
470 Self(bytes[0..4].try_into().unwrap())
471 }
472
473 fn as_slice(&self) -> &[u8] {
474 &self.0
475 }
476
477 fn as_mut_slice(&mut self) -> &mut [u8] {
478 &mut self.0
479 }
480
481 fn to_number(&self) -> Self::NumericType {
482 let padded = [self.0[1], self.0[2], self.0[3], 0];
483 i32::from_be_bytes(padded)
484 }
485
486 fn from_number(value: Self::NumericType) -> Self {
487 let bytes = value.to_be_bytes();
488 Self([0, bytes[0], bytes[1], bytes[2]])
489 }
490}
491
492impl BytesSample for I24_4LJ_BE {
495 type NumericType = i32;
496 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
497
498 fn zero() -> Self {
499 Self(Default::default())
500 }
501
502 fn from_slice(bytes: &[u8]) -> Self {
503 Self(bytes[0..4].try_into().unwrap())
504 }
505
506 fn as_slice(&self) -> &[u8] {
507 &self.0
508 }
509
510 fn as_mut_slice(&mut self) -> &mut [u8] {
511 &mut self.0
512 }
513
514 fn to_number(&self) -> Self::NumericType {
515 let padded = [self.0[0], self.0[1], self.0[2], 0];
516 i32::from_be_bytes(padded)
517 }
518
519 fn from_number(value: Self::NumericType) -> Self {
520 let bytes = value.to_be_bytes();
521 Self([bytes[0], bytes[1], bytes[2], 0])
522 }
523}
524
525impl BytesSample for I24_BE {
527 type NumericType = i32;
528 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
529
530 fn zero() -> Self {
531 Self(Default::default())
532 }
533
534 fn from_slice(bytes: &[u8]) -> Self {
535 Self(bytes[0..3].try_into().unwrap())
536 }
537
538 fn as_slice(&self) -> &[u8] {
539 &self.0
540 }
541
542 fn as_mut_slice(&mut self) -> &mut [u8] {
543 &mut self.0
544 }
545
546 fn to_number(&self) -> Self::NumericType {
547 let padded = [self.0[0], self.0[1], self.0[2], 0];
548 i32::from_be_bytes(padded)
549 }
550
551 fn from_number(value: Self::NumericType) -> Self {
552 let bytes = value.to_be_bytes();
553 Self([bytes[0], bytes[1], bytes[2]])
554 }
555}
556
557impl BytesSample for U24_4RJ_LE {
560 type NumericType = u32;
561 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
562
563 fn zero() -> Self {
564 Self(Default::default())
565 }
566
567 fn from_slice(bytes: &[u8]) -> Self {
568 Self(bytes[0..4].try_into().unwrap())
569 }
570
571 fn as_slice(&self) -> &[u8] {
572 &self.0
573 }
574
575 fn as_mut_slice(&mut self) -> &mut [u8] {
576 &mut self.0
577 }
578
579 fn to_number(&self) -> Self::NumericType {
580 let padded = [0, self.0[0], self.0[1], self.0[2]];
581 u32::from_le_bytes(padded)
582 }
583
584 fn from_number(value: Self::NumericType) -> Self {
585 let bytes = value.to_le_bytes();
586 Self([bytes[1], bytes[2], bytes[3], 0])
587 }
588}
589
590impl BytesSample for U24_4LJ_LE {
593 type NumericType = u32;
594 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
595
596 fn zero() -> Self {
597 Self(Default::default())
598 }
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 = [0, self.0[1], self.0[2], self.0[3]];
614 u32::from_le_bytes(padded)
615 }
616
617 fn from_number(value: Self::NumericType) -> Self {
618 let bytes = value.to_le_bytes();
619 Self([0, bytes[1], bytes[2], bytes[3]])
620 }
621}
622
623impl BytesSample for U24_LE {
625 type NumericType = u32;
626 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
627
628 fn zero() -> Self {
629 Self(Default::default())
630 }
631
632 fn from_slice(bytes: &[u8]) -> Self {
633 Self(bytes[0..3].try_into().unwrap())
634 }
635
636 fn as_slice(&self) -> &[u8] {
637 &self.0
638 }
639
640 fn as_mut_slice(&mut self) -> &mut [u8] {
641 &mut self.0
642 }
643
644 fn to_number(&self) -> Self::NumericType {
645 let padded = [0, self.0[0], self.0[1], self.0[2]];
646 u32::from_le_bytes(padded)
647 }
648
649 fn from_number(value: Self::NumericType) -> Self {
650 let bytes = value.to_le_bytes();
651 Self([bytes[1], bytes[2], bytes[3]])
652 }
653}
654
655impl BytesSample for U24_4RJ_BE {
658 type NumericType = u32;
659 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
660
661 fn zero() -> Self {
662 Self(Default::default())
663 }
664
665 fn from_slice(bytes: &[u8]) -> Self {
666 Self(bytes[0..4].try_into().unwrap())
667 }
668
669 fn as_slice(&self) -> &[u8] {
670 &self.0
671 }
672
673 fn as_mut_slice(&mut self) -> &mut [u8] {
674 &mut self.0
675 }
676
677 fn to_number(&self) -> Self::NumericType {
678 let padded = [self.0[1], self.0[2], self.0[3], 0];
679 u32::from_be_bytes(padded)
680 }
681
682 fn from_number(value: Self::NumericType) -> Self {
683 let bytes = value.to_be_bytes();
684 Self([0, bytes[0], bytes[1], bytes[2]])
685 }
686}
687
688impl BytesSample for U24_4LJ_BE {
691 type NumericType = u32;
692 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
693
694 fn zero() -> Self {
695 Self(Default::default())
696 }
697
698 fn from_slice(bytes: &[u8]) -> Self {
699 Self(bytes[0..4].try_into().unwrap())
700 }
701
702 fn as_slice(&self) -> &[u8] {
703 &self.0
704 }
705
706 fn as_mut_slice(&mut self) -> &mut [u8] {
707 &mut self.0
708 }
709
710 fn to_number(&self) -> Self::NumericType {
711 let padded = [self.0[0], self.0[1], self.0[2], 0];
712 u32::from_be_bytes(padded)
713 }
714
715 fn from_number(value: Self::NumericType) -> Self {
716 let bytes = value.to_be_bytes();
717 Self([bytes[0], bytes[1], bytes[2], 0])
718 }
719}
720
721impl BytesSample for U24_BE {
723 type NumericType = u32;
724 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
725
726 fn zero() -> Self {
727 Self(Default::default())
728 }
729
730 fn from_slice(bytes: &[u8]) -> Self {
731 Self(bytes[0..3].try_into().unwrap())
732 }
733
734 fn as_slice(&self) -> &[u8] {
735 &self.0
736 }
737
738 fn as_mut_slice(&mut self) -> &mut [u8] {
739 &mut self.0
740 }
741
742 fn to_number(&self) -> Self::NumericType {
743 let padded = [self.0[0], self.0[1], self.0[2], 0];
744 u32::from_be_bytes(padded)
745 }
746
747 fn from_number(value: Self::NumericType) -> Self {
748 let bytes = value.to_be_bytes();
749 Self([bytes[0], bytes[1], bytes[2]])
750 }
751}
752
753macro_rules! bytessample_for_newtype {
754 ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
755 impl BytesSample for $newtype {
756 type NumericType = $type;
757 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
758
759 fn zero() -> Self {
760 Self(Default::default())
761 }
762
763 fn from_slice(bytes: &[u8]) -> Self {
764 Self(bytes.try_into().unwrap())
765 }
766
767 fn as_slice(&self) -> &[u8] {
768 &self.0
769 }
770
771 fn as_mut_slice(&mut self) -> &mut [u8] {
772 &mut self.0
773 }
774
775 fn to_number(&self) -> Self::NumericType {
776 $type::$from(self.0)
777 }
778
779 fn from_number(value: Self::NumericType) -> Self {
780 Self(value.$to())
781 }
782 }
783 };
784}
785
786bytessample_for_newtype!(i8, I8, from_le_bytes, to_le_bytes);
788bytessample_for_newtype!(u8, U8, from_le_bytes, to_le_bytes);
789
790bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
791bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
792bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
793bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
794
795bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
796bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
797bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
798bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
799
800bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
801bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
802bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
803bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
804
805bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
806bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
807bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
808bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
809
810impl<V> RawSample for V
811where
812 V: BytesSample,
813 <V as BytesSample>::NumericType: RawSample,
814{
815 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
816 let value = self.to_number();
817 value.to_scaled_float()
818 }
819
820 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
821 let value = <V as BytesSample>::NumericType::from_scaled_float(value);
822 ConversionResult {
823 clipped: value.clipped,
824 value: V::from_number(value.value),
825 }
826 }
827}
828
829#[cfg(test)]
830mod tests {
831 use super::*;
832
833 macro_rules! assert_conversion_eq {
834 ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
835 assert_eq!($result.value, $value, $desc);
836 assert_eq!($result.clipped, $clipped, $desc);
837 };
838 }
839
840 macro_rules! test_to_signed_int {
841 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
842 #[test]
843 fn $fname() {
844 let val: $float = 0.25;
845 assert_conversion_eq!(
846 $int::from_scaled_float(val),
847 1 << ($bits - 3),
848 false,
849 "check +0.25"
850 );
851 let val: $float = -0.25;
852 assert_conversion_eq!(
853 $int::from_scaled_float(val),
854 -1 << ($bits - 3),
855 false,
856 "check -0.25"
857 );
858 let val: $float = 1.1;
859 assert_conversion_eq!(
860 $int::from_scaled_float(val),
861 $int::MAX,
862 true,
863 "clipped positive"
864 );
865 let val: $float = -1.1;
866 assert_conversion_eq!(
867 $int::from_scaled_float(val),
868 $int::MIN,
869 true,
870 "clipped negative"
871 );
872 }
873 };
874 }
875
876 macro_rules! test_to_unsigned_int {
877 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
878 #[test]
879 fn $fname() {
880 let val: $float = -0.5;
881 assert_conversion_eq!(
882 $int::from_scaled_float(val),
883 1 << ($bits - 2),
884 false,
885 "check -0.5"
886 );
887 let val: $float = 0.5;
888 assert_conversion_eq!(
889 $int::from_scaled_float(val),
890 $int::MAX - (1 << ($bits - 2)) + 1,
891 false,
892 "check 0.5"
893 );
894 let val: $float = 1.1;
895 assert_conversion_eq!(
896 $int::from_scaled_float(val),
897 $int::MAX,
898 true,
899 "clipped positive"
900 );
901 let val: $float = -1.1;
902 assert_conversion_eq!(
903 $int::from_scaled_float(val),
904 $int::MIN,
905 true,
906 "clipped negative"
907 );
908 }
909 };
910 }
911
912 test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
913 test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
914 test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
915 test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
916 test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
917 test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
918 test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
919 test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
920
921 test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
922 test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
923 test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
924 test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
925 test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
926 test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
927 test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
928 test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
929
930 macro_rules! test_from_signed_int {
931 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
932 #[test]
933 fn $fname() {
934 let val: $int = -1 << ($bits - 2);
935 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
936 let val: $int = 1 << ($bits - 2);
937 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
938 let val: $int = $int::MIN;
939 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
940 }
941 };
942 }
943
944 macro_rules! test_from_unsigned_int {
945 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
946 #[test]
947 fn $fname() {
948 let val: $int = 1 << ($bits - 2);
949 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
950 let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
951 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
952 let val: $int = 0;
953 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
954 }
955 };
956 }
957
958 test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
959 test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
960 test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
961 test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
962 test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
963 test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
964 test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
965 test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
966
967 test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
968 test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
969 test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
970 test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
971 test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
972 test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
973 test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
974 test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
975
976 #[test]
977 fn test_to_clamped_int() {
978 let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
979 assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
980
981 let converted = to_clamped_int::<f32, i32>(1.0e10, None);
982 assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
983
984 let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
985 assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
986
987 let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
988 assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
989
990 let converted = to_clamped_int::<f64, i32>(1.0e10, None);
991 assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
992
993 let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
994 assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
995 }
996
997 #[test]
998 fn test_to_clamped_uint() {
999 let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
1000 assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
1001
1002 let converted = to_clamped_int::<f32, u32>(1.0e10, None);
1003 assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
1004
1005 let converted = to_clamped_int::<f32, u32>(-1.0, None);
1006 assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
1007
1008 let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
1009 assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
1010
1011 let converted = to_clamped_int::<f64, u32>(1.0e10, None);
1012 assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
1013
1014 let converted = to_clamped_int::<f64, u32>(-1.0, None);
1015 assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
1016 }
1017
1018 macro_rules! test_simple_int_bytes {
1019 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1020 #[test]
1021 #[allow(non_snake_case)]
1022 fn $fname() {
1023 let number: $number = <$number>::MAX / 5 * 4;
1024 let wrapped = $wrapper(number.$to_bytes_fn());
1025 assert_eq!(number, wrapped.to_number());
1026 }
1027 };
1028 }
1029
1030 macro_rules! test_float_bytes {
1031 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1032 #[test]
1033 #[allow(non_snake_case)]
1034 fn $fname() {
1035 let number: $number = 12345.0;
1036 let wrapped = $wrapper(number.$to_bytes_fn());
1037 assert_eq!(number, wrapped.to_number());
1038 }
1039 };
1040 }
1041
1042 test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
1043 test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
1044 test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
1045 test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
1046 test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
1047 test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1048
1049 test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1050 test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1051 test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1052 test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1053 test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1054 test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1055
1056 test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1057 test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1058 test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1059 test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1060
1061 #[test]
1062 #[allow(non_snake_case)]
1063 fn test_I8() {
1064 assert_eq!(I8::BYTES_PER_SAMPLE, 1);
1065 assert_eq!(I8::zero().to_number(), 0);
1066 assert_eq!(I8::from_slice(&[0x80]).to_number(), i8::MIN);
1067
1068 for number in [0, 1, -1, 100, i8::MIN, i8::MAX] {
1069 let wrapped = I8::from_number(number);
1070 assert_eq!(
1071 wrapped.as_slice(),
1072 number.to_le_bytes(),
1073 "bytes for {number}"
1074 );
1075 assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1076 }
1077 }
1078
1079 #[test]
1080 #[allow(non_snake_case)]
1081 fn test_U8() {
1082 assert_eq!(U8::BYTES_PER_SAMPLE, 1);
1083 assert_eq!(U8::zero().to_number(), 0);
1084 assert_eq!(U8::from_slice(&[0x80]).to_number(), 128);
1085
1086 for number in [0, 1, 128, 200, u8::MAX] {
1087 let wrapped = U8::from_number(number);
1088 assert_eq!(
1089 wrapped.as_slice(),
1090 number.to_le_bytes(),
1091 "bytes for {number}"
1092 );
1093 assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1094 }
1095 }
1096
1097 #[test]
1098 #[allow(non_snake_case)]
1099 fn convert_I8_to_and_from_float() {
1100 assert_eq!(I8::from_slice(&[0]).to_scaled_float::<f32>(), 0.0);
1101 assert_eq!(I8::from_slice(&[0x80]).to_scaled_float::<f32>(), -1.0);
1102 assert_eq!(I8::from_slice(&[0x40]).to_scaled_float::<f32>(), 0.5);
1103 assert_eq!(I8::from_slice(&[0xC0]).to_scaled_float::<f32>(), -0.5);
1104
1105 let converted = I8::from_scaled_float(0.5f32);
1106 assert_eq!(converted.value.as_slice(), [0x40]);
1107 assert!(!converted.clipped);
1108
1109 let converted = I8::from_scaled_float(-1.0f32);
1110 assert_eq!(converted.value.as_slice(), [0x80]);
1111 assert!(!converted.clipped);
1112
1113 let converted = I8::from_scaled_float(1.5f32);
1115 assert_eq!(converted.value.to_number(), i8::MAX);
1116 assert!(converted.clipped);
1117
1118 let converted = I8::from_scaled_float(-1.5f32);
1119 assert_eq!(converted.value.to_number(), i8::MIN);
1120 assert!(converted.clipped);
1121 }
1122
1123 #[test]
1124 #[allow(non_snake_case)]
1125 fn convert_U8_to_and_from_float() {
1126 assert_eq!(U8::from_slice(&[128]).to_scaled_float::<f32>(), 0.0);
1128 assert_eq!(U8::from_slice(&[0]).to_scaled_float::<f32>(), -1.0);
1129 assert_eq!(U8::from_slice(&[192]).to_scaled_float::<f32>(), 0.5);
1130 assert_eq!(U8::from_slice(&[64]).to_scaled_float::<f32>(), -0.5);
1131
1132 let converted = U8::from_scaled_float(0.5f32);
1133 assert_eq!(converted.value.as_slice(), [192]);
1134 assert!(!converted.clipped);
1135
1136 let converted = U8::from_scaled_float(-1.0f32);
1137 assert_eq!(converted.value.as_slice(), [0]);
1138 assert!(!converted.clipped);
1139
1140 let converted = U8::from_scaled_float(1.5f32);
1142 assert_eq!(converted.value.to_number(), u8::MAX);
1143 assert!(converted.clipped);
1144
1145 let converted = U8::from_scaled_float(-1.5f32);
1146 assert_eq!(converted.value.to_number(), u8::MIN);
1147 assert!(converted.clipped);
1148 }
1149
1150 #[test]
1151 #[allow(non_snake_case)]
1152 fn test_I24_LE() {
1153 let number = i32::MAX / 5 * 4;
1154
1155 let number = number >> 8;
1157 let number = number << 8;
1158
1159 let allbytes = number.to_le_bytes();
1160 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1163
1164 let wrapped = I24_LE(bytes);
1165 assert_eq!(number, wrapped.to_number());
1166 }
1167
1168 #[test]
1169 #[allow(non_snake_case)]
1170 fn test_I24_BE() {
1171 let number = i32::MAX / 5 * 4;
1172
1173 let number = number >> 8;
1175 let number = number << 8;
1176
1177 let allbytes = number.to_be_bytes();
1178 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1181
1182 let wrapped = I24_BE(bytes);
1183 assert_eq!(number, wrapped.to_number());
1184 }
1185
1186 #[test]
1187 #[allow(non_snake_case)]
1188 fn test_I24_4RJ_LE() {
1189 let number = i32::MAX / 5 * 4;
1190
1191 let number = number >> 8;
1193 let number = number << 8;
1194
1195 let allbytes = number.to_le_bytes();
1196 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1199
1200 let wrapped = I24_4RJ_LE(bytes);
1201 assert_eq!(number, wrapped.to_number());
1202 }
1203
1204 #[test]
1205 #[allow(non_snake_case)]
1206 fn test_I24_4RJ_BE() {
1207 let number = i32::MAX / 5 * 4;
1208
1209 let number = number >> 8;
1211 let number = number << 8;
1212
1213 let allbytes = number.to_be_bytes();
1214 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1217
1218 let wrapped = I24_4RJ_BE(bytes);
1219 assert_eq!(number, wrapped.to_number());
1220 }
1221
1222 #[test]
1223 #[allow(non_snake_case)]
1224 fn test_I24_4LJ_LE() {
1225 let number = i32::MAX / 5 * 4;
1226
1227 let number = number >> 8;
1229 let number = number << 8;
1230
1231 let allbytes = number.to_le_bytes();
1232 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1235
1236 let wrapped = I24_4LJ_LE(bytes);
1237 assert_eq!(number, wrapped.to_number());
1238 }
1239
1240 #[test]
1241 #[allow(non_snake_case)]
1242 fn test_I24_4LJ_BE() {
1243 let number = i32::MAX / 5 * 4;
1244
1245 let number = number >> 8;
1247 let number = number << 8;
1248
1249 let allbytes = number.to_be_bytes();
1250 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1253
1254 let wrapped = I24_4LJ_BE(bytes);
1255 assert_eq!(number, wrapped.to_number());
1256 }
1257
1258 #[test]
1259 #[allow(non_snake_case)]
1260 fn test_U24_LE() {
1261 let number = u32::MAX / 5 * 4;
1262
1263 let number = number >> 8;
1265 let number = number << 8;
1266
1267 let allbytes = number.to_le_bytes();
1268 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1271
1272 let wrapped = U24_LE(bytes);
1273 assert_eq!(number, wrapped.to_number());
1274 }
1275
1276 #[test]
1277 #[allow(non_snake_case)]
1278 fn test_U24_BE() {
1279 let number = u32::MAX / 5 * 4;
1280
1281 let number = number >> 8;
1283 let number = number << 8;
1284
1285 let allbytes = number.to_be_bytes();
1286 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1289
1290 let wrapped = U24_BE(bytes);
1291 assert_eq!(number, wrapped.to_number());
1292 }
1293
1294 #[test]
1295 #[allow(non_snake_case)]
1296 fn test_U24_4RJ_LE() {
1297 let number = u32::MAX / 5 * 4;
1298
1299 let number = number >> 8;
1301 let number = number << 8;
1302
1303 let allbytes = number.to_le_bytes();
1304 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1307
1308 let wrapped = U24_4RJ_LE(bytes);
1309 assert_eq!(number, wrapped.to_number());
1310 }
1311
1312 #[test]
1313 #[allow(non_snake_case)]
1314 fn test_U24_4RJ_BE() {
1315 let number = u32::MAX / 5 * 4;
1316
1317 let number = number >> 8;
1319 let number = number << 8;
1320
1321 let allbytes = number.to_be_bytes();
1322 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1325
1326 let wrapped = U24_4RJ_BE(bytes);
1327 assert_eq!(number, wrapped.to_number());
1328 }
1329
1330 #[test]
1331 #[allow(non_snake_case)]
1332 fn test_U24_4LJ_LE() {
1333 let number = u32::MAX / 5 * 4;
1334
1335 let number = number >> 8;
1337 let number = number << 8;
1338
1339 let allbytes = number.to_le_bytes();
1340 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1343
1344 let wrapped = U24_4LJ_LE(bytes);
1345 assert_eq!(number, wrapped.to_number());
1346 }
1347
1348 #[test]
1349 #[allow(non_snake_case)]
1350 fn test_U24_4LJ_BE() {
1351 let number = u32::MAX / 5 * 4;
1352
1353 let number = number >> 8;
1355 let number = number << 8;
1356
1357 let allbytes = number.to_be_bytes();
1358 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1361
1362 let wrapped = U24_4LJ_BE(bytes);
1363 assert_eq!(number, wrapped.to_number());
1364 }
1365}