geng_rodio/conversions/
sample.rs1use cpal::{FromSample, Sample as CpalSample};
2use std::marker::PhantomData;
3
4#[derive(Clone, Debug)]
6pub struct DataConverter<I, O> {
7 input: I,
8 marker: PhantomData<O>,
9}
10
11impl<I, O> DataConverter<I, O> {
12 #[inline]
14 pub fn new(input: I) -> DataConverter<I, O> {
15 DataConverter {
16 input,
17 marker: PhantomData,
18 }
19 }
20
21 #[inline]
23 pub fn into_inner(self) -> I {
24 self.input
25 }
26}
27
28impl<I, O> Iterator for DataConverter<I, O>
29where
30 I: Iterator,
31 I::Item: Sample,
32 O: FromSample<I::Item> + Sample,
33{
34 type Item = O;
35
36 #[inline]
37 fn next(&mut self) -> Option<O> {
38 self.input.next().map(|s| CpalSample::from_sample(s))
39 }
40
41 #[inline]
42 fn size_hint(&self) -> (usize, Option<usize>) {
43 self.input.size_hint()
44 }
45}
46
47impl<I, O> ExactSizeIterator for DataConverter<I, O>
48where
49 I: ExactSizeIterator,
50 I::Item: Sample,
51 O: FromSample<I::Item> + Sample,
52{
53}
54
55pub trait Sample: CpalSample {
69 fn lerp(first: Self, second: Self, numerator: u32, denominator: u32) -> Self;
74 fn amplify(self, value: f32) -> Self;
76
77 fn saturating_add(self, other: Self) -> Self;
79
80 fn zero_value() -> Self;
82}
83
84impl Sample for u16 {
85 #[inline]
86 fn lerp(first: u16, second: u16, numerator: u32, denominator: u32) -> u16 {
87 let a = first as i32;
88 let b = second as i32;
89 let n = numerator as i32;
90 let d = denominator as i32;
91 (a + (b - a) * n / d) as u16
92 }
93
94 #[inline]
95 fn amplify(self, value: f32) -> u16 {
96 ((self as f32) * value) as u16
97 }
98
99 #[inline]
100 fn saturating_add(self, other: u16) -> u16 {
101 self.saturating_add(other)
102 }
103
104 #[inline]
105 fn zero_value() -> u16 {
106 32768
107 }
108}
109
110impl Sample for i16 {
111 #[inline]
112 fn lerp(first: i16, second: i16, numerator: u32, denominator: u32) -> i16 {
113 (first as i32 + (second as i32 - first as i32) * numerator as i32 / denominator as i32)
114 as i16
115 }
116
117 #[inline]
118 fn amplify(self, value: f32) -> i16 {
119 ((self as f32) * value) as i16
120 }
121
122 #[inline]
123 fn saturating_add(self, other: i16) -> i16 {
124 self.saturating_add(other)
125 }
126
127 #[inline]
128 fn zero_value() -> i16 {
129 0
130 }
131}
132
133impl Sample for f32 {
134 #[inline]
135 fn lerp(first: f32, second: f32, numerator: u32, denominator: u32) -> f32 {
136 first + (second - first) * numerator as f32 / denominator as f32
137 }
138
139 #[inline]
140 fn amplify(self, value: f32) -> f32 {
141 self * value
142 }
143
144 #[inline]
145 fn saturating_add(self, other: f32) -> f32 {
146 self + other
147 }
148
149 #[inline]
150 fn zero_value() -> f32 {
151 0.0
152 }
153}