1use super::SoundSource;
4use std::vec;
5
6#[cfg(test)]
7mod test {
8 use crate::SoundSource;
9
10 use super::{ChannelConverter, SampleRateConverter};
11
12 struct BufferSource {
13 sample_rate: u32,
14 channels: u16,
15 buffer: Vec<i16>,
16 i: usize,
17 }
18 impl SoundSource for BufferSource {
19 fn channels(&self) -> u16 {
20 self.channels
21 }
22
23 fn sample_rate(&self) -> u32 {
24 self.sample_rate
25 }
26
27 fn reset(&mut self) {
28 self.i = 0;
29 }
30
31 fn write_samples(&mut self, buffer: &mut [i16]) -> usize {
32 let i = self.i;
33 let len = (self.buffer.len() - i).min(buffer.len());
34 buffer[0..len].copy_from_slice(&self.buffer[i..i + len]);
35 self.i += len;
36 len
37 }
38 }
39
40 #[test]
41 fn sample_rate_1_3() {
42 let inner = BufferSource {
43 sample_rate: 10,
44 channels: 1,
45 buffer: vec![0, 3, 6, 9, 12],
46 i: 0,
47 };
48 let mut outer = SampleRateConverter::new(inner, 30);
49
50 let mut output = [0; 3];
51 let len = outer.write_samples(&mut output[..]);
52
53 assert_eq!(len, output.len());
54 assert_eq!(output, [0, 1, 2]);
55
56 let mut output = [0; 4];
57
58 let len = outer.write_samples(&mut output[..]);
59 assert_eq!(len, output.len());
60 assert_eq!(output, [3, 4, 5, 6]);
61
62 let len = outer.write_samples(&mut output[..]);
63 assert_eq!(len, output.len());
64 assert_eq!(output, [7, 8, 9, 10]);
65
66 let len = outer.write_samples(&mut output[..]);
67 assert_eq!(len, 2);
68 assert_eq!(output[..len], [11, 12]);
69
70 let len = outer.write_samples(&mut output[..]);
71 assert_eq!(len, 0);
72 }
73
74 #[test]
75 fn sample_rate_2_3() {
76 let inner = BufferSource {
77 sample_rate: 20,
78 channels: 1,
79 buffer: vec![0, 3, 6, 9, 12, 15],
80 i: 0,
81 };
82 let mut outer = SampleRateConverter::new(inner, 30);
83
84 let mut output = [0; 3];
85 let len = outer.write_samples(&mut output[..]);
86
87 assert_eq!(len, output.len());
88 assert_eq!(output, [0, 2, 4]);
89
90 let mut output = [0; 4];
91
92 let len = outer.write_samples(&mut output[..]);
93 assert_eq!(len, output.len());
94 assert_eq!(output, [6, 8, 10, 12]);
95
96 let len = outer.write_samples(&mut output[..]);
97 assert_eq!(len, 1);
98 assert_eq!(output[..len], [14]);
99
100 let len = outer.write_samples(&mut output[..]);
101 assert_eq!(len, 0);
102 }
103
104 #[test]
105 fn sample_rate_3_2() {
106 let inner = BufferSource {
107 sample_rate: 30,
108 channels: 1,
109 buffer: vec![0, 2, 4, 6, 8, 10, 12, 14, 16, 18],
110 i: 0,
111 };
112 let mut outer = SampleRateConverter::new(inner, 20);
113
114 let mut output = [0; 2];
115 let len = outer.write_samples(&mut output[..]);
116
117 assert_eq!(len, output.len());
118 assert_eq!(output, [0, 3]);
119
120 let mut output = [0; 4];
121
122 let len = outer.write_samples(&mut output[..]);
123 assert_eq!(len, output.len());
124 assert_eq!(output, [6, 9, 12, 15]);
125
126 let len = outer.write_samples(&mut output[..]);
127 assert_eq!(len, 1);
128 assert_eq!(output[..len], [18]);
129
130 let len = outer.write_samples(&mut output[..]);
131 assert_eq!(len, 0);
132 }
133
134 #[test]
135 fn channels_1_3() {
136 let inner = BufferSource {
137 sample_rate: 30,
138 channels: 1,
139 buffer: vec![-2, -1, 0, 1, 2],
140 i: 0,
141 };
142
143 let out_channels = 3;
144
145 let mut output = vec![0; 3 * 5];
146 let mut outer = ChannelConverter::new(inner, out_channels);
147
148 outer.write_samples(&mut output);
149
150 assert_eq!(output, [-2, -2, -2, -1, -1, -1, 0, 0, 0, 1, 1, 1, 2, 2, 2]);
151 }
152
153 #[test]
154 fn channels_3_1() {
155 let inner = BufferSource {
156 sample_rate: 30,
157 channels: 3,
158 buffer: vec![1, 2, 3, 4, 5, 6, 7, 8, 9],
159 i: 0,
160 };
161
162 let mut output = vec![0; 3];
163 let mut outer = ChannelConverter::new(inner, 1);
164
165 outer.write_samples(&mut output);
166
167 assert_eq!(output, [2, 5, 8]);
168 }
169
170 #[test]
171 fn channels_2_2() {
172 let inner = BufferSource {
173 sample_rate: 30,
174 channels: 2,
175 buffer: vec![1, 2, 3, 4, 5, 6, 7, 8, 9],
176 i: 0,
177 };
178
179 let input = inner.buffer.clone();
180 let mut output = vec![0; inner.buffer.len()];
181 let mut outer = ChannelConverter::new(inner, 2);
182 outer.write_samples(&mut output);
183 assert_eq!(output, input);
184 }
185
186 #[test]
187 fn channels_4_5() {
188 let inner = BufferSource {
189 sample_rate: 30,
190 channels: 4,
191 buffer: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
192 i: 0,
193 };
194 let mut output = vec![0; inner.buffer.len() / 4 * 5];
195 let mut outer = ChannelConverter::new(inner, 5);
196 outer.write_samples(&mut output);
197 assert_eq!(output, &[2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10,]);
198 }
199
200 #[test]
201 fn channels_5_3() {
202 let inner = BufferSource {
203 sample_rate: 30,
204 channels: 5,
205 buffer: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
206 i: 0,
207 };
208 let mut output = vec![0; inner.buffer.len() / 5 * 3];
209 let mut outer = ChannelConverter::new(inner, 3);
210 outer.write_samples(&mut output);
211 assert_eq!(output, &[3, 3, 3, 8, 8, 8, 13, 13, 13]);
212
213 let inner = BufferSource {
214 sample_rate: 30,
215 channels: 5,
216 buffer: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
217 i: 0,
218 };
219 let mut output = vec![0; 3];
220 let mut outer = ChannelConverter::new(inner, 3);
221 let len = outer.write_samples(&mut output);
222 assert_eq!(output, &[3, 3, 3]);
223 assert_eq!(len, 3);
224 let len = outer.write_samples(&mut output);
225 assert_eq!(output, &[8, 8, 8]);
226 assert_eq!(len, 3);
227 let len = outer.write_samples(&mut output);
228 assert_eq!(output, &[13, 13, 13]);
229 assert_eq!(len, 3);
230 let len = outer.write_samples(&mut output);
231 assert_eq!(&output[..len], &[]);
232 assert_eq!(len, 0);
233 }
234}
235
236pub struct ChannelConverter<T: SoundSource> {
242 inner: T,
243 channels: u16,
245 in_buffer: Vec<i16>,
247}
248impl<T: SoundSource> ChannelConverter<T> {
249 pub fn new(inner: T, channels: u16) -> Self {
254 Self {
255 inner,
256 channels,
257 in_buffer: Vec::new(),
258 }
259 }
260}
261impl<T: SoundSource> SoundSource for ChannelConverter<T> {
262 fn channels(&self) -> u16 {
263 self.channels
264 }
265 fn sample_rate(&self) -> u32 {
266 self.inner.sample_rate()
267 }
268 fn reset(&mut self) {
269 self.inner.reset()
270 }
271 fn write_samples(&mut self, out_buffer: &mut [i16]) -> usize {
272 let out_channels = self.channels as usize;
273 let in_channels = self.inner.channels() as usize;
274
275 use std::cmp::Ordering;
276 match in_channels.cmp(&out_channels) {
277 Ordering::Equal => self.inner.write_samples(out_buffer),
278 Ordering::Less => {
279 let in_len = out_buffer.len() / out_channels * in_channels;
282 let in_len = self.inner.write_samples(&mut out_buffer[0..in_len]);
283
284 let mut sum: i32 = 0;
285 for i in (0..in_len).rev() {
286 sum += out_buffer[i] as i32;
287 if i % in_channels == 0 {
288 let frame_index = i / in_channels * out_channels;
289 let mean = (sum / in_channels as i32) as i16;
290 for c in 0..out_channels {
291 out_buffer[frame_index + c] = mean;
292 }
293 sum = 0;
294 }
295 }
296 in_len * out_channels / in_channels
297 }
298 Ordering::Greater => {
299 let in_buffer = {
302 let len = out_buffer.len() / out_channels * in_channels;
303 if len > self.in_buffer.len() {
304 self.in_buffer.resize(len, 0);
305 }
306 &mut self.in_buffer[0..len]
307 };
308 let in_len = self.inner.write_samples(in_buffer);
309
310 let mut sum: i32 = 0;
311 for (i, &in_sample) in in_buffer[0..in_len].iter().enumerate() {
312 sum += in_sample as i32;
313 if (i + 1) % in_channels == 0 {
314 let frame_index = i / in_channels * out_channels;
315 let mean = (sum / in_channels as i32) as i16;
316 for c in 0..out_channels {
317 out_buffer[frame_index + c] = mean;
318 }
319 sum = 0;
320 }
321 }
322 in_len * out_channels / in_channels
323 }
324 }
325 }
326}
327
328pub struct SampleRateConverter<T: SoundSource> {
330 inner: T,
331 output_sample_rate: u32,
333 in_buffer: Box<[i16]>,
336 out_len: usize,
337 len: usize,
339 iter: usize,
342}
343impl<T: SoundSource> SampleRateConverter<T> {
344 pub fn new(inner: T, output_sample_rate: u32) -> Self {
348 use gcd::Gcd;
349
350 let gcd = inner.sample_rate().gcd(output_sample_rate) as usize;
353 let in_len = inner.sample_rate() as usize / gcd * inner.channels() as usize;
354 let out_len = output_sample_rate as usize / gcd * inner.channels() as usize;
355
356 let channels = inner.channels() as usize;
357
358 let in_buffer = vec![0; in_len + channels].into_boxed_slice();
360
361 let mut this = Self {
362 len: in_buffer.len() - 1,
363 in_buffer,
364 iter: out_len,
365 out_len,
366 inner,
367 output_sample_rate,
368 };
369
370 this.reset();
371
372 this
373 }
374}
375impl<T: SoundSource> SoundSource for SampleRateConverter<T> {
376 fn channels(&self) -> u16 {
377 self.inner.channels()
378 }
379 fn sample_rate(&self) -> u32 {
380 self.output_sample_rate
381 }
382 fn reset(&mut self) {
383 self.inner.reset();
384
385 let channels = self.inner.channels() as usize;
386 self.len = self.inner.write_samples(&mut self.in_buffer[..]) - channels;
387 self.iter = 0;
388 }
389 fn write_samples(&mut self, buffer: &mut [i16]) -> usize {
390 let channels = self.inner.channels() as usize;
391
392 if self.output_sample_rate == self.inner.sample_rate() {
393 return self.inner.write_samples(buffer);
394 }
395
396 let mut i = 0;
397 while i < buffer.len() {
398 let in_len = self.in_buffer.len() - channels;
399 fn div_up(a: usize, b: usize) -> usize {
400 a / b + (a % b != 0) as usize
401 }
402 let curr_out_len = div_up(self.out_len * self.len, in_len) / channels * channels;
403
404 if self.iter >= curr_out_len {
406 if self.len < in_len {
408 return i;
409 }
410
411 self.in_buffer.copy_within(self.len.., 0);
413
414 self.len = self.inner.write_samples(&mut self.in_buffer[channels..]);
415 self.iter = 0;
416 }
417
418 let j = ((self.iter / channels) * in_len) as f32 / self.out_len as f32;
420
421 let t = j.fract();
422 let j = j as usize * channels;
423
424 for c in 0..channels {
425 buffer[i + c] = (self.in_buffer[j + c] as f32 * (1.0 - t)
427 + self.in_buffer[j + c + channels] as f32 * t)
428 as i16;
429 }
430
431 self.iter += channels;
432 i += channels;
433 }
434
435 buffer.len()
436 }
437}