1#![allow(non_camel_case_types)]
2
3use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
4
5#[cfg(feature = "audio")]
6use audio_core::Sample;
7
8#[derive(Debug, Clone, Copy)]
12pub struct I16_LE([u8; 2]);
13
14#[derive(Debug, Clone, Copy)]
16pub struct I16_BE([u8; 2]);
17
18#[derive(Debug, Clone, Copy)]
20pub struct U16_LE([u8; 2]);
21
22#[derive(Debug, Clone, Copy)]
24pub struct U16_BE([u8; 2]);
25
26#[derive(Debug, Clone, Copy)]
30pub struct I24_LE([u8; 3]);
31
32#[derive(Debug, Clone, Copy)]
36pub struct I24_4LJ_LE([u8; 4]);
37
38#[derive(Debug, Clone, Copy)]
42pub struct I24_4RJ_LE([u8; 4]);
43
44#[derive(Debug, Clone, Copy)]
46pub struct I24_BE([u8; 3]);
47
48#[derive(Debug, Clone, Copy)]
52pub struct I24_4LJ_BE([u8; 4]);
53
54#[derive(Debug, Clone, Copy)]
58pub struct I24_4RJ_BE([u8; 4]);
59
60#[derive(Debug, Clone, Copy)]
62pub struct U24_LE([u8; 3]);
63
64#[derive(Debug, Clone, Copy)]
68pub struct U24_4LJ_LE([u8; 4]);
69
70#[derive(Debug, Clone, Copy)]
74pub struct U24_4RJ_LE([u8; 4]);
75
76#[derive(Debug, Clone, Copy)]
78pub struct U24_BE([u8; 3]);
79
80#[derive(Debug, Clone, Copy)]
84pub struct U24_4LJ_BE([u8; 4]);
85
86#[derive(Debug, Clone, Copy)]
90pub struct U24_4RJ_BE([u8; 4]);
91
92#[derive(Debug, Clone, Copy)]
96pub struct I32_LE([u8; 4]);
97
98#[derive(Debug, Clone, Copy)]
100pub struct I32_BE([u8; 4]);
101
102#[derive(Debug, Clone, Copy)]
104pub struct U32_LE([u8; 4]);
105
106#[derive(Debug, Clone, Copy)]
108pub struct U32_BE([u8; 4]);
109
110#[derive(Debug, Clone, Copy)]
114pub struct I64_LE([u8; 8]);
115
116#[derive(Debug, Clone, Copy)]
118pub struct I64_BE([u8; 8]);
119
120#[derive(Debug, Clone, Copy)]
122pub struct U64_LE([u8; 8]);
123
124#[derive(Debug, Clone, Copy)]
126pub struct U64_BE([u8; 8]);
127
128#[derive(Debug, Clone, Copy)]
132pub struct F32_LE([u8; 4]);
133
134#[derive(Debug, Clone, Copy)]
136pub struct F32_BE([u8; 4]);
137
138#[derive(Debug, Clone, Copy)]
140pub struct F64_LE([u8; 8]);
141
142#[derive(Debug, Clone, Copy)]
144pub struct F64_BE([u8; 8]);
145
146fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
148 value: T,
149 converted: Option<U>,
150) -> ConversionResult<U> {
151 if let Some(val) = converted {
152 return ConversionResult {
153 clipped: false,
154 value: val,
155 };
156 }
157 if value.is_nan() {
158 return ConversionResult {
159 clipped: true,
160 value: U::zero(),
161 };
162 }
163 if value > T::zero() {
164 return ConversionResult {
165 clipped: true,
166 value: U::max_value(),
167 };
168 }
169 ConversionResult {
170 clipped: true,
171 value: U::min_value(),
172 }
173}
174
175pub struct ConversionResult<T> {
178 pub clipped: bool,
179 pub value: T,
180}
181
182pub trait RawSample
192where
193 Self: Sized,
194{
195 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
197
198 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
201}
202
203pub trait BytesSample {
215 type NumericType: Copy;
217
218 const BYTES_PER_SAMPLE: usize;
220
221 fn zero() -> Self;
227
228 fn from_slice(bytes: &[u8]) -> Self;
232
233 fn as_slice(&self) -> &[u8];
235
236 fn as_mut_slice(&mut self) -> &mut [u8];
238
239 fn to_number(&self) -> Self::NumericType;
241
242 fn from_number(value: Self::NumericType) -> Self;
244}
245
246macro_rules! rawsample_for_int {
247 ($type:ident, $to:ident) => {
248 impl RawSample for $type {
249 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
250 T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
251 }
252
253 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
254 let scaled = value * (T::from($type::MAX).unwrap() + T::one());
255 let converted = scaled.$to();
256 to_clamped_int(scaled, converted)
257 }
258 }
259 };
260}
261
262rawsample_for_int!(i8, to_i8);
263rawsample_for_int!(i16, to_i16);
264rawsample_for_int!(i32, to_i32);
265rawsample_for_int!(i64, to_i64);
266
267macro_rules! rawsample_for_uint {
268 ($type:ident, $to:ident) => {
269 impl RawSample for $type {
270 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
271 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
272 (T::from(*self).unwrap() - max_ampl) / max_ampl
273 }
274
275 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
276 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
277 let scaled = value * max_ampl + max_ampl;
278 let converted = scaled.$to();
279 to_clamped_int(scaled, converted)
280 }
281 }
282 };
283}
284
285rawsample_for_uint!(u8, to_u8);
286rawsample_for_uint!(u16, to_u16);
287rawsample_for_uint!(u32, to_u32);
288rawsample_for_uint!(u64, to_u64);
289
290macro_rules! rawsample_for_float {
291 ($type:ident, $to:ident) => {
292 impl RawSample for $type {
293 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
294 T::from(*self).unwrap_or(T::zero())
295 }
296
297 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
298 ConversionResult {
300 clipped: false,
301 value: value.$to().unwrap_or(0.0),
302 }
303 }
304 }
305 };
306}
307
308rawsample_for_float!(f32, to_f32);
309rawsample_for_float!(f64, to_f64);
310
311impl BytesSample for I24_4RJ_LE {
317 type NumericType = i32;
318 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
319
320 fn zero() -> Self {
321 Self(Default::default())
322 }
323
324 fn from_slice(bytes: &[u8]) -> Self {
325 Self(bytes[0..4].try_into().unwrap())
326 }
327
328 fn as_slice(&self) -> &[u8] {
329 &self.0
330 }
331
332 fn as_mut_slice(&mut self) -> &mut [u8] {
333 &mut self.0
334 }
335
336 fn to_number(&self) -> Self::NumericType {
337 let padded = [0, self.0[0], self.0[1], self.0[2]];
338 i32::from_le_bytes(padded)
339 }
340
341 fn from_number(value: Self::NumericType) -> Self {
342 let bytes = value.to_le_bytes();
343 Self([bytes[1], bytes[2], bytes[3], 0])
344 }
345}
346
347impl BytesSample for I24_4LJ_LE {
350 type NumericType = i32;
351 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
352
353 fn zero() -> Self {
354 Self(Default::default())
355 }
356
357 fn from_slice(bytes: &[u8]) -> Self {
358 Self(bytes[0..4].try_into().unwrap())
359 }
360
361 fn as_slice(&self) -> &[u8] {
362 &self.0
363 }
364
365 fn as_mut_slice(&mut self) -> &mut [u8] {
366 &mut self.0
367 }
368
369 fn to_number(&self) -> Self::NumericType {
370 let padded = [0, self.0[1], self.0[2], self.0[3]];
371 i32::from_le_bytes(padded)
372 }
373
374 fn from_number(value: Self::NumericType) -> Self {
375 let bytes = value.to_le_bytes();
376 Self([0, bytes[1], bytes[2], bytes[3]])
377 }
378}
379
380impl BytesSample for I24_LE {
382 type NumericType = i32;
383 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
384
385 fn zero() -> Self {
386 Self(Default::default())
387 }
388
389 fn from_slice(bytes: &[u8]) -> Self {
390 Self(bytes[0..3].try_into().unwrap())
391 }
392
393 fn as_slice(&self) -> &[u8] {
394 &self.0
395 }
396
397 fn as_mut_slice(&mut self) -> &mut [u8] {
398 &mut self.0
399 }
400
401 fn to_number(&self) -> Self::NumericType {
402 let padded = [0, self.0[0], self.0[1], self.0[2]];
403 i32::from_le_bytes(padded)
404 }
405
406 fn from_number(value: Self::NumericType) -> Self {
407 let bytes = value.to_le_bytes();
408 Self([bytes[1], bytes[2], bytes[3]])
409 }
410}
411
412impl BytesSample for I24_4RJ_BE {
415 type NumericType = i32;
416 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
417
418 fn zero() -> Self {
419 Self(Default::default())
420 }
421
422 fn from_slice(bytes: &[u8]) -> Self {
423 Self(bytes[0..4].try_into().unwrap())
424 }
425
426 fn as_slice(&self) -> &[u8] {
427 &self.0
428 }
429
430 fn as_mut_slice(&mut self) -> &mut [u8] {
431 &mut self.0
432 }
433
434 fn to_number(&self) -> Self::NumericType {
435 let padded = [self.0[1], self.0[2], self.0[3], 0];
436 i32::from_be_bytes(padded)
437 }
438
439 fn from_number(value: Self::NumericType) -> Self {
440 let bytes = value.to_be_bytes();
441 Self([0, bytes[0], bytes[1], bytes[2]])
442 }
443}
444
445impl BytesSample for I24_4LJ_BE {
448 type NumericType = i32;
449 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
450
451 fn zero() -> Self {
452 Self(Default::default())
453 }
454
455 fn from_slice(bytes: &[u8]) -> Self {
456 Self(bytes[0..4].try_into().unwrap())
457 }
458
459 fn as_slice(&self) -> &[u8] {
460 &self.0
461 }
462
463 fn as_mut_slice(&mut self) -> &mut [u8] {
464 &mut self.0
465 }
466
467 fn to_number(&self) -> Self::NumericType {
468 let padded = [self.0[0], self.0[1], self.0[2], 0];
469 i32::from_be_bytes(padded)
470 }
471
472 fn from_number(value: Self::NumericType) -> Self {
473 let bytes = value.to_be_bytes();
474 Self([bytes[0], bytes[1], bytes[2], 0])
475 }
476}
477
478impl BytesSample for I24_BE {
480 type NumericType = i32;
481 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
482
483 fn zero() -> Self {
484 Self(Default::default())
485 }
486
487 fn from_slice(bytes: &[u8]) -> Self {
488 Self(bytes[0..3].try_into().unwrap())
489 }
490
491 fn as_slice(&self) -> &[u8] {
492 &self.0
493 }
494
495 fn as_mut_slice(&mut self) -> &mut [u8] {
496 &mut self.0
497 }
498
499 fn to_number(&self) -> Self::NumericType {
500 let padded = [self.0[0], self.0[1], self.0[2], 0];
501 i32::from_be_bytes(padded)
502 }
503
504 fn from_number(value: Self::NumericType) -> Self {
505 let bytes = value.to_be_bytes();
506 Self([bytes[0], bytes[1], bytes[2]])
507 }
508}
509
510impl BytesSample for U24_4RJ_LE {
513 type NumericType = u32;
514 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
515
516 fn zero() -> Self {
517 Self(Default::default())
518 }
519
520 fn from_slice(bytes: &[u8]) -> Self {
521 Self(bytes[0..4].try_into().unwrap())
522 }
523
524 fn as_slice(&self) -> &[u8] {
525 &self.0
526 }
527
528 fn as_mut_slice(&mut self) -> &mut [u8] {
529 &mut self.0
530 }
531
532 fn to_number(&self) -> Self::NumericType {
533 let padded = [0, self.0[0], self.0[1], self.0[2]];
534 u32::from_le_bytes(padded)
535 }
536
537 fn from_number(value: Self::NumericType) -> Self {
538 let bytes = value.to_le_bytes();
539 Self([bytes[1], bytes[2], bytes[3], 0])
540 }
541}
542
543impl BytesSample for U24_4LJ_LE {
546 type NumericType = u32;
547 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
548
549 fn zero() -> Self {
550 Self(Default::default())
551 }
552
553 fn from_slice(bytes: &[u8]) -> Self {
554 Self(bytes[0..4].try_into().unwrap())
555 }
556
557 fn as_slice(&self) -> &[u8] {
558 &self.0
559 }
560
561 fn as_mut_slice(&mut self) -> &mut [u8] {
562 &mut self.0
563 }
564
565 fn to_number(&self) -> Self::NumericType {
566 let padded = [0, self.0[1], self.0[2], self.0[3]];
567 u32::from_le_bytes(padded)
568 }
569
570 fn from_number(value: Self::NumericType) -> Self {
571 let bytes = value.to_le_bytes();
572 Self([0, bytes[1], bytes[2], bytes[3]])
573 }
574}
575
576impl BytesSample for U24_LE {
578 type NumericType = u32;
579 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
580
581 fn zero() -> Self {
582 Self(Default::default())
583 }
584
585 fn from_slice(bytes: &[u8]) -> Self {
586 Self(bytes[0..3].try_into().unwrap())
587 }
588
589 fn as_slice(&self) -> &[u8] {
590 &self.0
591 }
592
593 fn as_mut_slice(&mut self) -> &mut [u8] {
594 &mut self.0
595 }
596
597 fn to_number(&self) -> Self::NumericType {
598 let padded = [0, self.0[0], self.0[1], self.0[2]];
599 u32::from_le_bytes(padded)
600 }
601
602 fn from_number(value: Self::NumericType) -> Self {
603 let bytes = value.to_le_bytes();
604 Self([bytes[1], bytes[2], bytes[3]])
605 }
606}
607
608impl BytesSample for U24_4RJ_BE {
611 type NumericType = u32;
612 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
613
614 fn zero() -> Self {
615 Self(Default::default())
616 }
617
618 fn from_slice(bytes: &[u8]) -> Self {
619 Self(bytes[0..4].try_into().unwrap())
620 }
621
622 fn as_slice(&self) -> &[u8] {
623 &self.0
624 }
625
626 fn as_mut_slice(&mut self) -> &mut [u8] {
627 &mut self.0
628 }
629
630 fn to_number(&self) -> Self::NumericType {
631 let padded = [self.0[1], self.0[2], self.0[3], 0];
632 u32::from_be_bytes(padded)
633 }
634
635 fn from_number(value: Self::NumericType) -> Self {
636 let bytes = value.to_be_bytes();
637 Self([0, bytes[0], bytes[1], bytes[2]])
638 }
639}
640
641impl BytesSample for U24_4LJ_BE {
644 type NumericType = u32;
645 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
646
647 fn zero() -> Self {
648 Self(Default::default())
649 }
650
651 fn from_slice(bytes: &[u8]) -> Self {
652 Self(bytes[0..4].try_into().unwrap())
653 }
654
655 fn as_slice(&self) -> &[u8] {
656 &self.0
657 }
658
659 fn as_mut_slice(&mut self) -> &mut [u8] {
660 &mut self.0
661 }
662
663 fn to_number(&self) -> Self::NumericType {
664 let padded = [self.0[0], self.0[1], self.0[2], 0];
665 u32::from_be_bytes(padded)
666 }
667
668 fn from_number(value: Self::NumericType) -> Self {
669 let bytes = value.to_be_bytes();
670 Self([bytes[0], bytes[1], bytes[2], 0])
671 }
672}
673
674impl BytesSample for U24_BE {
676 type NumericType = u32;
677 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
678
679 fn zero() -> Self {
680 Self(Default::default())
681 }
682
683 fn from_slice(bytes: &[u8]) -> Self {
684 Self(bytes[0..3].try_into().unwrap())
685 }
686
687 fn as_slice(&self) -> &[u8] {
688 &self.0
689 }
690
691 fn as_mut_slice(&mut self) -> &mut [u8] {
692 &mut self.0
693 }
694
695 fn to_number(&self) -> Self::NumericType {
696 let padded = [self.0[0], self.0[1], self.0[2], 0];
697 u32::from_be_bytes(padded)
698 }
699
700 fn from_number(value: Self::NumericType) -> Self {
701 let bytes = value.to_be_bytes();
702 Self([bytes[0], bytes[1], bytes[2]])
703 }
704}
705
706macro_rules! bytessample_for_newtype {
707 ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
708 impl BytesSample for $newtype {
709 type NumericType = $type;
710 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
711
712 fn zero() -> Self {
713 Self(Default::default())
714 }
715
716 fn from_slice(bytes: &[u8]) -> Self {
717 Self(bytes.try_into().unwrap())
718 }
719
720 fn as_slice(&self) -> &[u8] {
721 &self.0
722 }
723
724 fn as_mut_slice(&mut self) -> &mut [u8] {
725 &mut self.0
726 }
727
728 fn to_number(&self) -> Self::NumericType {
729 $type::$from(self.0)
730 }
731
732 fn from_number(value: Self::NumericType) -> Self {
733 Self(value.$to())
734 }
735 }
736 };
737}
738
739bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
740bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
741bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
742bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
743
744bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
745bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
746bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
747bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
748
749bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
750bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
751bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
752bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
753
754bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
755bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
756bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
757bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
758
759impl<V> RawSample for V
760where
761 V: BytesSample,
762 <V as BytesSample>::NumericType: RawSample,
763{
764 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
765 let value = self.to_number();
766 value.to_scaled_float()
767 }
768
769 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
770 let value = <V as BytesSample>::NumericType::from_scaled_float(value);
771 ConversionResult {
772 clipped: value.clipped,
773 value: V::from_number(value.value),
774 }
775 }
776}
777
778#[cfg(feature = "audio")]
780macro_rules! impl_sample_for_newtype {
781 ($newtype:ident, $bytes:expr) => {
782 unsafe impl Sample for $newtype {
783 const ZERO: $newtype = $newtype([0; $bytes]);
784 }
785 };
786}
787
788#[cfg(feature = "audio")]
789impl_sample_for_newtype!(I16_LE, 2);
790#[cfg(feature = "audio")]
791impl_sample_for_newtype!(U16_LE, 2);
792#[cfg(feature = "audio")]
793impl_sample_for_newtype!(I16_BE, 2);
794#[cfg(feature = "audio")]
795impl_sample_for_newtype!(U16_BE, 2);
796#[cfg(feature = "audio")]
797impl_sample_for_newtype!(I24_LE, 3);
798#[cfg(feature = "audio")]
799impl_sample_for_newtype!(I24_4LJ_LE, 4);
800#[cfg(feature = "audio")]
801impl_sample_for_newtype!(I24_4RJ_LE, 4);
802#[cfg(feature = "audio")]
803impl_sample_for_newtype!(U24_LE, 3);
804#[cfg(feature = "audio")]
805impl_sample_for_newtype!(U24_4LJ_LE, 4);
806#[cfg(feature = "audio")]
807impl_sample_for_newtype!(U24_4RJ_LE, 4);
808#[cfg(feature = "audio")]
809impl_sample_for_newtype!(I24_BE, 3);
810#[cfg(feature = "audio")]
811impl_sample_for_newtype!(I24_4LJ_BE, 4);
812#[cfg(feature = "audio")]
813impl_sample_for_newtype!(I24_4RJ_BE, 4);
814#[cfg(feature = "audio")]
815impl_sample_for_newtype!(U24_BE, 3);
816#[cfg(feature = "audio")]
817impl_sample_for_newtype!(U24_4LJ_BE, 4);
818#[cfg(feature = "audio")]
819impl_sample_for_newtype!(U24_4RJ_BE, 4);
820#[cfg(feature = "audio")]
821impl_sample_for_newtype!(I32_LE, 4);
822#[cfg(feature = "audio")]
823impl_sample_for_newtype!(U32_LE, 4);
824#[cfg(feature = "audio")]
825impl_sample_for_newtype!(I32_BE, 4);
826#[cfg(feature = "audio")]
827impl_sample_for_newtype!(U32_BE, 4);
828#[cfg(feature = "audio")]
829impl_sample_for_newtype!(I64_LE, 8);
830#[cfg(feature = "audio")]
831impl_sample_for_newtype!(U64_LE, 8);
832#[cfg(feature = "audio")]
833impl_sample_for_newtype!(I64_BE, 8);
834#[cfg(feature = "audio")]
835impl_sample_for_newtype!(U64_BE, 8);
836#[cfg(feature = "audio")]
837impl_sample_for_newtype!(F32_LE, 4);
838#[cfg(feature = "audio")]
839impl_sample_for_newtype!(F32_BE, 4);
840#[cfg(feature = "audio")]
841impl_sample_for_newtype!(F64_LE, 8);
842#[cfg(feature = "audio")]
843impl_sample_for_newtype!(F64_BE, 8);
844
845#[cfg(test)]
846mod tests {
847 use super::*;
848
849 macro_rules! assert_conversion_eq {
850 ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
851 assert_eq!($result.value, $value, $desc);
852 assert_eq!($result.clipped, $clipped, $desc);
853 };
854 }
855
856 macro_rules! test_to_signed_int {
857 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
858 #[test]
859 fn $fname() {
860 let val: $float = 0.25;
861 assert_conversion_eq!(
862 $int::from_scaled_float(val),
863 1 << ($bits - 3),
864 false,
865 "check +0.25"
866 );
867 let val: $float = -0.25;
868 assert_conversion_eq!(
869 $int::from_scaled_float(val),
870 -1 << ($bits - 3),
871 false,
872 "check -0.25"
873 );
874 let val: $float = 1.1;
875 assert_conversion_eq!(
876 $int::from_scaled_float(val),
877 $int::MAX,
878 true,
879 "clipped positive"
880 );
881 let val: $float = -1.1;
882 assert_conversion_eq!(
883 $int::from_scaled_float(val),
884 $int::MIN,
885 true,
886 "clipped negative"
887 );
888 }
889 };
890 }
891
892 macro_rules! test_to_unsigned_int {
893 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
894 #[test]
895 fn $fname() {
896 let val: $float = -0.5;
897 assert_conversion_eq!(
898 $int::from_scaled_float(val),
899 1 << ($bits - 2),
900 false,
901 "check -0.5"
902 );
903 let val: $float = 0.5;
904 assert_conversion_eq!(
905 $int::from_scaled_float(val),
906 $int::MAX - (1 << ($bits - 2)) + 1,
907 false,
908 "check 0.5"
909 );
910 let val: $float = 1.1;
911 assert_conversion_eq!(
912 $int::from_scaled_float(val),
913 $int::MAX,
914 true,
915 "clipped positive"
916 );
917 let val: $float = -1.1;
918 assert_conversion_eq!(
919 $int::from_scaled_float(val),
920 $int::MIN,
921 true,
922 "clipped negative"
923 );
924 }
925 };
926 }
927
928 test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
929 test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
930 test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
931 test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
932 test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
933 test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
934 test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
935 test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
936
937 test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
938 test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
939 test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
940 test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
941 test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
942 test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
943 test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
944 test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
945
946 macro_rules! test_from_signed_int {
947 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
948 #[test]
949 fn $fname() {
950 let val: $int = -1 << ($bits - 2);
951 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
952 let val: $int = 1 << ($bits - 2);
953 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
954 let val: $int = $int::MIN;
955 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
956 }
957 };
958 }
959
960 macro_rules! test_from_unsigned_int {
961 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
962 #[test]
963 fn $fname() {
964 let val: $int = 1 << ($bits - 2);
965 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
966 let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
967 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
968 let val: $int = 0;
969 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
970 }
971 };
972 }
973
974 test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
975 test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
976 test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
977 test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
978 test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
979 test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
980 test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
981 test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
982
983 test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
984 test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
985 test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
986 test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
987 test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
988 test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
989 test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
990 test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
991
992 #[test]
993 fn test_to_clamped_int() {
994 let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
995 assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
996
997 let converted = to_clamped_int::<f32, i32>(1.0e10, None);
998 assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
999
1000 let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
1001 assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
1002
1003 let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
1004 assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
1005
1006 let converted = to_clamped_int::<f64, i32>(1.0e10, None);
1007 assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
1008
1009 let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
1010 assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
1011 }
1012
1013 #[test]
1014 fn test_to_clamped_uint() {
1015 let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
1016 assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
1017
1018 let converted = to_clamped_int::<f32, u32>(1.0e10, None);
1019 assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
1020
1021 let converted = to_clamped_int::<f32, u32>(-1.0, None);
1022 assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
1023
1024 let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
1025 assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
1026
1027 let converted = to_clamped_int::<f64, u32>(1.0e10, None);
1028 assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
1029
1030 let converted = to_clamped_int::<f64, u32>(-1.0, None);
1031 assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
1032 }
1033
1034 macro_rules! test_simple_int_bytes {
1035 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1036 #[test]
1037 #[allow(non_snake_case)]
1038 fn $fname() {
1039 let number: $number = <$number>::MAX / 5 * 4;
1040 let wrapped = $wrapper(number.$to_bytes_fn());
1041 assert_eq!(number, wrapped.to_number());
1042 }
1043 };
1044 }
1045
1046 macro_rules! test_float_bytes {
1047 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
1048 #[test]
1049 #[allow(non_snake_case)]
1050 fn $fname() {
1051 let number: $number = 12345.0;
1052 let wrapped = $wrapper(number.$to_bytes_fn());
1053 assert_eq!(number, wrapped.to_number());
1054 }
1055 };
1056 }
1057
1058 test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
1059 test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
1060 test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
1061 test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
1062 test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
1063 test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1064
1065 test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1066 test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1067 test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1068 test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1069 test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1070 test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1071
1072 test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1073 test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1074 test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1075 test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1076
1077 #[test]
1078 #[allow(non_snake_case)]
1079 fn test_I24_LE() {
1080 let number = i32::MAX / 5 * 4;
1081
1082 let number = number >> 8;
1084 let number = number << 8;
1085
1086 let allbytes = number.to_le_bytes();
1087 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1090
1091 let wrapped = I24_LE(bytes);
1092 assert_eq!(number, wrapped.to_number());
1093 }
1094
1095 #[test]
1096 #[allow(non_snake_case)]
1097 fn test_I24_BE() {
1098 let number = i32::MAX / 5 * 4;
1099
1100 let number = number >> 8;
1102 let number = number << 8;
1103
1104 let allbytes = number.to_be_bytes();
1105 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1108
1109 let wrapped = I24_BE(bytes);
1110 assert_eq!(number, wrapped.to_number());
1111 }
1112
1113 #[test]
1114 #[allow(non_snake_case)]
1115 fn test_I24_4RJ_LE() {
1116 let number = i32::MAX / 5 * 4;
1117
1118 let number = number >> 8;
1120 let number = number << 8;
1121
1122 let allbytes = number.to_le_bytes();
1123 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1126
1127 let wrapped = I24_4RJ_LE(bytes);
1128 assert_eq!(number, wrapped.to_number());
1129 }
1130
1131 #[test]
1132 #[allow(non_snake_case)]
1133 fn test_I24_4RJ_BE() {
1134 let number = i32::MAX / 5 * 4;
1135
1136 let number = number >> 8;
1138 let number = number << 8;
1139
1140 let allbytes = number.to_be_bytes();
1141 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1144
1145 let wrapped = I24_4RJ_BE(bytes);
1146 assert_eq!(number, wrapped.to_number());
1147 }
1148
1149 #[test]
1150 #[allow(non_snake_case)]
1151 fn test_I24_4LJ_LE() {
1152 let number = i32::MAX / 5 * 4;
1153
1154 let number = number >> 8;
1156 let number = number << 8;
1157
1158 let allbytes = number.to_le_bytes();
1159 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1162
1163 let wrapped = I24_4LJ_LE(bytes);
1164 assert_eq!(number, wrapped.to_number());
1165 }
1166
1167 #[test]
1168 #[allow(non_snake_case)]
1169 fn test_I24_4LJ_BE() {
1170 let number = i32::MAX / 5 * 4;
1171
1172 let number = number >> 8;
1174 let number = number << 8;
1175
1176 let allbytes = number.to_be_bytes();
1177 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1180
1181 let wrapped = I24_4LJ_BE(bytes);
1182 assert_eq!(number, wrapped.to_number());
1183 }
1184
1185 #[test]
1186 #[allow(non_snake_case)]
1187 fn test_U24_LE() {
1188 let number = u32::MAX / 5 * 4;
1189
1190 let number = number >> 8;
1192 let number = number << 8;
1193
1194 let allbytes = number.to_le_bytes();
1195 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1198
1199 let wrapped = U24_LE(bytes);
1200 assert_eq!(number, wrapped.to_number());
1201 }
1202
1203 #[test]
1204 #[allow(non_snake_case)]
1205 fn test_U24_BE() {
1206 let number = u32::MAX / 5 * 4;
1207
1208 let number = number >> 8;
1210 let number = number << 8;
1211
1212 let allbytes = number.to_be_bytes();
1213 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1216
1217 let wrapped = U24_BE(bytes);
1218 assert_eq!(number, wrapped.to_number());
1219 }
1220
1221 #[test]
1222 #[allow(non_snake_case)]
1223 fn test_U24_4RJ_LE() {
1224 let number = u32::MAX / 5 * 4;
1225
1226 let number = number >> 8;
1228 let number = number << 8;
1229
1230 let allbytes = number.to_le_bytes();
1231 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1234
1235 let wrapped = U24_4RJ_LE(bytes);
1236 assert_eq!(number, wrapped.to_number());
1237 }
1238
1239 #[test]
1240 #[allow(non_snake_case)]
1241 fn test_U24_4RJ_BE() {
1242 let number = u32::MAX / 5 * 4;
1243
1244 let number = number >> 8;
1246 let number = number << 8;
1247
1248 let allbytes = number.to_be_bytes();
1249 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1252
1253 let wrapped = U24_4RJ_BE(bytes);
1254 assert_eq!(number, wrapped.to_number());
1255 }
1256
1257 #[test]
1258 #[allow(non_snake_case)]
1259 fn test_U24_4LJ_LE() {
1260 let number = u32::MAX / 5 * 4;
1261
1262 let number = number >> 8;
1264 let number = number << 8;
1265
1266 let allbytes = number.to_le_bytes();
1267 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1270
1271 let wrapped = U24_4LJ_LE(bytes);
1272 assert_eq!(number, wrapped.to_number());
1273 }
1274
1275 #[test]
1276 #[allow(non_snake_case)]
1277 fn test_U24_4LJ_BE() {
1278 let number = u32::MAX / 5 * 4;
1279
1280 let number = number >> 8;
1282 let number = number << 8;
1283
1284 let allbytes = number.to_be_bytes();
1285 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1288
1289 let wrapped = U24_4LJ_BE(bytes);
1290 assert_eq!(number, wrapped.to_number());
1291 }
1292}