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