1#![allow(unused_imports)]
7
8#[cfg(feature = "std")]
9use std::{vec::Vec, marker::PhantomData};
10
11#[cfg(not(feature = "std"))]
12use core::marker::PhantomData;
13
14#[cfg(all(not(feature = "std"), feature = "alloc"))]
15use alloc::vec::Vec;
16
17use num_traits::Float;
18
19pub struct Buffer<T: Float> {
36 buffer_index: usize,
37 buffer_mask: usize,
38 buffer: Vec<T>,
39}
40
41impl<T: Float> Buffer<T> {
42 pub fn new(min_capacity: usize) -> Self {
44 let mut result = Self {
45 buffer_index: 0,
46 buffer_mask: 0,
47 buffer: Vec::new(),
48 };
49 result.resize(min_capacity, T::zero());
50 result
51 }
52
53 pub fn resize(&mut self, min_capacity: usize, value: T) {
55 let mut buffer_length = 1;
56 while buffer_length < min_capacity {
57 buffer_length *= 2;
58 }
59 self.buffer = vec![value; buffer_length];
60 self.buffer_mask = buffer_length - 1;
61 self.buffer_index = 0;
62 }
63
64 pub fn reset(&mut self, value: T) {
66 for i in 0..self.buffer.len() {
67 self.buffer[i] = value;
68 }
69 }
70
71 pub fn get(&self, offset: isize) -> T {
73 let index = (self.buffer_index as isize + offset) as usize & self.buffer_mask;
74 self.buffer[index]
75 }
76
77 pub fn set(&mut self, offset: isize, value: T) {
79 let index = (self.buffer_index as isize + offset) as usize & self.buffer_mask;
80 self.buffer[index] = value;
81 }
82
83 pub fn advance(&mut self, amount: isize) -> &mut Self {
85 if amount >= 0 {
86 self.buffer_index = self.buffer_index.wrapping_add(amount as usize);
87 } else {
88 self.buffer_index = self.buffer_index.wrapping_sub((-amount) as usize);
89 }
90 self
91 }
92
93 pub fn write<D>(&mut self, data: &[D], length: usize)
95 where
96 D: Copy + Into<T>,
97 {
98 for i in 0..length {
99 self.set(i as isize, data[i].into());
100 }
101 }
102
103 pub fn read<D>(&self, length: usize, data: &mut [D])
105 where
106 T: Into<D>,
107 D: Copy,
108 {
109 for i in 0..length {
110 data[i] = self.get(i as isize).into();
111 }
112 }
113
114 pub fn view(&self) -> View<T> {
116 View {
117 buffer: self,
118 offset: 0,
119 }
120 }
121
122 pub fn view_at(&self, offset: isize) -> View<T> {
124 View {
125 buffer: self,
126 offset,
127 }
128 }
129}
130
131pub struct View<'a, T: Float> {
133 buffer: &'a Buffer<T>,
134 offset: isize,
135}
136
137impl<'a, T: Float> View<'a, T> {
138 pub fn get(&self, offset: isize) -> T {
140 self.buffer.get(self.offset + offset)
141 }
142
143 pub fn offset(&self, offset: isize) -> View<'a, T> {
145 View {
146 buffer: self.buffer,
147 offset: self.offset + offset,
148 }
149 }
150}
151
152pub struct MultiBuffer<T: Float> {
159 channels: usize,
160 stride: usize,
161 buffer: Buffer<T>,
162}
163
164impl<T: Float> MultiBuffer<T> {
165 pub fn new(channels: usize, capacity: usize) -> Self {
167 Self {
168 channels,
169 stride: capacity,
170 buffer: Buffer::new(channels * capacity),
171 }
172 }
173
174 pub fn resize(&mut self, channels: usize, capacity: usize, value: T) {
176 self.channels = channels;
177 self.stride = capacity;
178 self.buffer.resize(channels * capacity, value);
179 }
180
181 pub fn reset(&mut self, value: T) {
183 self.buffer.reset(value);
184 }
185
186 pub fn advance(&mut self, amount: isize) -> &mut Self {
188 self.buffer.advance(amount);
189 self
190 }
191
192 pub fn channel(&self, channel: usize) -> View<T> {
194 self.buffer.view_at((channel * self.stride) as isize)
195 }
196
197 pub fn get(&self, channel: usize, offset: isize) -> T {
199 self.buffer.get((channel * self.stride) as isize + offset)
200 }
201
202 pub fn set(&mut self, channel: usize, offset: isize, value: T) {
204 self.buffer.set((channel * self.stride) as isize + offset, value);
205 }
206}
207
208pub struct InterpolatorNearest<T: Float> {
210 _marker: PhantomData<T>,
211}
212
213impl<T: Float> InterpolatorNearest<T> {
214 pub fn new() -> Self {
216 Self { _marker: PhantomData }
217 }
218
219 pub const INPUT_LENGTH: usize = 1;
221
222 pub fn latency() -> T {
224 -T::from(0.5).unwrap()
225 }
226
227 pub fn fractional<D>(&self, data: &D, _fractional: T) -> T
229 where
230 D: core::ops::Index<usize, Output = T>,
231 {
232 data[0]
233 }
234}
235
236pub struct InterpolatorLinear<T: Float> {
238 _marker: PhantomData<T>,
239}
240
241impl<T: Float> InterpolatorLinear<T> {
242 pub fn new() -> Self {
244 Self { _marker: PhantomData }
245 }
246
247 pub const INPUT_LENGTH: usize = 2;
249
250 pub fn latency() -> T {
252 T::zero()
253 }
254
255 pub fn fractional<D>(&self, data: &D, fractional: T) -> T
257 where
258 D: core::ops::Index<usize, Output = T>,
259 {
260 let a = data[0];
261 let b = data[1];
262 a + fractional * (b - a)
263 }
264}
265
266pub struct InterpolatorCubic<T: Float> {
268 _marker: PhantomData<T>,
269}
270
271impl<T: Float> InterpolatorCubic<T> {
272 pub fn new() -> Self {
274 Self { _marker: PhantomData }
275 }
276
277 pub const INPUT_LENGTH: usize = 4;
279
280 pub fn latency() -> T {
282 T::one()
283 }
284
285 pub fn fractional<D>(&self, data: &D, fractional: T) -> T
287 where
288 D: core::ops::Index<usize, Output = T>,
289 {
290 let a = data[0];
291 let b = data[1];
292 let c = data[2];
293 let d = data[3];
294
295 let cb_diff = c - b;
296 let half = T::from(0.5).unwrap();
297 let k1 = (c - a) * half;
298 let two = T::one() + T::one();
299 let k3 = k1 + (d - b) * half - cb_diff * two;
300 let k2 = cb_diff - k3 - k1;
301
302 b + fractional * (k1 + fractional * (k2 + fractional * k3))
303 }
304}
305
306pub struct Reader<T: Float, I> {
308 interpolator: I,
309 _marker: PhantomData<T>,
310}
311
312impl<T: Float, I> Reader<T, I> {
313 pub fn new(interpolator: I) -> Self {
315 Self {
316 interpolator,
317 _marker: PhantomData,
318 }
319 }
320
321 pub fn read<B>(&self, buffer: &B, delay_samples: T) -> T
323 where
324 I: InterpolatorTrait<T>,
325 B: BufferTrait<T>,
326 {
327 let start_index = delay_samples.floor().to_usize().unwrap_or(0);
328 let remainder = delay_samples - T::from(start_index).unwrap();
329
330 struct Flipped<'a, T: Float, B: BufferTrait<T>> {
332 view: &'a B,
333 start_index: usize,
334 _marker: PhantomData<T>,
335 }
336
337 impl<'a, T: Float, B: BufferTrait<T>> core::ops::Index<usize> for Flipped<'a, T, B> {
338 type Output = T;
339
340 fn index(&self, index: usize) -> &Self::Output {
341 let offset = -(index as isize) - (self.start_index as isize);
343 self.view.get_ref(offset)
344 }
345 }
346
347 let flipped = Flipped {
348 view: buffer,
349 start_index,
350 _marker: PhantomData,
351 };
352
353 self.interpolator.fractional(&flipped, remainder)
354 }
355}
356
357pub trait BufferTrait<T: Float> {
359 fn get_ref(&self, offset: isize) -> &T;
361}
362
363impl<T: Float> BufferTrait<T> for Buffer<T> {
364 fn get_ref(&self, offset: isize) -> &T {
365 let index = (self.buffer_index as isize + offset) as usize & self.buffer_mask;
366 &self.buffer[index]
367 }
368}
369
370impl<'a, T: Float> BufferTrait<T> for View<'a, T> {
371 fn get_ref(&self, offset: isize) -> &T {
372 let index = (self.buffer.buffer_index as isize + self.offset + offset) as usize
373 & self.buffer.buffer_mask;
374 &self.buffer.buffer[index]
375 }
376}
377
378pub trait InterpolatorTrait<T: Float> {
380 fn fractional<D>(&self, data: &D, fractional: T) -> T
382 where
383 D: core::ops::Index<usize, Output = T>;
384}
385
386impl<T: Float> InterpolatorTrait<T> for InterpolatorNearest<T> {
387 fn fractional<D>(&self, data: &D, fractional: T) -> T
388 where
389 D: core::ops::Index<usize, Output = T>,
390 {
391 self.fractional(data, fractional)
392 }
393}
394
395impl<T: Float> InterpolatorTrait<T> for InterpolatorLinear<T> {
396 fn fractional<D>(&self, data: &D, fractional: T) -> T
397 where
398 D: core::ops::Index<usize, Output = T>,
399 {
400 self.fractional(data, fractional)
401 }
402}
403
404impl<T: Float> InterpolatorTrait<T> for InterpolatorCubic<T> {
405 fn fractional<D>(&self, data: &D, fractional: T) -> T
406 where
407 D: core::ops::Index<usize, Output = T>,
408 {
409 self.fractional(data, fractional)
410 }
411}
412
413pub struct Delay<T: Float, I> {
415 reader: Reader<T, I>,
416 buffer: Buffer<T>,
417}
418
419impl<T: Float, I: InterpolatorTrait<T>> Delay<T, I> {
420 pub fn new(interpolator: I, capacity: usize) -> Self {
422 Self {
423 reader: Reader::new(interpolator),
424 buffer: Buffer::new(capacity),
425 }
426 }
427
428 pub fn reset(&mut self, value: T) {
430 self.buffer.reset(value);
431 }
432
433 pub fn resize(&mut self, min_capacity: usize, value: T) {
435 self.buffer.resize(min_capacity, value);
436 }
437
438 pub fn read(&self, delay_samples: T) -> T {
440 self.reader.read(&self.buffer, delay_samples)
441 }
442
443 pub fn write(&mut self, value: T) -> &mut Self {
445 self.buffer.advance(1);
446 self.buffer.set(0, value);
447 self
448 }
449}
450
451pub struct MultiDelay<T: Float, I> {
453 reader: Reader<T, I>,
454 channels: usize,
455 buffer: MultiBuffer<T>,
456}
457
458impl<T: Float, I: InterpolatorTrait<T>> MultiDelay<T, I> {
459 pub fn new(interpolator: I, channels: usize, capacity: usize) -> Self {
461 Self {
462 reader: Reader::new(interpolator),
463 channels,
464 buffer: MultiBuffer::new(channels, capacity),
465 }
466 }
467
468 pub fn reset(&mut self, value: T) {
470 self.buffer.reset(value);
471 }
472
473 pub fn resize(&mut self, channels: usize, capacity: usize, value: T) {
475 self.channels = channels;
476 self.buffer.resize(channels, capacity, value);
477 }
478
479 pub fn read_channel(&self, channel: usize, delay_samples: T) -> T {
481 self.reader.read(&self.buffer.channel(channel), delay_samples)
482 }
483
484 pub fn read(&self, delay_samples: T, output: &mut [T]) {
486 for c in 0..self.channels {
487 output[c] = self.read_channel(c, delay_samples);
488 }
489 }
490
491 pub fn read_multi(&self, delays: &[T], output: &mut [T]) {
493 for c in 0..self.channels {
494 output[c] = self.read_channel(c, delays[c]);
495 }
496 }
497
498 pub fn write(&mut self, data: &[T]) -> &mut Self {
500 self.buffer.advance(1);
501 for c in 0..self.channels {
502 self.buffer.set(c, 0, data[c]);
503 }
504 self
505 }
506}
507
508#[cfg(test)]
509mod tests {
510 use super::*;
511
512 #[test]
513 fn test_buffer() {
514 let mut buffer = Buffer::<f32>::new(16);
515
516 buffer.set(0, 1.0);
518 buffer.set(1, 2.0);
519 buffer.set(2, 3.0);
520
521 assert_eq!(buffer.get(0), 1.0);
523 assert_eq!(buffer.get(1), 2.0);
524 assert_eq!(buffer.get(2), 3.0);
525
526 buffer.advance(1);
528 assert_eq!(buffer.get(-1), 1.0);
529 assert_eq!(buffer.get(0), 2.0);
530 assert_eq!(buffer.get(1), 3.0);
531 }
532
533 #[test]
534 fn test_multi_buffer() {
535 let mut buffer = MultiBuffer::<f32>::new(2, 16);
536
537 buffer.set(0, 0, 1.0);
539 buffer.set(0, 1, 2.0);
540 buffer.set(1, 0, 3.0);
541 buffer.set(1, 1, 4.0);
542
543 assert_eq!(buffer.get(0, 0), 1.0);
545 assert_eq!(buffer.get(0, 1), 2.0);
546 assert_eq!(buffer.get(1, 0), 3.0);
547 assert_eq!(buffer.get(1, 1), 4.0);
548
549 buffer.advance(1);
551 assert_eq!(buffer.get(0, -1), 1.0);
552 assert_eq!(buffer.get(0, 0), 2.0);
553 assert_eq!(buffer.get(1, -1), 3.0);
554 assert_eq!(buffer.get(1, 0), 4.0);
555 }
556
557 #[test]
558 fn test_interpolators() {
559 let data = [1.0, 2.0, 3.0, 4.0];
561
562 let nearest = InterpolatorNearest::<f32>::new();
564 assert_eq!(nearest.fractional(&data, 0.0), 1.0);
565 assert_eq!(nearest.fractional(&data, 0.4), 1.0);
566 assert_eq!(nearest.fractional(&data, 0.6), 1.0);
567
568 let linear = InterpolatorLinear::<f32>::new();
570 assert_eq!(linear.fractional(&data, 0.0), 1.0);
571 assert_eq!(linear.fractional(&data, 0.5), 1.5);
572 assert_eq!(linear.fractional(&data, 1.0), 2.0);
573
574 let cubic = InterpolatorCubic::<f32>::new();
576 assert_eq!(cubic.fractional(&data, 0.0), 2.0);
577 let cubic_result = cubic.fractional(&data, 0.5);
579 assert!(cubic_result > 2.0 && cubic_result < 3.0);
580 }
581
582 #[test]
583 fn test_delay() {
584 let interpolator = InterpolatorLinear::<f32>::new();
585 let mut delay = Delay::new(interpolator, 16);
586
587 delay.write(1.0).write(2.0).write(3.0);
589
590 assert_eq!(delay.read(0.0), 3.0);
592 assert_eq!(delay.read(1.0), 2.0);
593 assert_eq!(delay.read(2.0), 1.0);
594 assert_eq!(delay.read(0.5), 2.5); }
596
597 #[test]
598 fn test_multi_delay() {
599 let interpolator = InterpolatorLinear::<f32>::new();
600 let mut delay = MultiDelay::new(interpolator, 2, 16);
601
602 delay.write(&[1.0, 3.0]).write(&[2.0, 4.0]);
604
605 let mut output = [0.0, 0.0];
607 delay.read(0.0, &mut output);
608 assert_eq!(output, [2.0, 4.0]);
609
610 delay.read(1.0, &mut output);
611 assert_eq!(output, [1.0, 3.0]);
612
613 delay.read_multi(&[0.0, 1.0], &mut output);
615 assert_eq!(output, [2.0, 3.0]);
616 }
617}