1#![allow(non_camel_case_types)]
2
3use audio_codec_algorithms::{decode_alaw, decode_ulaw, encode_alaw, encode_ulaw};
4use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
5
6#[derive(Debug, Clone, Copy)]
12#[repr(transparent)]
13pub struct I8([u8; 1]);
14
15#[derive(Debug, Clone, Copy)]
19#[repr(transparent)]
20pub struct U8([u8; 1]);
21
22#[derive(Debug, Clone, Copy)]
26#[repr(transparent)]
27pub struct I16_LE([u8; 2]);
28
29#[derive(Debug, Clone, Copy)]
31#[repr(transparent)]
32pub struct I16_BE([u8; 2]);
33
34#[derive(Debug, Clone, Copy)]
36#[repr(transparent)]
37pub struct U16_LE([u8; 2]);
38
39#[derive(Debug, Clone, Copy)]
41#[repr(transparent)]
42pub struct U16_BE([u8; 2]);
43
44#[derive(Debug, Clone, Copy)]
48#[repr(transparent)]
49pub struct I24_LE([u8; 3]);
50
51#[derive(Debug, Clone, Copy)]
55#[repr(transparent)]
56pub struct I24_4LJ_LE([u8; 4]);
57
58#[derive(Debug, Clone, Copy)]
62#[repr(transparent)]
63pub struct I24_4RJ_LE([u8; 4]);
64
65#[derive(Debug, Clone, Copy)]
67#[repr(transparent)]
68pub struct I24_BE([u8; 3]);
69
70#[derive(Debug, Clone, Copy)]
74#[repr(transparent)]
75pub struct I24_4LJ_BE([u8; 4]);
76
77#[derive(Debug, Clone, Copy)]
81#[repr(transparent)]
82pub struct I24_4RJ_BE([u8; 4]);
83
84#[derive(Debug, Clone, Copy)]
86#[repr(transparent)]
87pub struct U24_LE([u8; 3]);
88
89#[derive(Debug, Clone, Copy)]
93#[repr(transparent)]
94pub struct U24_4LJ_LE([u8; 4]);
95
96#[derive(Debug, Clone, Copy)]
100#[repr(transparent)]
101pub struct U24_4RJ_LE([u8; 4]);
102
103#[derive(Debug, Clone, Copy)]
105#[repr(transparent)]
106pub struct U24_BE([u8; 3]);
107
108#[derive(Debug, Clone, Copy)]
112#[repr(transparent)]
113pub struct U24_4LJ_BE([u8; 4]);
114
115#[derive(Debug, Clone, Copy)]
119#[repr(transparent)]
120pub struct U24_4RJ_BE([u8; 4]);
121
122#[derive(Debug, Clone, Copy)]
126#[repr(transparent)]
127pub struct I32_LE([u8; 4]);
128
129#[derive(Debug, Clone, Copy)]
131#[repr(transparent)]
132pub struct I32_BE([u8; 4]);
133
134#[derive(Debug, Clone, Copy)]
136#[repr(transparent)]
137pub struct U32_LE([u8; 4]);
138
139#[derive(Debug, Clone, Copy)]
141#[repr(transparent)]
142pub struct U32_BE([u8; 4]);
143
144#[derive(Debug, Clone, Copy)]
148#[repr(transparent)]
149pub struct I64_LE([u8; 8]);
150
151#[derive(Debug, Clone, Copy)]
153#[repr(transparent)]
154pub struct I64_BE([u8; 8]);
155
156#[derive(Debug, Clone, Copy)]
158#[repr(transparent)]
159pub struct U64_LE([u8; 8]);
160
161#[derive(Debug, Clone, Copy)]
163#[repr(transparent)]
164pub struct U64_BE([u8; 8]);
165
166#[derive(Debug, Clone, Copy)]
170#[repr(transparent)]
171pub struct F32_LE([u8; 4]);
172
173#[derive(Debug, Clone, Copy)]
175#[repr(transparent)]
176pub struct F32_BE([u8; 4]);
177
178#[derive(Debug, Clone, Copy)]
180#[repr(transparent)]
181pub struct F64_LE([u8; 8]);
182
183#[derive(Debug, Clone, Copy)]
185#[repr(transparent)]
186pub struct F64_BE([u8; 8]);
187
188#[derive(Debug, Clone, Copy)]
214#[repr(transparent)]
215pub struct ALAW([u8; 1]);
216
217#[derive(Debug, Clone, Copy)]
239#[repr(transparent)]
240pub struct MULAW([u8; 1]);
241
242fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
244 value: T,
245 converted: Option<U>,
246) -> ConversionResult<U> {
247 if let Some(val) = converted {
248 return ConversionResult {
249 clipped: false,
250 value: val,
251 };
252 }
253 if value.is_nan() {
254 return ConversionResult {
255 clipped: true,
256 value: U::zero(),
257 };
258 }
259 if value > T::zero() {
260 return ConversionResult {
261 clipped: true,
262 value: U::max_value(),
263 };
264 }
265 ConversionResult {
266 clipped: true,
267 value: U::min_value(),
268 }
269}
270
271pub struct ConversionResult<T> {
274 pub clipped: bool,
275 pub value: T,
276}
277
278pub trait RawSample
288where
289 Self: Sized,
290{
291 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
293
294 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
301}
302
303pub trait BytesSample {
315 type NumericType: Copy;
317
318 const BYTES_PER_SAMPLE: usize;
320
321 fn zero() -> Self;
327
328 fn from_slice(bytes: &[u8]) -> Self;
332
333 fn as_slice(&self) -> &[u8];
335
336 fn as_mut_slice(&mut self) -> &mut [u8];
338
339 fn to_number(&self) -> Self::NumericType;
341
342 fn from_number(value: Self::NumericType) -> Self;
344}
345
346macro_rules! rawsample_for_int {
347 ($type:ident, $to:ident) => {
348 impl RawSample for $type {
349 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
350 T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
351 }
352
353 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
354 let scaled = value * (T::from($type::MAX).unwrap() + T::one());
355 let converted = scaled.$to();
356 to_clamped_int(scaled, converted)
357 }
358 }
359 };
360}
361
362rawsample_for_int!(i8, to_i8);
363rawsample_for_int!(i16, to_i16);
364rawsample_for_int!(i32, to_i32);
365rawsample_for_int!(i64, to_i64);
366
367macro_rules! rawsample_for_uint {
368 ($type:ident, $to:ident) => {
369 impl RawSample for $type {
370 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
371 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
372 (T::from(*self).unwrap() - max_ampl) / max_ampl
373 }
374
375 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
376 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
377 let scaled = value * max_ampl + max_ampl;
378 let converted = scaled.$to();
379 to_clamped_int(scaled, converted)
380 }
381 }
382 };
383}
384
385rawsample_for_uint!(u8, to_u8);
386rawsample_for_uint!(u16, to_u16);
387rawsample_for_uint!(u32, to_u32);
388rawsample_for_uint!(u64, to_u64);
389
390macro_rules! rawsample_for_float {
391 ($type:ident, $to:ident) => {
392 impl RawSample for $type {
393 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
394 T::from(*self).unwrap_or(T::zero())
395 }
396
397 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
398 ConversionResult {
402 clipped: false,
403 value: value.$to().unwrap_or(0.0),
404 }
405 }
406 }
407 };
408}
409
410rawsample_for_float!(f32, to_f32);
411rawsample_for_float!(f64, to_f64);
412
413impl BytesSample for I24_4RJ_LE {
419 type NumericType = i32;
420 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
421
422 fn zero() -> Self {
423 Self(Default::default())
424 }
425
426 fn from_slice(bytes: &[u8]) -> Self {
427 Self(bytes[0..4].try_into().unwrap())
428 }
429
430 fn as_slice(&self) -> &[u8] {
431 &self.0
432 }
433
434 fn as_mut_slice(&mut self) -> &mut [u8] {
435 &mut self.0
436 }
437
438 fn to_number(&self) -> Self::NumericType {
439 let padded = [0, self.0[0], self.0[1], self.0[2]];
440 i32::from_le_bytes(padded)
441 }
442
443 fn from_number(value: Self::NumericType) -> Self {
444 let bytes = value.to_le_bytes();
445 Self([bytes[1], bytes[2], bytes[3], 0])
446 }
447}
448
449impl BytesSample for I24_4LJ_LE {
452 type NumericType = i32;
453 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
454
455 fn zero() -> Self {
456 Self(Default::default())
457 }
458
459 fn from_slice(bytes: &[u8]) -> Self {
460 Self(bytes[0..4].try_into().unwrap())
461 }
462
463 fn as_slice(&self) -> &[u8] {
464 &self.0
465 }
466
467 fn as_mut_slice(&mut self) -> &mut [u8] {
468 &mut self.0
469 }
470
471 fn to_number(&self) -> Self::NumericType {
472 let padded = [0, self.0[1], self.0[2], self.0[3]];
473 i32::from_le_bytes(padded)
474 }
475
476 fn from_number(value: Self::NumericType) -> Self {
477 let bytes = value.to_le_bytes();
478 Self([0, bytes[1], bytes[2], bytes[3]])
479 }
480}
481
482impl BytesSample for I24_LE {
484 type NumericType = i32;
485 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
486
487 fn zero() -> Self {
488 Self(Default::default())
489 }
490
491 fn from_slice(bytes: &[u8]) -> Self {
492 Self(bytes[0..3].try_into().unwrap())
493 }
494
495 fn as_slice(&self) -> &[u8] {
496 &self.0
497 }
498
499 fn as_mut_slice(&mut self) -> &mut [u8] {
500 &mut self.0
501 }
502
503 fn to_number(&self) -> Self::NumericType {
504 let padded = [0, self.0[0], self.0[1], self.0[2]];
505 i32::from_le_bytes(padded)
506 }
507
508 fn from_number(value: Self::NumericType) -> Self {
509 let bytes = value.to_le_bytes();
510 Self([bytes[1], bytes[2], bytes[3]])
511 }
512}
513
514impl BytesSample for I24_4RJ_BE {
517 type NumericType = i32;
518 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
519
520 fn zero() -> Self {
521 Self(Default::default())
522 }
523
524 fn from_slice(bytes: &[u8]) -> Self {
525 Self(bytes[0..4].try_into().unwrap())
526 }
527
528 fn as_slice(&self) -> &[u8] {
529 &self.0
530 }
531
532 fn as_mut_slice(&mut self) -> &mut [u8] {
533 &mut self.0
534 }
535
536 fn to_number(&self) -> Self::NumericType {
537 let padded = [self.0[1], self.0[2], self.0[3], 0];
538 i32::from_be_bytes(padded)
539 }
540
541 fn from_number(value: Self::NumericType) -> Self {
542 let bytes = value.to_be_bytes();
543 Self([0, bytes[0], bytes[1], bytes[2]])
544 }
545}
546
547impl BytesSample for I24_4LJ_BE {
550 type NumericType = i32;
551 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
552
553 fn zero() -> Self {
554 Self(Default::default())
555 }
556
557 fn from_slice(bytes: &[u8]) -> Self {
558 Self(bytes[0..4].try_into().unwrap())
559 }
560
561 fn as_slice(&self) -> &[u8] {
562 &self.0
563 }
564
565 fn as_mut_slice(&mut self) -> &mut [u8] {
566 &mut self.0
567 }
568
569 fn to_number(&self) -> Self::NumericType {
570 let padded = [self.0[0], self.0[1], self.0[2], 0];
571 i32::from_be_bytes(padded)
572 }
573
574 fn from_number(value: Self::NumericType) -> Self {
575 let bytes = value.to_be_bytes();
576 Self([bytes[0], bytes[1], bytes[2], 0])
577 }
578}
579
580impl BytesSample for I24_BE {
582 type NumericType = i32;
583 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
584
585 fn zero() -> Self {
586 Self(Default::default())
587 }
588
589 fn from_slice(bytes: &[u8]) -> Self {
590 Self(bytes[0..3].try_into().unwrap())
591 }
592
593 fn as_slice(&self) -> &[u8] {
594 &self.0
595 }
596
597 fn as_mut_slice(&mut self) -> &mut [u8] {
598 &mut self.0
599 }
600
601 fn to_number(&self) -> Self::NumericType {
602 let padded = [self.0[0], self.0[1], self.0[2], 0];
603 i32::from_be_bytes(padded)
604 }
605
606 fn from_number(value: Self::NumericType) -> Self {
607 let bytes = value.to_be_bytes();
608 Self([bytes[0], bytes[1], bytes[2]])
609 }
610}
611
612impl BytesSample for U24_4RJ_LE {
615 type NumericType = u32;
616 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
617
618 fn zero() -> Self {
619 Self(Default::default())
620 }
621
622 fn from_slice(bytes: &[u8]) -> Self {
623 Self(bytes[0..4].try_into().unwrap())
624 }
625
626 fn as_slice(&self) -> &[u8] {
627 &self.0
628 }
629
630 fn as_mut_slice(&mut self) -> &mut [u8] {
631 &mut self.0
632 }
633
634 fn to_number(&self) -> Self::NumericType {
635 let padded = [0, self.0[0], self.0[1], self.0[2]];
636 u32::from_le_bytes(padded)
637 }
638
639 fn from_number(value: Self::NumericType) -> Self {
640 let bytes = value.to_le_bytes();
641 Self([bytes[1], bytes[2], bytes[3], 0])
642 }
643}
644
645impl BytesSample for U24_4LJ_LE {
648 type NumericType = u32;
649 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
650
651 fn zero() -> Self {
652 Self(Default::default())
653 }
654
655 fn from_slice(bytes: &[u8]) -> Self {
656 Self(bytes[0..4].try_into().unwrap())
657 }
658
659 fn as_slice(&self) -> &[u8] {
660 &self.0
661 }
662
663 fn as_mut_slice(&mut self) -> &mut [u8] {
664 &mut self.0
665 }
666
667 fn to_number(&self) -> Self::NumericType {
668 let padded = [0, self.0[1], self.0[2], self.0[3]];
669 u32::from_le_bytes(padded)
670 }
671
672 fn from_number(value: Self::NumericType) -> Self {
673 let bytes = value.to_le_bytes();
674 Self([0, bytes[1], bytes[2], bytes[3]])
675 }
676}
677
678impl BytesSample for U24_LE {
680 type NumericType = u32;
681 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
682
683 fn zero() -> Self {
684 Self(Default::default())
685 }
686
687 fn from_slice(bytes: &[u8]) -> Self {
688 Self(bytes[0..3].try_into().unwrap())
689 }
690
691 fn as_slice(&self) -> &[u8] {
692 &self.0
693 }
694
695 fn as_mut_slice(&mut self) -> &mut [u8] {
696 &mut self.0
697 }
698
699 fn to_number(&self) -> Self::NumericType {
700 let padded = [0, self.0[0], self.0[1], self.0[2]];
701 u32::from_le_bytes(padded)
702 }
703
704 fn from_number(value: Self::NumericType) -> Self {
705 let bytes = value.to_le_bytes();
706 Self([bytes[1], bytes[2], bytes[3]])
707 }
708}
709
710impl BytesSample for U24_4RJ_BE {
713 type NumericType = u32;
714 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
715
716 fn zero() -> Self {
717 Self(Default::default())
718 }
719
720 fn from_slice(bytes: &[u8]) -> Self {
721 Self(bytes[0..4].try_into().unwrap())
722 }
723
724 fn as_slice(&self) -> &[u8] {
725 &self.0
726 }
727
728 fn as_mut_slice(&mut self) -> &mut [u8] {
729 &mut self.0
730 }
731
732 fn to_number(&self) -> Self::NumericType {
733 let padded = [self.0[1], self.0[2], self.0[3], 0];
734 u32::from_be_bytes(padded)
735 }
736
737 fn from_number(value: Self::NumericType) -> Self {
738 let bytes = value.to_be_bytes();
739 Self([0, bytes[0], bytes[1], bytes[2]])
740 }
741}
742
743impl BytesSample for U24_4LJ_BE {
746 type NumericType = u32;
747 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
748
749 fn zero() -> Self {
750 Self(Default::default())
751 }
752
753 fn from_slice(bytes: &[u8]) -> Self {
754 Self(bytes[0..4].try_into().unwrap())
755 }
756
757 fn as_slice(&self) -> &[u8] {
758 &self.0
759 }
760
761 fn as_mut_slice(&mut self) -> &mut [u8] {
762 &mut self.0
763 }
764
765 fn to_number(&self) -> Self::NumericType {
766 let padded = [self.0[0], self.0[1], self.0[2], 0];
767 u32::from_be_bytes(padded)
768 }
769
770 fn from_number(value: Self::NumericType) -> Self {
771 let bytes = value.to_be_bytes();
772 Self([bytes[0], bytes[1], bytes[2], 0])
773 }
774}
775
776impl BytesSample for U24_BE {
778 type NumericType = u32;
779 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
780
781 fn zero() -> Self {
782 Self(Default::default())
783 }
784
785 fn from_slice(bytes: &[u8]) -> Self {
786 Self(bytes[0..3].try_into().unwrap())
787 }
788
789 fn as_slice(&self) -> &[u8] {
790 &self.0
791 }
792
793 fn as_mut_slice(&mut self) -> &mut [u8] {
794 &mut self.0
795 }
796
797 fn to_number(&self) -> Self::NumericType {
798 let padded = [self.0[0], self.0[1], self.0[2], 0];
799 u32::from_be_bytes(padded)
800 }
801
802 fn from_number(value: Self::NumericType) -> Self {
803 let bytes = value.to_be_bytes();
804 Self([bytes[0], bytes[1], bytes[2]])
805 }
806}
807
808macro_rules! bytessample_for_newtype {
809 ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
810 impl BytesSample for $newtype {
811 type NumericType = $type;
812 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
813
814 fn zero() -> Self {
815 Self(Default::default())
816 }
817
818 fn from_slice(bytes: &[u8]) -> Self {
819 Self(bytes.try_into().unwrap())
820 }
821
822 fn as_slice(&self) -> &[u8] {
823 &self.0
824 }
825
826 fn as_mut_slice(&mut self) -> &mut [u8] {
827 &mut self.0
828 }
829
830 fn to_number(&self) -> Self::NumericType {
831 $type::$from(self.0)
832 }
833
834 fn from_number(value: Self::NumericType) -> Self {
835 Self(value.$to())
836 }
837 }
838 };
839}
840
841bytessample_for_newtype!(i8, I8, from_le_bytes, to_le_bytes);
843bytessample_for_newtype!(u8, U8, from_le_bytes, to_le_bytes);
844
845bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
846bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
847bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
848bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
849
850bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
851bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
852bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
853bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
854
855bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
856bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
857bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
858bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
859
860bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
861bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
862bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
863bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
864
865macro_rules! bytessample_for_g711 {
877 ($newtype:ident, $decode:ident, $encode:ident) => {
878 impl BytesSample for $newtype {
879 type NumericType = i16;
880 const BYTES_PER_SAMPLE: usize = 1;
881
882 fn zero() -> Self {
883 Self(Default::default())
884 }
885
886 fn from_slice(bytes: &[u8]) -> Self {
887 Self(bytes[0..1].try_into().unwrap())
888 }
889
890 fn as_slice(&self) -> &[u8] {
891 &self.0
892 }
893
894 fn as_mut_slice(&mut self) -> &mut [u8] {
895 &mut self.0
896 }
897
898 fn to_number(&self) -> Self::NumericType {
899 $decode(self.0[0])
900 }
901
902 fn from_number(value: Self::NumericType) -> Self {
903 Self([$encode(value)])
904 }
905 }
906 };
907}
908
909bytessample_for_g711!(ALAW, decode_alaw, encode_alaw);
910bytessample_for_g711!(MULAW, decode_ulaw, encode_ulaw);
911
912impl<V> RawSample for V
913where
914 V: BytesSample,
915 <V as BytesSample>::NumericType: RawSample,
916{
917 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
918 let value = self.to_number();
919 value.to_scaled_float()
920 }
921
922 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
923 let value = <V as BytesSample>::NumericType::from_scaled_float(value);
924 ConversionResult {
925 clipped: value.clipped,
926 value: V::from_number(value.value),
927 }
928 }
929}
930
931#[cfg(test)]
932mod tests {
933 use super::*;
934
935 macro_rules! assert_conversion_eq {
936 ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
937 assert_eq!($result.value, $value, $desc);
938 assert_eq!($result.clipped, $clipped, $desc);
939 };
940 }
941
942 macro_rules! test_to_signed_int {
943 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
944 #[test]
945 fn $fname() {
946 let val: $float = 0.25;
947 assert_conversion_eq!(
948 $int::from_scaled_float(val),
949 1 << ($bits - 3),
950 false,
951 "check +0.25"
952 );
953 let val: $float = -0.25;
954 assert_conversion_eq!(
955 $int::from_scaled_float(val),
956 -1 << ($bits - 3),
957 false,
958 "check -0.25"
959 );
960 let val: $float = 1.1;
961 assert_conversion_eq!(
962 $int::from_scaled_float(val),
963 $int::MAX,
964 true,
965 "clipped positive"
966 );
967 let val: $float = -1.1;
968 assert_conversion_eq!(
969 $int::from_scaled_float(val),
970 $int::MIN,
971 true,
972 "clipped negative"
973 );
974 }
975 };
976 }
977
978 macro_rules! test_to_unsigned_int {
979 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
980 #[test]
981 fn $fname() {
982 let val: $float = -0.5;
983 assert_conversion_eq!(
984 $int::from_scaled_float(val),
985 1 << ($bits - 2),
986 false,
987 "check -0.5"
988 );
989 let val: $float = 0.5;
990 assert_conversion_eq!(
991 $int::from_scaled_float(val),
992 $int::MAX - (1 << ($bits - 2)) + 1,
993 false,
994 "check 0.5"
995 );
996 let val: $float = 1.1;
997 assert_conversion_eq!(
998 $int::from_scaled_float(val),
999 $int::MAX,
1000 true,
1001 "clipped positive"
1002 );
1003 let val: $float = -1.1;
1004 assert_conversion_eq!(
1005 $int::from_scaled_float(val),
1006 $int::MIN,
1007 true,
1008 "clipped negative"
1009 );
1010 }
1011 };
1012 }
1013
1014 test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
1015 test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
1016 test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
1017 test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
1018 test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
1019 test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
1020 test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
1021 test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
1022
1023 test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
1024 test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
1025 test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
1026 test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
1027 test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
1028 test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
1029 test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
1030 test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
1031
1032 macro_rules! test_from_signed_int {
1033 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
1034 #[test]
1035 fn $fname() {
1036 let val: $int = -1 << ($bits - 2);
1037 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
1038 let val: $int = 1 << ($bits - 2);
1039 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
1040 let val: $int = $int::MIN;
1041 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
1042 }
1043 };
1044 }
1045
1046 macro_rules! test_from_unsigned_int {
1047 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
1048 #[test]
1049 fn $fname() {
1050 let val: $int = 1 << ($bits - 2);
1051 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
1052 let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
1053 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
1054 let val: $int = 0;
1055 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
1056 }
1057 };
1058 }
1059
1060 test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
1061 test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
1062 test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
1063 test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
1064 test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
1065 test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
1066 test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
1067 test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
1068
1069 test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
1070 test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
1071 test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
1072 test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
1073 test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
1074 test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
1075 test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
1076 test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
1077
1078 #[test]
1079 fn test_to_clamped_int() {
1080 let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
1081 assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
1082
1083 let converted = to_clamped_int::<f32, i32>(1.0e10, None);
1084 assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
1085
1086 let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
1087 assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
1088
1089 let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
1090 assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
1091
1092 let converted = to_clamped_int::<f64, i32>(1.0e10, None);
1093 assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
1094
1095 let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
1096 assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
1097 }
1098
1099 #[test]
1100 fn test_to_clamped_uint() {
1101 let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
1102 assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
1103
1104 let converted = to_clamped_int::<f32, u32>(1.0e10, None);
1105 assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
1106
1107 let converted = to_clamped_int::<f32, u32>(-1.0, None);
1108 assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
1109
1110 let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
1111 assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
1112
1113 let converted = to_clamped_int::<f64, u32>(1.0e10, None);
1114 assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
1115
1116 let converted = to_clamped_int::<f64, u32>(-1.0, None);
1117 assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
1118 }
1119
1120 macro_rules! test_simple_int_bytes {
1121 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1122 #[test]
1123 #[allow(non_snake_case)]
1124 fn $fname() {
1125 let number: $number = <$number>::MAX / 5 * 4;
1126 let wrapped = $wrapper(number.$to_bytes_fn());
1127 assert_eq!(number, wrapped.to_number());
1128 }
1129 };
1130 }
1131
1132 macro_rules! test_float_bytes {
1133 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1134 #[test]
1135 #[allow(non_snake_case)]
1136 fn $fname() {
1137 let number: $number = 12345.0;
1138 let wrapped = $wrapper(number.$to_bytes_fn());
1139 assert_eq!(number, wrapped.to_number());
1140 }
1141 };
1142 }
1143
1144 test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
1145 test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
1146 test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
1147 test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
1148 test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
1149 test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1150
1151 test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1152 test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1153 test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1154 test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1155 test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1156 test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1157
1158 test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1159 test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1160 test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1161 test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1162
1163 #[test]
1164 #[allow(non_snake_case)]
1165 fn test_I8() {
1166 assert_eq!(I8::BYTES_PER_SAMPLE, 1);
1167 assert_eq!(I8::zero().to_number(), 0);
1168 assert_eq!(I8::from_slice(&[0x80]).to_number(), i8::MIN);
1169
1170 for number in [0, 1, -1, 100, i8::MIN, i8::MAX] {
1171 let wrapped = I8::from_number(number);
1172 assert_eq!(
1173 wrapped.as_slice(),
1174 number.to_le_bytes(),
1175 "bytes for {number}"
1176 );
1177 assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1178 }
1179 }
1180
1181 #[test]
1182 #[allow(non_snake_case)]
1183 fn test_U8() {
1184 assert_eq!(U8::BYTES_PER_SAMPLE, 1);
1185 assert_eq!(U8::zero().to_number(), 0);
1186 assert_eq!(U8::from_slice(&[0x80]).to_number(), 128);
1187
1188 for number in [0, 1, 128, 200, u8::MAX] {
1189 let wrapped = U8::from_number(number);
1190 assert_eq!(
1191 wrapped.as_slice(),
1192 number.to_le_bytes(),
1193 "bytes for {number}"
1194 );
1195 assert_eq!(wrapped.to_number(), number, "roundtrip of {number}");
1196 }
1197 }
1198
1199 #[test]
1200 #[allow(non_snake_case)]
1201 fn convert_I8_to_and_from_float() {
1202 assert_eq!(I8::from_slice(&[0]).to_scaled_float::<f32>(), 0.0);
1203 assert_eq!(I8::from_slice(&[0x80]).to_scaled_float::<f32>(), -1.0);
1204 assert_eq!(I8::from_slice(&[0x40]).to_scaled_float::<f32>(), 0.5);
1205 assert_eq!(I8::from_slice(&[0xC0]).to_scaled_float::<f32>(), -0.5);
1206
1207 let converted = I8::from_scaled_float(0.5f32);
1208 assert_eq!(converted.value.as_slice(), [0x40]);
1209 assert!(!converted.clipped);
1210
1211 let converted = I8::from_scaled_float(-1.0f32);
1212 assert_eq!(converted.value.as_slice(), [0x80]);
1213 assert!(!converted.clipped);
1214
1215 let converted = I8::from_scaled_float(1.5f32);
1217 assert_eq!(converted.value.to_number(), i8::MAX);
1218 assert!(converted.clipped);
1219
1220 let converted = I8::from_scaled_float(-1.5f32);
1221 assert_eq!(converted.value.to_number(), i8::MIN);
1222 assert!(converted.clipped);
1223 }
1224
1225 #[test]
1226 #[allow(non_snake_case)]
1227 fn convert_U8_to_and_from_float() {
1228 assert_eq!(U8::from_slice(&[128]).to_scaled_float::<f32>(), 0.0);
1230 assert_eq!(U8::from_slice(&[0]).to_scaled_float::<f32>(), -1.0);
1231 assert_eq!(U8::from_slice(&[192]).to_scaled_float::<f32>(), 0.5);
1232 assert_eq!(U8::from_slice(&[64]).to_scaled_float::<f32>(), -0.5);
1233
1234 let converted = U8::from_scaled_float(0.5f32);
1235 assert_eq!(converted.value.as_slice(), [192]);
1236 assert!(!converted.clipped);
1237
1238 let converted = U8::from_scaled_float(-1.0f32);
1239 assert_eq!(converted.value.as_slice(), [0]);
1240 assert!(!converted.clipped);
1241
1242 let converted = U8::from_scaled_float(1.5f32);
1244 assert_eq!(converted.value.to_number(), u8::MAX);
1245 assert!(converted.clipped);
1246
1247 let converted = U8::from_scaled_float(-1.5f32);
1248 assert_eq!(converted.value.to_number(), u8::MIN);
1249 assert!(converted.clipped);
1250 }
1251
1252 #[test]
1253 #[allow(non_snake_case)]
1254 fn test_I24_LE() {
1255 let number = i32::MAX / 5 * 4;
1256
1257 let number = number >> 8;
1259 let number = number << 8;
1260
1261 let allbytes = number.to_le_bytes();
1262 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1265
1266 let wrapped = I24_LE(bytes);
1267 assert_eq!(number, wrapped.to_number());
1268 }
1269
1270 #[test]
1271 #[allow(non_snake_case)]
1272 fn test_I24_BE() {
1273 let number = i32::MAX / 5 * 4;
1274
1275 let number = number >> 8;
1277 let number = number << 8;
1278
1279 let allbytes = number.to_be_bytes();
1280 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1283
1284 let wrapped = I24_BE(bytes);
1285 assert_eq!(number, wrapped.to_number());
1286 }
1287
1288 #[test]
1289 #[allow(non_snake_case)]
1290 fn test_I24_4RJ_LE() {
1291 let number = i32::MAX / 5 * 4;
1292
1293 let number = number >> 8;
1295 let number = number << 8;
1296
1297 let allbytes = number.to_le_bytes();
1298 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1301
1302 let wrapped = I24_4RJ_LE(bytes);
1303 assert_eq!(number, wrapped.to_number());
1304 }
1305
1306 #[test]
1307 #[allow(non_snake_case)]
1308 fn test_I24_4RJ_BE() {
1309 let number = i32::MAX / 5 * 4;
1310
1311 let number = number >> 8;
1313 let number = number << 8;
1314
1315 let allbytes = number.to_be_bytes();
1316 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1319
1320 let wrapped = I24_4RJ_BE(bytes);
1321 assert_eq!(number, wrapped.to_number());
1322 }
1323
1324 #[test]
1325 #[allow(non_snake_case)]
1326 fn test_I24_4LJ_LE() {
1327 let number = i32::MAX / 5 * 4;
1328
1329 let number = number >> 8;
1331 let number = number << 8;
1332
1333 let allbytes = number.to_le_bytes();
1334 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1337
1338 let wrapped = I24_4LJ_LE(bytes);
1339 assert_eq!(number, wrapped.to_number());
1340 }
1341
1342 #[test]
1343 #[allow(non_snake_case)]
1344 fn test_I24_4LJ_BE() {
1345 let number = i32::MAX / 5 * 4;
1346
1347 let number = number >> 8;
1349 let number = number << 8;
1350
1351 let allbytes = number.to_be_bytes();
1352 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1355
1356 let wrapped = I24_4LJ_BE(bytes);
1357 assert_eq!(number, wrapped.to_number());
1358 }
1359
1360 #[test]
1361 #[allow(non_snake_case)]
1362 fn test_U24_LE() {
1363 let number = u32::MAX / 5 * 4;
1364
1365 let number = number >> 8;
1367 let number = number << 8;
1368
1369 let allbytes = number.to_le_bytes();
1370 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1373
1374 let wrapped = U24_LE(bytes);
1375 assert_eq!(number, wrapped.to_number());
1376 }
1377
1378 #[test]
1379 #[allow(non_snake_case)]
1380 fn test_U24_BE() {
1381 let number = u32::MAX / 5 * 4;
1382
1383 let number = number >> 8;
1385 let number = number << 8;
1386
1387 let allbytes = number.to_be_bytes();
1388 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1391
1392 let wrapped = U24_BE(bytes);
1393 assert_eq!(number, wrapped.to_number());
1394 }
1395
1396 #[test]
1397 #[allow(non_snake_case)]
1398 fn test_U24_4RJ_LE() {
1399 let number = u32::MAX / 5 * 4;
1400
1401 let number = number >> 8;
1403 let number = number << 8;
1404
1405 let allbytes = number.to_le_bytes();
1406 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1409
1410 let wrapped = U24_4RJ_LE(bytes);
1411 assert_eq!(number, wrapped.to_number());
1412 }
1413
1414 #[test]
1415 #[allow(non_snake_case)]
1416 fn test_U24_4RJ_BE() {
1417 let number = u32::MAX / 5 * 4;
1418
1419 let number = number >> 8;
1421 let number = number << 8;
1422
1423 let allbytes = number.to_be_bytes();
1424 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1427
1428 let wrapped = U24_4RJ_BE(bytes);
1429 assert_eq!(number, wrapped.to_number());
1430 }
1431
1432 #[test]
1433 #[allow(non_snake_case)]
1434 fn test_U24_4LJ_LE() {
1435 let number = u32::MAX / 5 * 4;
1436
1437 let number = number >> 8;
1439 let number = number << 8;
1440
1441 let allbytes = number.to_le_bytes();
1442 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1445
1446 let wrapped = U24_4LJ_LE(bytes);
1447 assert_eq!(number, wrapped.to_number());
1448 }
1449
1450 #[test]
1451 #[allow(non_snake_case)]
1452 fn test_U24_4LJ_BE() {
1453 let number = u32::MAX / 5 * 4;
1454
1455 let number = number >> 8;
1457 let number = number << 8;
1458
1459 let allbytes = number.to_be_bytes();
1460 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1463
1464 let wrapped = U24_4LJ_BE(bytes);
1465 assert_eq!(number, wrapped.to_number());
1466 }
1467
1468 #[test]
1477 #[allow(non_snake_case)]
1478 fn test_ALAW() {
1479 assert_eq!(ALAW::BYTES_PER_SAMPLE, 1);
1480
1481 assert_eq!(ALAW::from_slice(&[0xd5]).to_number(), 8);
1483 assert_eq!(ALAW::from_slice(&[0x55]).to_number(), -8);
1484 assert_eq!(ALAW::from_number(0).as_slice(), [0xd5]);
1485
1486 assert_eq!(ALAW::from_slice(&[0xaa]).to_number(), 32256);
1488 assert_eq!(ALAW::from_slice(&[0x2a]).to_number(), -32256);
1489
1490 assert_eq!(ALAW::zero().to_number(), -5504);
1492 }
1493
1494 #[test]
1495 #[allow(non_snake_case)]
1496 fn test_MULAW() {
1497 assert_eq!(MULAW::BYTES_PER_SAMPLE, 1);
1498
1499 assert_eq!(MULAW::from_slice(&[0xff]).to_number(), 0);
1501 assert_eq!(MULAW::from_slice(&[0x7f]).to_number(), 0);
1502 assert_eq!(MULAW::from_number(0).as_slice(), [0xff]);
1503
1504 assert_eq!(MULAW::from_slice(&[0x80]).to_number(), 32124);
1507 assert_eq!(MULAW::from_slice(&[0x00]).to_number(), -32124);
1508
1509 assert_eq!(MULAW::zero().to_number(), -32124);
1511 }
1512
1513 macro_rules! test_g711_roundtrips {
1514 ($name:ident, $type:ident, $maxmagnitude:expr, $aliases:expr) => {
1515 #[test]
1516 #[allow(non_snake_case)]
1517 fn $name() {
1518 for byte in 0..=u8::MAX {
1521 if $aliases.contains(&byte) {
1522 continue;
1523 }
1524 let number = $type::from_slice(&[byte]).to_number();
1525 assert_eq!(
1526 $type::from_number(number).as_slice(),
1527 [byte],
1528 "code word {byte:#04x} decoded to {number}"
1529 );
1530 }
1531
1532 for number in (i16::MIN..=i16::MAX).step_by(7) {
1535 let once = $type::from_number(number).to_number();
1536 let twice = $type::from_number(once).to_number();
1537 assert_eq!(once, twice, "quantizing {number} is not stable");
1538 }
1539
1540 for byte in 0..=u8::MAX {
1543 let number = $type::from_slice(&[byte]).to_number();
1544 assert!(
1545 number.abs() <= $maxmagnitude,
1546 "code word {byte:#04x} decoded to {number}"
1547 );
1548 let mirrored = $type::from_slice(&[byte ^ 0x80]).to_number();
1549 assert_eq!(number, -mirrored, "code word {byte:#04x} is not symmetric");
1550 }
1551 }
1552 };
1553 }
1554
1555 test_g711_roundtrips!(roundtrip_ALAW, ALAW, 32256, []);
1558 test_g711_roundtrips!(roundtrip_MULAW, MULAW, 32124, [0x7f]);
1559
1560 #[test]
1561 #[allow(non_snake_case)]
1562 fn convert_ALAW_to_and_from_float() {
1563 assert_eq!(
1564 ALAW::from_slice(&[0xaa]).to_scaled_float::<f32>(),
1565 32256.0 / 32768.0
1566 );
1567 assert_eq!(
1568 ALAW::from_slice(&[0x2a]).to_scaled_float::<f32>(),
1569 -32256.0 / 32768.0
1570 );
1571 assert!(ALAW::from_slice(&[0xd5]).to_scaled_float::<f32>().abs() < 0.001);
1572
1573 let converted = ALAW::from_scaled_float(1.5f32);
1575 assert_eq!(converted.value.to_number(), 32256);
1576 assert!(converted.clipped);
1577
1578 let converted = ALAW::from_scaled_float(-1.5f32);
1579 assert_eq!(converted.value.to_number(), -32256);
1580 assert!(converted.clipped);
1581 }
1582
1583 #[test]
1584 #[allow(non_snake_case)]
1585 fn convert_MULAW_to_and_from_float() {
1586 assert_eq!(
1587 MULAW::from_slice(&[0x80]).to_scaled_float::<f32>(),
1588 32124.0 / 32768.0
1589 );
1590 assert_eq!(
1591 MULAW::from_slice(&[0x00]).to_scaled_float::<f32>(),
1592 -32124.0 / 32768.0
1593 );
1594 assert_eq!(MULAW::from_slice(&[0xff]).to_scaled_float::<f32>(), 0.0);
1595
1596 let converted = MULAW::from_scaled_float(1.5f32);
1598 assert_eq!(converted.value.to_number(), 32124);
1599 assert!(converted.clipped);
1600
1601 let converted = MULAW::from_scaled_float(-1.5f32);
1602 assert_eq!(converted.value.to_number(), -32124);
1603 assert!(converted.clipped);
1604 }
1605
1606 macro_rules! test_g711_accuracy {
1613 ($name:ident, $type:ident, $smallerror:expr) => {
1614 #[test]
1615 #[allow(non_snake_case)]
1616 fn $name() {
1617 for value in (i16::MIN..=i16::MAX).step_by(3) {
1618 let encoded = $type::from_number(value).to_number();
1619 let error = (i32::from(encoded) - i32::from(value)).abs();
1620 if value.unsigned_abs() >= 1000 {
1621 let relative = f64::from(error) / f64::from(value.unsigned_abs());
1622 assert!(
1623 relative < 0.05,
1624 "relative error {relative} at {value} is too large, got {encoded}"
1625 );
1626 } else {
1627 assert!(
1628 error <= $smallerror,
1629 "error {error} at {value} is too large, got {encoded}"
1630 );
1631 }
1632 }
1633 }
1634 };
1635 }
1636
1637 test_g711_accuracy!(accuracy_ALAW, ALAW, 16);
1639 test_g711_accuracy!(accuracy_MULAW, MULAW, 32);
1640}