1use crate::audio::sample::{Sample, i24, u24};
10
11pub mod dither {
12 use super::FromSample;
29 use crate::audio::sample::Sample;
30 use crate::audio::sample::{i24, u24};
31 use std::marker::PhantomData;
32
33 mod prng {
34 #[inline]
35 fn split_mix_64(x: &mut u64) -> u64 {
36 *x = x.wrapping_add(0x9e37_79b9_7f4a_7c15);
37 let mut z = *x;
38 z = (z ^ (z >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
39 z = (z ^ (z >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
40 z ^ (z >> 31)
41 }
42
43 pub struct Xoshiro128pp {
52 s: [u32; 4],
53 }
54
55 impl Xoshiro128pp {
56 pub fn new(mut seed: u64) -> Self {
57 let a = split_mix_64(&mut seed);
58 let b = split_mix_64(&mut seed);
59
60 Xoshiro128pp {
61 s: [
62 (a & 0xffff_ffff) as u32,
63 (a >> 32) as u32,
64 (b & 0xffff_ffff) as u32,
65 (b >> 32) as u32,
66 ],
67 }
68 }
69
70 #[inline]
71 pub fn next(&mut self) -> u32 {
72 let x = self.s[0].wrapping_add(self.s[3]);
73
74 let result = x.rotate_left(7).wrapping_add(self.s[0]);
75
76 let t = self.s[1] << 9;
77
78 self.s[2] ^= self.s[0];
79 self.s[3] ^= self.s[1];
80 self.s[1] ^= self.s[2];
81 self.s[0] ^= self.s[3];
82
83 self.s[2] ^= t;
84
85 self.s[3] = self.s[3].rotate_left(11);
86
87 result
88 }
89 }
90 }
91
92 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
96 pub struct RandomNoise(pub i32);
97
98 impl RandomNoise {
99 pub fn from(random: i32, n_bits: u32) -> Self {
101 RandomNoise(random >> (32 - n_bits))
102 }
103 }
104
105 pub trait AddNoise<S: Sample> {
107 fn add_noise(self, sample: S) -> S;
108 }
109
110 macro_rules! add_noise_impl {
111 ($sample_type:ty, $self:ident, $sample:ident, $conv:expr) => (
112 impl AddNoise<$sample_type> for RandomNoise {
113 #[inline]
114 fn add_noise($self, $sample: $sample_type) -> $sample_type { $conv }
115 }
116 )
117 }
118
119 add_noise_impl!(i8, self, s, {
120 i8::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
121 });
122 add_noise_impl!(u8, self, s, {
123 u8::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
124 });
125 add_noise_impl!(i16, self, s, {
126 i16::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
127 });
128 add_noise_impl!(u16, self, s, {
129 u16::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
130 });
131 add_noise_impl!(i24, self, s, {
132 i24::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
133 });
134 add_noise_impl!(u24, self, s, {
135 u24::from_sample(f32::from_sample(s) + f32::from_sample(self.0))
136 });
137 add_noise_impl!(i32, self, s, {
138 i32::from_sample(f64::from_sample(s) + f64::from_sample(self.0))
139 });
140 add_noise_impl!(u32, self, s, {
141 u32::from_sample(f64::from_sample(s) + f64::from_sample(self.0))
142 });
143 add_noise_impl!(f32, self, s, s + f32::from_sample(self.0));
144 add_noise_impl!(f64, self, s, s + f64::from_sample(self.0));
145
146 pub trait Dither<F: Sample, T: Sample> {
148 fn dither(&mut self, sample: F) -> F;
151 }
152
153 pub struct Identity<F: Sample, T: Sample> {
155 from_type: PhantomData<F>,
156 to_type: PhantomData<T>,
157 }
158
159 impl<F: Sample, T: Sample> Identity<F, T> {
160 pub fn new() -> Self {
161 Identity { from_type: PhantomData, to_type: PhantomData }
162 }
163 }
164
165 impl<F: Sample, T: Sample> Dither<F, T> for Identity<F, T> {
166 fn dither(&mut self, sample: F) -> F {
167 sample
168 }
169 }
170
171 impl<F: Sample, T: Sample> Default for Identity<F, T> {
172 fn default() -> Self {
173 Self::new()
174 }
175 }
176
177 pub struct Rectangular<F: Sample, T: Sample> {
179 prng: prng::Xoshiro128pp,
180 from_type: PhantomData<F>,
181 to_type: PhantomData<T>,
182 }
183
184 impl<F: Sample, T: Sample> Rectangular<F, T> {
185 pub fn new() -> Self {
186 Rectangular {
187 prng: prng::Xoshiro128pp::new(0xb2c1_01f4_425b_987e),
188 from_type: PhantomData,
189 to_type: PhantomData,
190 }
191 }
192 }
193
194 impl<F: Sample, T: Sample> Dither<F, T> for Rectangular<F, T>
195 where
196 RandomNoise: AddNoise<F>,
197 {
198 fn dither(&mut self, sample: F) -> F {
199 debug_assert!(F::EFF_BITS > T::EFF_BITS);
202
203 let dither_bits = 32 - T::EFF_BITS;
205
206 let noise = RandomNoise::from(self.prng.next() as i32, dither_bits);
208 noise.add_noise(sample)
209 }
210 }
211
212 impl<F: Sample, T: Sample> Default for Rectangular<F, T> {
213 fn default() -> Self {
214 Self::new()
215 }
216 }
217
218 pub struct Triangular<F: Sample, T: Sample> {
220 prng: prng::Xoshiro128pp,
221 from_type: PhantomData<F>,
222 to_type: PhantomData<T>,
223 }
224
225 impl<F: Sample, T: Sample> Triangular<F, T> {
226 pub fn new() -> Self {
227 Triangular {
228 prng: prng::Xoshiro128pp::new(0xb2c1_01f4_425b_987e),
229 from_type: PhantomData,
230 to_type: PhantomData,
231 }
232 }
233 }
234
235 impl<F: Sample, T: Sample> Dither<F, T> for Triangular<F, T>
236 where
237 RandomNoise: AddNoise<F>,
238 {
239 fn dither(&mut self, sample: F) -> F {
240 debug_assert!(F::EFF_BITS > T::EFF_BITS);
241
242 let dither_bits = 32 - T::EFF_BITS;
243
244 let tpdf = (self.prng.next() as i32 >> 1) + (self.prng.next() as i32 >> 1);
246
247 let noise = RandomNoise::from(tpdf, dither_bits);
249 noise.add_noise(sample)
250 }
251 }
252
253 impl<F: Sample, T: Sample> Default for Triangular<F, T> {
254 fn default() -> Self {
255 Self::new()
256 }
257 }
258
259 #[non_exhaustive]
261 pub enum DitherType {
262 Identity,
264 Rectangular,
266 Triangular,
268 }
269
270 pub trait MaybeDither<T: Sample>: Sample {
273 const DITHERABLE: bool;
274
275 fn maybe_dither<D: Dither<Self, T>>(self, dither: &mut D) -> Self;
276 }
277
278 macro_rules! dither_never {
280 ($to:ty, $from:ty) => {
281 impl MaybeDither<$to> for $from {
282 const DITHERABLE: bool = false;
283 #[inline(always)]
284 fn maybe_dither<D: Dither<$from, $to>>(self, _: &mut D) -> Self {
285 self
286 }
287 }
288 };
289 }
290
291 macro_rules! dither_maybe {
293 ($to:ty, $from:ty) => {
294 impl MaybeDither<$to> for $from {
295 const DITHERABLE: bool = true;
296 #[inline(always)]
297 fn maybe_dither<D: Dither<$from, $to>>(self, dither: &mut D) -> Self {
298 dither.dither(self)
299 }
300 }
301 };
302 }
303
304 dither_never!(u8, u8);
306 dither_maybe!(u8, u16);
307 dither_maybe!(u8, u24);
308 dither_maybe!(u8, u32);
309 dither_never!(u8, i8);
310 dither_maybe!(u8, i16);
311 dither_maybe!(u8, i24);
312 dither_maybe!(u8, i32);
313 dither_never!(u8, f32);
314 dither_never!(u8, f64);
315
316 dither_never!(u16, u8);
318 dither_never!(u16, u16);
319 dither_maybe!(u16, u24);
320 dither_maybe!(u16, u32);
321 dither_never!(u16, i8);
322 dither_never!(u16, i16);
323 dither_maybe!(u16, i24);
324 dither_maybe!(u16, i32);
325 dither_never!(u16, f32);
326 dither_never!(u16, f64);
327
328 dither_never!(u24, u8);
330 dither_never!(u24, u16);
331 dither_never!(u24, u24);
332 dither_maybe!(u24, u32);
333 dither_never!(u24, i8);
334 dither_never!(u24, i16);
335 dither_never!(u24, i24);
336 dither_maybe!(u24, i32);
337 dither_never!(u24, f32);
338 dither_never!(u24, f64);
339
340 dither_never!(u32, u8);
342 dither_never!(u32, u16);
343 dither_never!(u32, u24);
344 dither_never!(u32, u32);
345 dither_never!(u32, i8);
346 dither_never!(u32, i16);
347 dither_never!(u32, i24);
348 dither_never!(u32, i32);
349 dither_never!(u32, f32);
350 dither_never!(u32, f64);
351
352 dither_never!(i8, u8);
354 dither_maybe!(i8, u16);
355 dither_maybe!(i8, u24);
356 dither_maybe!(i8, u32);
357 dither_never!(i8, i8);
358 dither_maybe!(i8, i16);
359 dither_maybe!(i8, i24);
360 dither_maybe!(i8, i32);
361 dither_never!(i8, f32);
362 dither_never!(i8, f64);
363
364 dither_never!(i16, u8);
366 dither_never!(i16, u16);
367 dither_maybe!(i16, u24);
368 dither_maybe!(i16, u32);
369 dither_never!(i16, i8);
370 dither_never!(i16, i16);
371 dither_maybe!(i16, i24);
372 dither_maybe!(i16, i32);
373 dither_never!(i16, f32);
374 dither_never!(i16, f64);
375
376 dither_never!(i24, u8);
378 dither_never!(i24, u16);
379 dither_never!(i24, u24);
380 dither_maybe!(i24, u32);
381 dither_never!(i24, i8);
382 dither_never!(i24, i16);
383 dither_never!(i24, i24);
384 dither_maybe!(i24, i32);
385 dither_never!(i24, f32);
386 dither_never!(i24, f64);
387
388 dither_never!(i32, u8);
390 dither_never!(i32, u16);
391 dither_never!(i32, u24);
392 dither_never!(i32, u32);
393 dither_never!(i32, i8);
394 dither_never!(i32, i16);
395 dither_never!(i32, i24);
396 dither_never!(i32, i32);
397 dither_never!(i32, f32);
398 dither_never!(i32, f64);
399
400 dither_never!(f32, u8);
402 dither_never!(f32, u16);
403 dither_never!(f32, u24);
404 dither_never!(f32, u32);
405 dither_never!(f32, i8);
406 dither_never!(f32, i16);
407 dither_never!(f32, i24);
408 dither_never!(f32, i32);
409 dither_never!(f32, f32);
410 dither_never!(f32, f64);
411
412 dither_never!(f64, u8);
414 dither_never!(f64, u16);
415 dither_never!(f64, u24);
416 dither_never!(f64, u32);
417 dither_never!(f64, i8);
418 dither_never!(f64, i16);
419 dither_never!(f64, i24);
420 dither_never!(f64, i32);
421 dither_never!(f64, f32);
422 dither_never!(f64, f64);
423}
424
425pub trait FromSample<F> {
430 fn from_sample(val: F) -> Self;
431}
432
433macro_rules! impl_convert {
444 ($from:ty, $to:ty, $sample:ident, $func:expr) => {
445 impl FromSample<$from> for $to {
446 #[inline(always)]
447 fn from_sample($sample: $from) -> Self {
448 $func
449 }
450 }
451 };
452}
453
454#[inline(always)]
457fn i8_to_u8(s: i8) -> u8 {
458 (s as u8).wrapping_add(0x80)
459}
460
461impl_convert!(i8, u8, s, i8_to_u8(s)); impl_convert!(i8, u16, s, (i8_to_u8(s) as u16) << 8); impl_convert!(i8, u24, s, u24::from((i8_to_u8(s) as u32) << 16)); impl_convert!(i8, u32, s, (i8_to_u8(s) as u32) << 24); impl_convert!(i8, i8, s, s); impl_convert!(i8, i16, s, (s as i16) << 8); impl_convert!(i8, i24, s, i24::from((s as i32) << 16)); impl_convert!(i8, i32, s, (s as i32) << 24); impl_convert!(i8, f32, s, s as f32 / 128.0); impl_convert!(i8, f64, s, s as f64 / 128.0); #[inline(always)]
477fn i16_to_u16(s: i16) -> u16 {
478 (s as u16).wrapping_add(0x8000)
479}
480
481impl_convert!(i16, u8, s, (i16_to_u16(s) >> 8) as u8); impl_convert!(i16, u16, s, i16_to_u16(s)); impl_convert!(i16, u24, s, u24::from((i16_to_u16(s) as u32) << 8)); impl_convert!(i16, u32, s, (i16_to_u16(s) as u32) << 16); impl_convert!(i16, i8, s, (s >> 8) as i8); impl_convert!(i16, i16, s, s); impl_convert!(i16, i24, s, i24::from((s as i32) << 8)); impl_convert!(i16, i32, s, (s as i32) << 16); impl_convert!(i16, f32, s, s as f32 / 32_768.0); impl_convert!(i16, f64, s, s as f64 / 32_768.0); #[inline(always)]
497fn i24_to_u32(s: i24) -> u32 {
498 ((s.clamped().inner() << 8) as u32).wrapping_add(0x8000_0000)
499}
500
501impl_convert!(i24, u8, s, (i24_to_u32(s) >> 24) as u8); impl_convert!(i24, u16, s, (i24_to_u32(s) >> 16) as u16); impl_convert!(i24, u24, s, u24::from(i24_to_u32(s) >> 8)); impl_convert!(i24, u32, s, i24_to_u32(s)); impl_convert!(i24, i8, s, (s.clamped().inner() >> 16) as i8); impl_convert!(i24, i16, s, (s.clamped().inner() >> 8) as i16); impl_convert!(i24, i24, s, s); impl_convert!(i24, i32, s, (s.clamped().inner()) << 8); impl_convert!(i24, f32, s, s.clamped().inner() as f32 / 8_388_608.0); impl_convert!(i24, f64, s, s.clamped().inner() as f64 / 8_388_608.0); #[inline(always)]
517fn i32_to_u32(s: i32) -> u32 {
518 (s as u32).wrapping_add(0x8000_0000)
519}
520
521impl_convert!(i32, u8, s, (i32_to_u32(s) >> 24) as u8); impl_convert!(i32, u16, s, (i32_to_u32(s) >> 16) as u16); impl_convert!(i32, u24, s, u24::from(i32_to_u32(s) >> 8)); impl_convert!(i32, u32, s, i32_to_u32(s)); impl_convert!(i32, i8, s, (s >> 24) as i8); impl_convert!(i32, i16, s, (s >> 16) as i16); impl_convert!(i32, i24, s, i24::from(s >> 8)); impl_convert!(i32, i32, s, s); impl_convert!(i32, f32, s, (s as f64 / 2_147_483_648.0) as f32); impl_convert!(i32, f64, s, s as f64 / 2_147_483_648.0); impl_convert!(u8, u8, s, s); impl_convert!(u8, u16, s, (s as u16) << 8); impl_convert!(u8, u24, s, u24::from((s as u32) << 16)); impl_convert!(u8, u32, s, (s as u32) << 24); impl_convert!(u8, i8, s, s.wrapping_sub(0x80) as i8); impl_convert!(u8, i16, s, ((s.wrapping_sub(0x80) as i8) as i16) << 8); impl_convert!(u8, i24, s, i24::from(((s.wrapping_sub(0x80) as i8) as i32) << 16)); impl_convert!(u8, i32, s, ((s.wrapping_sub(0x80) as i8) as i32) << 24); impl_convert!(u8, f32, s, ((s as f32) / 128.0) - 1.0); impl_convert!(u8, f64, s, ((s as f64) / 128.0) - 1.0); impl_convert!(u16, u8, s, (s >> 8) as u8); impl_convert!(u16, u16, s, s); impl_convert!(u16, u24, s, u24::from((s as u32) << 8)); impl_convert!(u16, u32, s, (s as u32) << 16); impl_convert!(u16, i8, s, (s.wrapping_sub(0x8000) >> 8) as i8); impl_convert!(u16, i16, s, s.wrapping_sub(0x8000) as i16); impl_convert!(u16, i24, s, i24::from(((s.wrapping_sub(0x8000) as i16) as i32) << 8)); impl_convert!(u16, i32, s, ((s.wrapping_sub(0x8000) as i16) as i32) << 16); impl_convert!(u16, f32, s, ((s as f32) / 32_768.0) - 1.0); impl_convert!(u16, f64, s, ((s as f64) / 32_768.0) - 1.0); impl_convert!(u24, u8, s, (s.clamped().inner() >> 16) as u8); impl_convert!(u24, u16, s, (s.clamped().inner() >> 8) as u16); impl_convert!(u24, u24, s, s); impl_convert!(u24, u32, s, s.clamped().inner() << 8); impl_convert!(u24, i8, s, (s.clamped().inner().wrapping_sub(0x80_0000) >> 16) as i8); impl_convert!(u24, i16, s, (s.clamped().inner().wrapping_sub(0x80_0000) >> 8) as i16); impl_convert!(u24, i24, s, i24::from(s.clamped().inner().wrapping_sub(0x80_0000) as i32)); impl_convert!(u24, i32, s, (s.clamped().inner().wrapping_sub(0x80_0000) << 8) as i32); impl_convert!(u24, f32, s, ((s.clamped().inner() as f32) / 8_388_608.0) - 1.0); impl_convert!(u24, f64, s, ((s.clamped().inner() as f64) / 8_388_608.0) - 1.0); impl_convert!(u32, u8, s, (s >> 24) as u8); impl_convert!(u32, u16, s, (s >> 16) as u16); impl_convert!(u32, u24, s, u24::from(s >> 8)); impl_convert!(u32, u32, s, s); impl_convert!(u32, i8, s, (s.wrapping_sub(0x8000_0000) >> 24) as i8); impl_convert!(u32, i16, s, (s.wrapping_sub(0x8000_0000) >> 16) as i16); impl_convert!(u32, i24, s, i24::from((s.wrapping_sub(0x8000_0000) as i32) >> 8)); impl_convert!(u32, i32, s, s.wrapping_sub(0x8000_0000) as i32); impl_convert!(u32, f32, s, (((s as f64) / 2_147_483_648.0) - 1.0) as f32); impl_convert!(u32, f64, s, ((s as f64) / 2_147_483_648.0) - 1.0); impl_convert!(f32, u8, s, ((s.clamped() + 1.0) * 128.0) as u8); impl_convert!(f32, u16, s, ((s.clamped() + 1.0) * 32_768.0) as u16); impl_convert!(f32, u24, s, u24::from(((s.clamped() + 1.0) * 8_388_608.0) as u32)); impl_convert!(f32, u32, s, ((s.clamped() + 1.0) as f64 * 2_147_483_648.0) as u32); impl_convert!(f32, i8, s, (s.clamped() * 128.0) as i8); impl_convert!(f32, i16, s, (s.clamped() * 32_768.0) as i16); impl_convert!(f32, i24, s, i24::from((s.clamped() * 8_388_608.0) as i32)); impl_convert!(f32, i32, s, (s.clamped() as f64 * 2_147_483_648.0) as i32); impl_convert!(f32, f32, s, s); impl_convert!(f32, f64, s, s as f64); impl_convert!(f64, u8, s, ((s.clamped() + 1.0) * 128.0) as u8); impl_convert!(f64, u16, s, ((s.clamped() + 1.0) * 32_768.0) as u16); impl_convert!(f64, u24, s, u24::from(((s.clamped() + 1.0) * 8_388_608.0) as u32)); impl_convert!(f64, u32, s, ((s.clamped() + 1.0) * 2_147_483_648.0) as u32); impl_convert!(f64, i8, s, (s.clamped() * 128.0) as i8); impl_convert!(f64, i16, s, (s.clamped() * 32_768.0) as i16); impl_convert!(f64, i24, s, i24::from((s.clamped() * 8_388_608.0) as i32)); impl_convert!(f64, i32, s, (s.clamped() * 2_147_483_648.0) as i32); impl_convert!(f64, f32, s, s as f32); impl_convert!(f64, f64, s, s); pub trait IntoSample<T> {
629 fn into_sample(self) -> T;
630}
631
632impl<F, T: FromSample<F>> IntoSample<T> for F {
633 #[inline]
634 fn into_sample(self) -> T {
635 T::from_sample(self)
636 }
637}
638
639pub trait ReversibleSample<S>: Sample + FromSample<S> + IntoSample<S> {}
642impl<S, T> ReversibleSample<S> for T where T: Sample + FromSample<S> + IntoSample<S> {}
643
644pub trait ConvertibleSample:
645 Sample
646 + FromSample<i8>
647 + FromSample<u8>
648 + FromSample<i16>
649 + FromSample<u16>
650 + FromSample<i24>
651 + FromSample<u24>
652 + FromSample<i32>
653 + FromSample<u32>
654 + FromSample<f32>
655 + FromSample<f64>
656{
657}
658
659impl<S> ConvertibleSample for S where
660 S: Sample
661 + FromSample<i8>
662 + FromSample<u8>
663 + FromSample<i16>
664 + FromSample<u16>
665 + FromSample<i24>
666 + FromSample<u24>
667 + FromSample<i32>
668 + FromSample<u32>
669 + FromSample<f32>
670 + FromSample<f64>
671{
672}
673
674#[cfg(test)]
675mod tests {
676 use super::FromSample;
677 use crate::audio::sample::{Sample, i24, u24};
678
679 #[test]
680 fn verify_u8_from_sample() {
681 assert_eq!(u8::from_sample(u8::MAX), u8::MAX);
682 assert_eq!(u8::from_sample(u8::MID), u8::MID);
683 assert_eq!(u8::from_sample(u8::MIN), u8::MIN);
684
685 assert_eq!(u8::from_sample(u16::MAX), u8::MAX);
686 assert_eq!(u8::from_sample(u16::MID), u8::MID);
687 assert_eq!(u8::from_sample(u16::MIN), u8::MIN);
688
689 assert_eq!(u8::from_sample(u24::MAX), u8::MAX);
690 assert_eq!(u8::from_sample(u24::MID), u8::MID);
691 assert_eq!(u8::from_sample(u24::MIN), u8::MIN);
692
693 assert_eq!(u8::from_sample(u32::MAX), u8::MAX);
694 assert_eq!(u8::from_sample(u32::MID), u8::MID);
695 assert_eq!(u8::from_sample(u32::MIN), u8::MIN);
696
697 assert_eq!(u8::from_sample(i8::MAX), u8::MAX);
698 assert_eq!(u8::from_sample(i8::MID), u8::MID);
699 assert_eq!(u8::from_sample(i8::MIN), u8::MIN);
700
701 assert_eq!(u8::from_sample(i16::MAX), u8::MAX);
702 assert_eq!(u8::from_sample(i16::MID), u8::MID);
703 assert_eq!(u8::from_sample(i16::MIN), u8::MIN);
704
705 assert_eq!(u8::from_sample(i24::MAX), u8::MAX);
706 assert_eq!(u8::from_sample(i24::MID), u8::MID);
707 assert_eq!(u8::from_sample(i24::MIN), u8::MIN);
708
709 assert_eq!(u8::from_sample(i32::MAX), u8::MAX);
710 assert_eq!(u8::from_sample(i32::MID), u8::MID);
711 assert_eq!(u8::from_sample(i32::MIN), u8::MIN);
712
713 assert_eq!(u8::from_sample(1.0f32), u8::MAX);
714 assert_eq!(u8::from_sample(0f32), u8::MID);
715 assert_eq!(u8::from_sample(-1.0f32), u8::MIN);
716
717 assert_eq!(u8::from_sample(1.0f64), u8::MAX);
718 assert_eq!(u8::from_sample(0f64), u8::MID);
719 assert_eq!(u8::from_sample(-1.0f64), u8::MIN);
720 }
721
722 #[test]
723 fn verify_u16_from_sample() {
724 assert_eq!(u16::from_sample(u8::MAX), u16::MAX - 255);
725 assert_eq!(u16::from_sample(u8::MID), u16::MID);
726 assert_eq!(u16::from_sample(u8::MIN), u16::MIN);
727
728 assert_eq!(u16::from_sample(u16::MAX), u16::MAX);
729 assert_eq!(u16::from_sample(u16::MID), u16::MID);
730 assert_eq!(u16::from_sample(u16::MIN), u16::MIN);
731
732 assert_eq!(u16::from_sample(u24::MAX), u16::MAX);
733 assert_eq!(u16::from_sample(u24::MID), u16::MID);
734 assert_eq!(u16::from_sample(u24::MIN), u16::MIN);
735
736 assert_eq!(u16::from_sample(u32::MAX), u16::MAX);
737 assert_eq!(u16::from_sample(u32::MID), u16::MID);
738 assert_eq!(u16::from_sample(u32::MIN), u16::MIN);
739
740 assert_eq!(u16::from_sample(i8::MAX), u16::MAX - 255);
741 assert_eq!(u16::from_sample(i8::MID), u16::MID);
742 assert_eq!(u16::from_sample(i8::MIN), u16::MIN);
743
744 assert_eq!(u16::from_sample(i16::MAX), u16::MAX);
745 assert_eq!(u16::from_sample(i16::MID), u16::MID);
746 assert_eq!(u16::from_sample(i16::MIN), u16::MIN);
747
748 assert_eq!(u16::from_sample(i24::MAX), u16::MAX);
749 assert_eq!(u16::from_sample(i24::MID), u16::MID);
750 assert_eq!(u16::from_sample(i24::MIN), u16::MIN);
751
752 assert_eq!(u16::from_sample(i32::MAX), u16::MAX);
753 assert_eq!(u16::from_sample(i32::MID), u16::MID);
754 assert_eq!(u16::from_sample(i32::MIN), u16::MIN);
755
756 assert_eq!(u16::from_sample(1.0f32), u16::MAX);
757 assert_eq!(u16::from_sample(0f32), u16::MID);
758 assert_eq!(u16::from_sample(-1.0f32), u16::MIN);
759
760 assert_eq!(u16::from_sample(1.0f64), u16::MAX);
761 assert_eq!(u16::from_sample(0f64), u16::MID);
762 assert_eq!(u16::from_sample(-1.0f64), u16::MIN);
763 }
764
765 #[test]
766 fn verify_u24_from_sample() {
767 assert_eq!(u24::from_sample(u8::MAX), u24::MAX - u24::from(65_535u32));
768 assert_eq!(u24::from_sample(u8::MID), u24::MID);
769 assert_eq!(u24::from_sample(u8::MIN), u24::MIN);
770
771 assert_eq!(u24::from_sample(u16::MAX), u24::MAX - u24::from(255u32));
772 assert_eq!(u24::from_sample(u16::MID), u24::MID);
773 assert_eq!(u24::from_sample(u16::MIN), u24::MIN);
774
775 assert_eq!(u24::from_sample(u24::MAX), u24::MAX);
776 assert_eq!(u24::from_sample(u24::MID), u24::MID);
777 assert_eq!(u24::from_sample(u24::MIN), u24::MIN);
778
779 assert_eq!(u24::from_sample(u32::MAX), u24::MAX);
780 assert_eq!(u24::from_sample(u32::MID), u24::MID);
781 assert_eq!(u24::from_sample(u32::MIN), u24::MIN);
782
783 assert_eq!(u24::from_sample(i8::MAX), u24::MAX - u24::from(65_535u32));
784 assert_eq!(u24::from_sample(i8::MID), u24::MID);
785 assert_eq!(u24::from_sample(i8::MIN), u24::MIN);
786
787 assert_eq!(u24::from_sample(i16::MAX), u24::MAX - u24::from(255u32));
788 assert_eq!(u24::from_sample(i16::MID), u24::MID);
789 assert_eq!(u24::from_sample(i16::MIN), u24::MIN);
790
791 assert_eq!(u24::from_sample(i24::MAX), u24::MAX);
792 assert_eq!(u24::from_sample(i24::MID), u24::MID);
793 assert_eq!(u24::from_sample(i24::MIN), u24::MIN);
794
795 assert_eq!(u24::from_sample(i32::MAX), u24::MAX);
796 assert_eq!(u24::from_sample(i32::MID), u24::MID);
797 assert_eq!(u24::from_sample(i32::MIN), u24::MIN);
798
799 assert_eq!(u24::from_sample(1.0f32), u24::MAX);
800 assert_eq!(u24::from_sample(0f32), u24::MID);
801 assert_eq!(u24::from_sample(-1.0f32), u24::MIN);
802
803 assert_eq!(u24::from_sample(1.0f64), u24::MAX);
804 assert_eq!(u24::from_sample(0f64), u24::MID);
805 assert_eq!(u24::from_sample(-1.0f64), u24::MIN);
806 }
807
808 #[test]
809 fn verify_u32_from_sample() {
810 assert_eq!(u32::from_sample(u8::MAX), u32::MAX - 16_777_215);
811 assert_eq!(u32::from_sample(u8::MID), u32::MID);
812 assert_eq!(u32::from_sample(u8::MIN), u32::MIN);
813
814 assert_eq!(u32::from_sample(u16::MAX), u32::MAX - 65_535);
815 assert_eq!(u32::from_sample(u16::MID), u32::MID);
816 assert_eq!(u32::from_sample(u16::MIN), u32::MIN);
817
818 assert_eq!(u32::from_sample(u24::MAX), u32::MAX - 255);
819 assert_eq!(u32::from_sample(u24::MID), u32::MID);
820 assert_eq!(u32::from_sample(u24::MIN), u32::MIN);
821
822 assert_eq!(u32::from_sample(u32::MAX), u32::MAX);
823 assert_eq!(u32::from_sample(u32::MID), u32::MID);
824 assert_eq!(u32::from_sample(u32::MIN), u32::MIN);
825
826 assert_eq!(u32::from_sample(i8::MAX), u32::MAX - 16_777_215);
827 assert_eq!(u32::from_sample(i8::MID), u32::MID);
828 assert_eq!(u32::from_sample(i8::MIN), u32::MIN);
829
830 assert_eq!(u32::from_sample(i16::MAX), u32::MAX - 65_535);
831 assert_eq!(u32::from_sample(i16::MID), u32::MID);
832 assert_eq!(u32::from_sample(i16::MIN), u32::MIN);
833
834 assert_eq!(u32::from_sample(i24::MAX), u32::MAX - 255);
835 assert_eq!(u32::from_sample(i24::MID), u32::MID);
836 assert_eq!(u32::from_sample(i24::MIN), u32::MIN);
837
838 assert_eq!(u32::from_sample(i32::MAX), u32::MAX);
839 assert_eq!(u32::from_sample(i32::MID), u32::MID);
840 assert_eq!(u32::from_sample(i32::MIN), u32::MIN);
841
842 assert_eq!(u32::from_sample(1.0f32), u32::MAX);
843 assert_eq!(u32::from_sample(0f32), u32::MID);
844 assert_eq!(u32::from_sample(-1.0f32), u32::MIN);
845
846 assert_eq!(u32::from_sample(1.0f64), u32::MAX);
847 assert_eq!(u32::from_sample(0f64), u32::MID);
848 assert_eq!(u32::from_sample(-1.0f64), u32::MIN);
849 }
850
851 #[test]
852 fn verify_i8_from_sample() {
853 assert_eq!(i8::from_sample(u8::MAX), i8::MAX);
854 assert_eq!(i8::from_sample(u8::MID), i8::MID);
855 assert_eq!(i8::from_sample(u8::MIN), i8::MIN);
856
857 assert_eq!(i8::from_sample(u16::MAX), i8::MAX);
858 assert_eq!(i8::from_sample(u16::MID), i8::MID);
859 assert_eq!(i8::from_sample(u16::MIN), i8::MIN);
860
861 assert_eq!(i8::from_sample(u24::MAX), i8::MAX);
862 assert_eq!(i8::from_sample(u24::MID), i8::MID);
863 assert_eq!(i8::from_sample(u24::MIN), i8::MIN);
864
865 assert_eq!(i8::from_sample(u32::MAX), i8::MAX);
866 assert_eq!(i8::from_sample(u32::MID), i8::MID);
867 assert_eq!(i8::from_sample(u32::MIN), i8::MIN);
868
869 assert_eq!(i8::from_sample(i8::MAX), i8::MAX);
870 assert_eq!(i8::from_sample(i8::MID), i8::MID);
871 assert_eq!(i8::from_sample(i8::MIN), i8::MIN);
872
873 assert_eq!(i8::from_sample(i16::MAX), i8::MAX);
874 assert_eq!(i8::from_sample(i16::MID), i8::MID);
875 assert_eq!(i8::from_sample(i16::MIN), i8::MIN);
876
877 assert_eq!(i8::from_sample(i24::MAX), i8::MAX);
878 assert_eq!(i8::from_sample(i24::MID), i8::MID);
879 assert_eq!(i8::from_sample(i24::MIN), i8::MIN);
880
881 assert_eq!(i8::from_sample(i32::MAX), i8::MAX);
882 assert_eq!(i8::from_sample(i32::MID), i8::MID);
883 assert_eq!(i8::from_sample(i32::MIN), i8::MIN);
884
885 assert_eq!(i8::from_sample(1.0f32), i8::MAX);
886 assert_eq!(i8::from_sample(0f32), i8::MID);
887 assert_eq!(i8::from_sample(-1.0f32), i8::MIN);
888
889 assert_eq!(i8::from_sample(1.0f64), i8::MAX);
890 assert_eq!(i8::from_sample(0f64), i8::MID);
891 assert_eq!(i8::from_sample(-1.0f64), i8::MIN);
892 }
893
894 #[test]
895 fn verify_i16_from_sample() {
896 assert_eq!(i16::from_sample(u8::MAX), i16::MAX - 255);
897 assert_eq!(i16::from_sample(u8::MID), i16::MID);
898 assert_eq!(i16::from_sample(u8::MIN), i16::MIN);
899
900 assert_eq!(i16::from_sample(u16::MAX), i16::MAX);
901 assert_eq!(i16::from_sample(u16::MID), i16::MID);
902 assert_eq!(i16::from_sample(u16::MIN), i16::MIN);
903
904 assert_eq!(i16::from_sample(u24::MAX), i16::MAX);
905 assert_eq!(i16::from_sample(u24::MID), i16::MID);
906 assert_eq!(i16::from_sample(u24::MIN), i16::MIN);
907
908 assert_eq!(i16::from_sample(u32::MAX), i16::MAX);
909 assert_eq!(i16::from_sample(u32::MID), i16::MID);
910 assert_eq!(i16::from_sample(u32::MIN), i16::MIN);
911
912 assert_eq!(i16::from_sample(i8::MAX), i16::MAX - 255);
913 assert_eq!(i16::from_sample(i8::MID), i16::MID);
914 assert_eq!(i16::from_sample(i8::MIN), i16::MIN);
915
916 assert_eq!(i16::from_sample(i16::MAX), i16::MAX);
917 assert_eq!(i16::from_sample(i16::MID), i16::MID);
918 assert_eq!(i16::from_sample(i16::MIN), i16::MIN);
919
920 assert_eq!(i16::from_sample(i24::MAX), i16::MAX);
921 assert_eq!(i16::from_sample(i24::MID), i16::MID);
922 assert_eq!(i16::from_sample(i24::MIN), i16::MIN);
923
924 assert_eq!(i16::from_sample(i32::MAX), i16::MAX);
925 assert_eq!(i16::from_sample(i32::MID), i16::MID);
926 assert_eq!(i16::from_sample(i32::MIN), i16::MIN);
927
928 assert_eq!(i16::from_sample(1.0f32), i16::MAX);
929 assert_eq!(i16::from_sample(0f32), i16::MID);
930 assert_eq!(i16::from_sample(-1.0f32), i16::MIN);
931
932 assert_eq!(i16::from_sample(1.0f64), i16::MAX);
933 assert_eq!(i16::from_sample(0f64), i16::MID);
934 assert_eq!(i16::from_sample(-1.0f64), i16::MIN);
935 }
936
937 #[test]
938 fn verify_i24_from_sample() {
939 assert_eq!(i24::from_sample(u8::MAX), i24::MAX - i24::from(65_535));
940 assert_eq!(i24::from_sample(u8::MID), i24::MID);
941 assert_eq!(i24::from_sample(u8::MIN), i24::MIN);
942
943 assert_eq!(i24::from_sample(u16::MAX), i24::MAX - i24::from(255));
944 assert_eq!(i24::from_sample(u16::MID), i24::MID);
945 assert_eq!(i24::from_sample(u16::MIN), i24::MIN);
946
947 assert_eq!(i24::from_sample(u24::MAX), i24::MAX);
948 assert_eq!(i24::from_sample(u24::MID), i24::MID);
949 assert_eq!(i24::from_sample(u24::MIN), i24::MIN);
950
951 assert_eq!(i24::from_sample(u32::MAX), i24::MAX);
952 assert_eq!(i24::from_sample(u32::MID), i24::MID);
953 assert_eq!(i24::from_sample(u32::MIN), i24::MIN);
954
955 assert_eq!(i24::from_sample(i8::MAX), i24::MAX - i24::from(65_535));
956 assert_eq!(i24::from_sample(i8::MID), i24::MID);
957 assert_eq!(i24::from_sample(i8::MIN), i24::MIN);
958
959 assert_eq!(i24::from_sample(i16::MAX), i24::MAX - i24::from(255));
960 assert_eq!(i24::from_sample(i16::MID), i24::MID);
961 assert_eq!(i24::from_sample(i16::MIN), i24::MIN);
962
963 assert_eq!(i24::from_sample(i24::MAX), i24::MAX);
964 assert_eq!(i24::from_sample(i24::MID), i24::MID);
965 assert_eq!(i24::from_sample(i24::MIN), i24::MIN);
966
967 assert_eq!(i24::from_sample(i32::MAX), i24::MAX);
968 assert_eq!(i24::from_sample(i32::MID), i24::MID);
969 assert_eq!(i24::from_sample(i32::MIN), i24::MIN);
970
971 assert_eq!(i24::from_sample(1.0f32), i24::MAX);
972 assert_eq!(i24::from_sample(0f32), i24::MID);
973 assert_eq!(i24::from_sample(-1.0f32), i24::MIN);
974
975 assert_eq!(i24::from_sample(1.0f64), i24::MAX);
976 assert_eq!(i24::from_sample(0f64), i24::MID);
977 assert_eq!(i24::from_sample(-1.0f64), i24::MIN);
978 }
979
980 #[test]
981 fn verify_i32_from_sample() {
982 assert_eq!(i32::from_sample(u8::MAX), i32::MAX - 16_777_215);
983 assert_eq!(i32::from_sample(u8::MID), i32::MID);
984 assert_eq!(i32::from_sample(u8::MIN), i32::MIN);
985
986 assert_eq!(i32::from_sample(u16::MAX), i32::MAX - 65_535);
987 assert_eq!(i32::from_sample(u16::MID), i32::MID);
988 assert_eq!(i32::from_sample(u16::MIN), i32::MIN);
989
990 assert_eq!(i32::from_sample(u24::MAX), i32::MAX - 255);
991 assert_eq!(i32::from_sample(u24::MID), i32::MID);
992 assert_eq!(i32::from_sample(u24::MIN), i32::MIN);
993
994 assert_eq!(i32::from_sample(u32::MAX), i32::MAX);
995 assert_eq!(i32::from_sample(u32::MID), i32::MID);
996 assert_eq!(i32::from_sample(u32::MIN), i32::MIN);
997
998 assert_eq!(i32::from_sample(i8::MAX), i32::MAX - 16_777_215);
999 assert_eq!(i32::from_sample(i8::MID), i32::MID);
1000 assert_eq!(i32::from_sample(i8::MIN), i32::MIN);
1001
1002 assert_eq!(i32::from_sample(i16::MAX), i32::MAX - 65_535);
1003 assert_eq!(i32::from_sample(i16::MID), i32::MID);
1004 assert_eq!(i32::from_sample(i16::MIN), i32::MIN);
1005
1006 assert_eq!(i32::from_sample(i24::MAX), i32::MAX - 255);
1007 assert_eq!(i32::from_sample(i24::MID), i32::MID);
1008 assert_eq!(i32::from_sample(i24::MIN), i32::MIN);
1009
1010 assert_eq!(i32::from_sample(i32::MAX), i32::MAX);
1011 assert_eq!(i32::from_sample(i32::MID), i32::MID);
1012 assert_eq!(i32::from_sample(i32::MIN), i32::MIN);
1013
1014 assert_eq!(i32::from_sample(1.0f32), i32::MAX);
1015 assert_eq!(i32::from_sample(0f32), i32::MID);
1016 assert_eq!(i32::from_sample(-1.0f32), i32::MIN);
1017
1018 assert_eq!(i32::from_sample(1.0f64), i32::MAX);
1019 assert_eq!(i32::from_sample(0f64), i32::MID);
1020 assert_eq!(i32::from_sample(-1.0f64), i32::MIN);
1021 }
1022
1023 #[test]
1024 fn verify_f64_from_sample() {
1025 assert_eq!(f64::from_sample(u8::MAX), 127.0 / 128.0);
1026 assert_eq!(f64::from_sample(u8::MID), 0.0);
1027 assert_eq!(f64::from_sample(u8::MIN), -1.0);
1028
1029 assert_eq!(f64::from_sample(u16::MAX), 32_767.0 / 32_768.0);
1030 assert_eq!(f64::from_sample(u16::MID), 0.0);
1031 assert_eq!(f64::from_sample(u16::MIN), -1.0);
1032
1033 assert_eq!(f64::from_sample(u24::MAX), 8_388_607.0 / 8_388_608.0);
1034 assert_eq!(f64::from_sample(u24::MID), 0.0);
1035 assert_eq!(f64::from_sample(u24::MIN), -1.0);
1036
1037 assert_eq!(f64::from_sample(u32::MAX), 2_147_483_647.0 / 2_147_483_648.0);
1038 assert_eq!(f64::from_sample(u32::MID), 0.0);
1039 assert_eq!(f64::from_sample(u32::MIN), -1.0);
1040
1041 assert_eq!(f64::from_sample(i8::MAX), 127.0 / 128.0);
1042 assert_eq!(f64::from_sample(i8::MID), 0.0);
1043 assert_eq!(f64::from_sample(i8::MIN), -1.0);
1044
1045 assert_eq!(f64::from_sample(i16::MAX), 32_767.0 / 32_768.0);
1046 assert_eq!(f64::from_sample(i16::MID), 0.0);
1047 assert_eq!(f64::from_sample(i16::MIN), -1.0);
1048
1049 assert_eq!(f64::from_sample(i24::MAX), 8_388_607.0 / 8_388_608.0);
1050 assert_eq!(f64::from_sample(i24::MID), 0.0);
1051 assert_eq!(f64::from_sample(i24::MIN), -1.0);
1052
1053 assert_eq!(f64::from_sample(i32::MAX), 2_147_483_647.0 / 2_147_483_648.0);
1054 assert_eq!(f64::from_sample(i32::MID), 0.0);
1055 assert_eq!(f64::from_sample(i32::MIN), -1.0);
1056
1057 assert_eq!(f64::from_sample(1.0f32), 1.0);
1058 assert_eq!(f64::from_sample(0f32), 0.0);
1059 assert_eq!(f64::from_sample(-1.0f32), -1.0);
1060
1061 assert_eq!(f64::from_sample(1.0f64), 1.0);
1062 assert_eq!(f64::from_sample(0f64), 0.0);
1063 assert_eq!(f64::from_sample(-1.0f64), -1.0);
1064 }
1065
1066 #[test]
1067 fn verify_f32_from_sample() {
1068 assert_eq!(f32::from_sample(u8::MAX), 127.0 / 128.0);
1069 assert_eq!(f32::from_sample(u8::MID), 0.0);
1070 assert_eq!(f32::from_sample(u8::MIN), -1.0);
1071
1072 assert_eq!(f32::from_sample(u16::MAX), 32_767.0 / 32_768.0);
1073 assert_eq!(f32::from_sample(u16::MID), 0.0);
1074 assert_eq!(f32::from_sample(u16::MIN), -1.0);
1075
1076 assert_eq!(f32::from_sample(u24::MAX), 8_388_607.0 / 8_388_608.0);
1077 assert_eq!(f32::from_sample(u24::MID), 0.0);
1078 assert_eq!(f32::from_sample(u24::MIN), -1.0);
1079
1080 assert_eq!(f32::from_sample(u32::MAX), 2_147_483_647.0 / 2_147_483_648.0);
1081 assert_eq!(f32::from_sample(u32::MID), 0.0);
1082 assert_eq!(f32::from_sample(u32::MIN), -1.0);
1083
1084 assert_eq!(f32::from_sample(i8::MAX), 127.0 / 128.0);
1085 assert_eq!(f32::from_sample(i8::MID), 0.0);
1086 assert_eq!(f32::from_sample(i8::MIN), -1.0);
1087
1088 assert_eq!(f32::from_sample(i16::MAX), 32_767.0 / 32_768.0);
1089 assert_eq!(f32::from_sample(i16::MID), 0.0);
1090 assert_eq!(f32::from_sample(i16::MIN), -1.0);
1091
1092 assert_eq!(f32::from_sample(i24::MAX), 8_388_607.0 / 8_388_608.0);
1093 assert_eq!(f32::from_sample(i24::MID), 0.0);
1094 assert_eq!(f32::from_sample(i24::MIN), -1.0);
1095
1096 assert_eq!(f32::from_sample(i32::MAX), 2_147_483_647.0 / 2_147_483_648.0);
1097 assert_eq!(f32::from_sample(i32::MID), 0.0);
1098 assert_eq!(f32::from_sample(i32::MIN), -1.0);
1099
1100 assert_eq!(f32::from_sample(1.0f32), 1.0);
1101 assert_eq!(f32::from_sample(0f32), 0.0);
1102 assert_eq!(f32::from_sample(-1.0f32), -1.0);
1103
1104 assert_eq!(f32::from_sample(1.0f64), 1.0);
1105 assert_eq!(f32::from_sample(0f64), 0.0);
1106 assert_eq!(f32::from_sample(-1.0f64), -1.0);
1107 }
1108}