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 #[inline]
29 pub fn inner_mut(&mut self) -> &mut I {
30 &mut self.input
31 }
32}
33
34impl<I, O> Iterator for DataConverter<I, O>
35where
36 I: Iterator,
37 I::Item: Sample,
38 O: FromSample<I::Item> + Sample,
39{
40 type Item = O;
41
42 #[inline]
43 fn next(&mut self) -> Option<O> {
44 self.input.next().map(|s| CpalSample::from_sample(s))
45 }
46
47 #[inline]
48 fn size_hint(&self) -> (usize, Option<usize>) {
49 self.input.size_hint()
50 }
51}
52
53impl<I, O> ExactSizeIterator for DataConverter<I, O>
54where
55 I: ExactSizeIterator,
56 I::Item: Sample,
57 O: FromSample<I::Item> + Sample,
58{
59}
60
61pub trait Sample: CpalSample {
75 fn lerp(first: Self, second: Self, numerator: u32, denominator: u32) -> Self;
80 fn amplify(self, value: f32) -> Self;
82
83 fn to_f32(self) -> f32;
85
86 fn saturating_add(self, other: Self) -> Self;
88
89 fn zero_value() -> Self;
91}
92
93impl Sample for u16 {
94 #[inline]
95 fn lerp(first: u16, second: u16, numerator: u32, denominator: u32) -> u16 {
96 let a = first as i32;
97 let b = second as i32;
98 let n = numerator as i32;
99 let d = denominator as i32;
100 (a + (b - a) * n / d) as u16
101 }
102
103 #[inline]
104 fn amplify(self, value: f32) -> u16 {
105 ((self as f32) * value) as u16
106 }
107
108 #[inline]
109 fn to_f32(self) -> f32 {
110 (self as f32 - 32768.0) / 32768.0
112 }
113
114 #[inline]
115 fn saturating_add(self, other: u16) -> u16 {
116 self.saturating_add(other)
117 }
118
119 #[inline]
120 fn zero_value() -> u16 {
121 32768
122 }
123}
124
125impl Sample for i16 {
126 #[inline]
127 fn lerp(first: i16, second: i16, numerator: u32, denominator: u32) -> i16 {
128 (first as i32 + (second as i32 - first as i32) * numerator as i32 / denominator as i32)
129 as i16
130 }
131
132 #[inline]
133 fn amplify(self, value: f32) -> i16 {
134 ((self as f32) * value) as i16
135 }
136
137 #[inline]
138 fn to_f32(self) -> f32 {
139 self as f32 / 32768.0
141 }
142
143 #[inline]
144 fn saturating_add(self, other: i16) -> i16 {
145 self.saturating_add(other)
146 }
147
148 #[inline]
149 fn zero_value() -> i16 {
150 0
151 }
152}
153
154impl Sample for f32 {
155 #[inline]
156 fn lerp(first: f32, second: f32, numerator: u32, denominator: u32) -> f32 {
157 first + (second - first) * numerator as f32 / denominator as f32
158 }
159
160 #[inline]
161 fn amplify(self, value: f32) -> f32 {
162 self * value
163 }
164
165 #[inline]
166 fn to_f32(self) -> f32 {
167 self
169 }
170
171 #[inline]
172 fn saturating_add(self, other: f32) -> f32 {
173 self + other
174 }
175
176 #[inline]
177 fn zero_value() -> f32 {
178 0.0
179 }
180}