1pub mod sinc {
2 use crate::audio::buffer::PooledBuffer;
3 use std::collections::VecDeque;
4 pub struct SincResampler {
5 ratio: f32,
6 index: f32,
7 channels: usize,
8 taps: usize,
9 table: Vec<f32>,
10 buffer: Vec<VecDeque<f32>>,
11 }
12 impl SincResampler {
13 pub fn new(source_rate: u32, target_rate: u32, channels: usize) -> Self {
14 let taps = 32;
15 let mut table = Vec::with_capacity(taps);
16 let m = taps as f32 - 1.0;
17 let half_taps = (taps / 2) as f32;
18 for i in 0..taps {
19 let offset = i as f32 - half_taps;
20 let a0 = 0.42;
21 let a1 = 0.5;
22 let a2 = 0.08;
23 let pi_n_m = 2.0 * std::f32::consts::PI * i as f32 / m;
24 let window = a0 - a1 * pi_n_m.cos() + a2 * (2.0 * pi_n_m).cos();
25 table.push(Self::sinc(offset) * window);
26 }
27 Self {
28 ratio: source_rate as f32 / target_rate as f32,
29 index: 0.0,
30 channels,
31 taps,
32 table,
33 buffer: vec![VecDeque::from(vec![0.0; taps]); channels],
34 }
35 }
36 fn sinc(x: f32) -> f32 {
37 if x.abs() < 1e-6 {
38 return 1.0;
39 }
40 let pi_x = std::f32::consts::PI * x;
41 pi_x.sin() / pi_x
42 }
43 pub fn process(&mut self, input: &[i16], output: &mut PooledBuffer) {
44 let num_frames = input.len() / self.channels;
45 for frame in 0..num_frames {
46 for ch in 0..self.channels {
47 self.buffer[ch].pop_front();
48 self.buffer[ch].push_back(input[frame * self.channels + ch] as f32);
49 }
50 while self.index < 1.0 {
51 for ch in 0..self.channels {
52 let mut sum = 0.0;
53 for i in 0..self.taps {
54 sum += self.buffer[ch][i] * self.table[i];
55 }
56 output.push(sum.clamp(i16::MIN as f32, i16::MAX as f32) as i16);
57 }
58 self.index += self.ratio;
59 }
60 self.index -= 1.0;
61 }
62 }
63 pub fn reset(&mut self) {
64 self.index = 0.0;
65 for ch in &mut self.buffer {
66 for x in ch {
67 *x = 0.0;
68 }
69 }
70 }
71 pub fn is_passthrough(&self) -> bool {
72 (self.ratio - 1.0).abs() < f32::EPSILON
73 }
74 }
75 #[cfg(test)]
76 mod tests {
77 use super::*;
78 #[test]
79 fn test_sinc_function() {
80 assert!((SincResampler::sinc(0.0) - 1.0).abs() < 1e-6);
81 assert!((SincResampler::sinc(1e-7) - 1.0).abs() < 1e-6);
82 let val = SincResampler::sinc(1.0);
83 assert!(val.abs() < 0.01);
84 assert!((SincResampler::sinc(2.0) - SincResampler::sinc(-2.0)).abs() < 1e-6);
85 }
86 #[test]
87 fn test_resampler_new_same_rate() {
88 let resampler = SincResampler::new(48000, 48000, 2);
89 assert!(resampler.is_passthrough());
90 assert_eq!(resampler.channels, 2);
91 assert_eq!(resampler.taps, 32);
92 assert_eq!(resampler.table.len(), 32);
93 assert_eq!(resampler.buffer.len(), 2);
94 }
95 #[test]
96 fn test_resampler_new_downsample() {
97 let resampler = SincResampler::new(48000, 44100, 2);
98 assert!(!resampler.is_passthrough());
99 assert!(resampler.ratio > 1.0);
100 assert_eq!(resampler.channels, 2);
101 }
102 #[test]
103 fn test_resampler_new_upsample() {
104 let resampler = SincResampler::new(44100, 48000, 2);
105 assert!(!resampler.is_passthrough());
106 assert!(resampler.ratio < 1.0);
107 }
108 #[test]
109 fn test_resampler_reset() {
110 let mut resampler = SincResampler::new(48000, 44100, 2);
111 resampler.index = 0.5;
112 for ch in &mut resampler.buffer {
113 for x in ch.iter_mut() {
114 *x = 100.0;
115 }
116 }
117 resampler.reset();
118 assert_eq!(resampler.index, 0.0);
119 for ch in &resampler.buffer {
120 for &x in ch.iter() {
121 assert_eq!(x, 0.0);
122 }
123 }
124 }
125 #[test]
126 fn test_resampler_process_empty() {
127 let mut resampler = SincResampler::new(48000, 48000, 2);
128 let input: Vec<i16> = vec![];
129 let mut output = Vec::new();
130 resampler.process(&input, &mut output);
131 assert!(output.is_empty());
132 }
133 #[test]
134 fn test_resampler_process_silence() {
135 let mut resampler = SincResampler::new(48000, 48000, 2);
136 let input = vec![0i16; 20];
137 let mut output = Vec::new();
138 resampler.process(&input, &mut output);
139 assert!(!output.is_empty());
140 for &sample in &output {
141 assert_eq!(sample, 0);
142 }
143 }
144 #[test]
145 fn test_resampler_process_mono() {
146 let mut resampler = SincResampler::new(48000, 48000, 1);
147 let input = vec![1000i16; 10];
148 let mut output = Vec::new();
149 resampler.process(&input, &mut output);
150 assert!(!output.is_empty());
151 }
152 #[test]
153 fn test_resampler_process_clamp() {
154 let mut resampler = SincResampler::new(48000, 48000, 1);
155 let input = vec![i16::MAX; 100];
156 let mut output = Vec::new();
157 resampler.process(&input, &mut output);
158 for &sample in &output {
159 assert!(sample >= i16::MIN && sample <= i16::MAX);
160 }
161 }
162 #[test]
163 fn test_is_passthrough_exact() {
164 let resampler = SincResampler::new(48000, 48000, 2);
165 assert!(resampler.is_passthrough());
166 }
167 #[test]
168 fn test_is_not_passthrough() {
169 let resampler = SincResampler::new(48000, 44100, 2);
170 assert!(!resampler.is_passthrough());
171 }
172 #[test]
173 fn test_resampler_table_generation() {
174 let resampler = SincResampler::new(48000, 44100, 2);
175 assert_eq!(resampler.table.len(), 32);
176 for &val in &resampler.table {
177 assert!(val.is_finite());
178 }
179 }
180 #[test]
181 fn test_resampler_multiple_channels() {
182 for channels in 1..=8 {
183 let resampler = SincResampler::new(48000, 44100, channels);
184 assert_eq!(resampler.buffer.len(), channels);
185 for ch_buffer in &resampler.buffer {
186 assert_eq!(ch_buffer.len(), 32);
187 }
188 }
189 }
190 }
191}
192pub mod linear {
193 use crate::audio::buffer::PooledBuffer;
194 pub struct LinearResampler {
195 ratio: f32,
196 index: f32,
197 last_samples: Vec<i16>,
198 channels: usize,
199 }
200 impl LinearResampler {
201 pub fn new(source_rate: u32, target_rate: u32, channels: usize) -> Self {
202 Self {
203 ratio: source_rate as f32 / target_rate as f32,
204 index: 0.0,
205 last_samples: vec![0; channels],
206 channels,
207 }
208 }
209 pub fn process(&mut self, input: &[i16], output: &mut PooledBuffer) {
210 let num_frames = input.len() / self.channels;
211 while self.index < num_frames as f32 {
212 let idx = self.index as usize;
213 let fract = self.index.fract();
214 for c in 0..self.channels {
215 let s1 = if idx == 0 {
216 self.last_samples[c]
217 } else {
218 input[(idx - 1) * self.channels + c]
219 } as f32;
220 let s2 = if idx < num_frames {
221 input[idx * self.channels + c]
222 } else {
223 input[(num_frames - 1) * self.channels + c]
224 } as f32;
225 output.push((s1 * (1.0 - fract) + s2 * fract) as i16);
226 }
227 self.index += self.ratio;
228 }
229 self.index -= num_frames as f32;
230 if num_frames > 0 {
231 for c in 0..self.channels {
232 self.last_samples[c] = input[(num_frames - 1) * self.channels + c];
233 }
234 }
235 }
236 pub fn reset(&mut self) {
237 self.index = 0.0;
238 self.last_samples.fill(0);
239 }
240 pub fn is_passthrough(&self) -> bool {
241 (self.ratio - 1.0).abs() < f32::EPSILON
242 }
243 }
244}
245pub mod hermite {
246 use crate::audio::buffer::PooledBuffer;
247 pub struct HermiteResampler {
248 ratio: f32,
249 index: f32,
250 channels: usize,
251 last_samples: Vec<i16>,
252 }
253 impl HermiteResampler {
254 pub fn new(source_rate: u32, target_rate: u32, channels: usize) -> Self {
255 Self {
256 ratio: source_rate as f32 / target_rate as f32,
257 index: 0.0,
258 channels,
259 last_samples: vec![0; channels],
260 }
261 }
262 #[inline]
263 fn hermite(p: [f32; 4], t: f32) -> f32 {
264 let c0 = p[1];
265 let c1 = 0.5 * (p[2] - p[0]);
266 let c2 = p[0] - 2.5 * p[1] + 2.0 * p[2] - 0.5 * p[3];
267 let c3 = 0.5 * (p[3] - p[0]) + 1.5 * (p[1] - p[2]);
268 ((c3 * t + c2) * t + c1) * t + c0
269 }
270 pub fn process(&mut self, input: &[i16], output: &mut PooledBuffer) {
271 let num_frames = input.len() / self.channels;
272 let num_frames_f = num_frames as f32;
273 while self.index < num_frames_f {
274 let idx = self.index as usize;
275 let t = self.index.fract();
276 for ch in 0..self.channels {
277 let base_idx = idx * self.channels + ch;
278 let p0 = if idx == 0 {
279 self.last_samples[ch]
280 } else {
281 input[base_idx - self.channels]
282 } as f32;
283 let p1 = input[base_idx] as f32;
284 let p2 = if idx + 1 < num_frames {
285 input[base_idx + self.channels]
286 } else {
287 input[(num_frames - 1) * self.channels + ch]
288 } as f32;
289 let p3 = if idx + 2 < num_frames {
290 input[base_idx + 2 * self.channels]
291 } else {
292 input[(num_frames - 1) * self.channels + ch]
293 } as f32;
294 let s = Self::hermite([p0, p1, p2, p3], t)
295 .clamp(i16::MIN as f32, i16::MAX as f32) as i16;
296 output.push(s);
297 }
298 self.index += self.ratio;
299 }
300 self.index -= num_frames as f32;
301 if num_frames > 0 {
302 for ch in 0..self.channels {
303 self.last_samples[ch] = input[(num_frames - 1) * self.channels + ch];
304 }
305 }
306 }
307 pub fn reset(&mut self) {
308 self.index = 0.0;
309 self.last_samples.fill(0);
310 }
311 pub fn is_passthrough(&self) -> bool {
312 (self.ratio - 1.0).abs() < f32::EPSILON
313 }
314 }
315}
316use crate::audio::buffer::PooledBuffer;
317pub use hermite::HermiteResampler;
318pub use linear::LinearResampler;
319pub use sinc::SincResampler;
320pub enum Resampler {
321 Linear(LinearResampler),
322 Hermite(HermiteResampler),
323 Sinc(SincResampler),
324}
325impl Resampler {
326 pub fn hermite(source_rate: u32, target_rate: u32, channels: usize) -> Self {
327 Self::Hermite(HermiteResampler::new(source_rate, target_rate, channels))
328 }
329 pub fn linear(source_rate: u32, target_rate: u32, channels: usize) -> Self {
330 Self::Linear(LinearResampler::new(source_rate, target_rate, channels))
331 }
332 pub fn sinc(source_rate: u32, target_rate: u32, channels: usize) -> Self {
333 Self::Sinc(SincResampler::new(source_rate, target_rate, channels))
334 }
335 pub fn is_passthrough(&self) -> bool {
336 match self {
337 Self::Linear(r) => r.is_passthrough(),
338 Self::Hermite(r) => r.is_passthrough(),
339 Self::Sinc(r) => r.is_passthrough(),
340 }
341 }
342 pub fn process(&mut self, input: &[i16], output: &mut PooledBuffer) {
343 match self {
344 Self::Linear(r) => r.process(input, output),
345 Self::Hermite(r) => r.process(input, output),
346 Self::Sinc(r) => r.process(input, output),
347 }
348 }
349 pub fn reset(&mut self) {
350 match self {
351 Self::Linear(r) => r.reset(),
352 Self::Hermite(r) => r.reset(),
353 Self::Sinc(r) => r.reset(),
354 }
355 }
356}