1#[derive(PartialEq, Eq)]
7pub struct DelayLine<B> {
8 pos: usize,
9 buffer: B,
10}
11
12impl<B> DelayLine<B>
13where
14 B: Buffer,
15{
16 pub fn new() -> DelayLine<B> {
18 DelayLine {
19 pos: 0,
20 buffer: B::zeroed(),
21 }
22 }
23
24 pub fn reset(&mut self) {
26 self.pos = 0;
27 self.buffer = B::zeroed();
28 }
29
30 pub fn size(&self) -> usize {
32 self.buffer.len()
33 }
34
35 pub fn back(&self) -> f32 {
37 let idx = self.index_back();
38 *self.buffer.index(idx)
39 }
40
41 pub fn index_back(&self) -> usize {
43 let i = self.pos + 1;
44 if i < self.size() {
45 i
46 } else {
47 0
48 }
49 }
50
51 pub fn read(&self, i: i32) -> &f32 {
53 let mut idx = self.pos as i32 - i;
54 if idx < 0 {
55 idx += self.size() as i32;
56 }
57 self.buffer.index(idx as usize)
58 }
59
60 pub fn write(&mut self, value: f32) {
62 *self.buffer.index_mut(self.pos) = value;
63 self.pos += 1;
64 if self.pos >= self.size() {
65 self.pos = 0;
66 }
67 }
68
69 pub fn get_write_and_step(&mut self, value: f32) -> f32 {
71 let r = *self.buffer.index(self.pos);
72 self.write(value);
73 r
74 }
75
76 pub fn comb(&mut self, value: f32, feed_fwd: f32, feed_bck: f32) -> f32 {
78 let d = *self.buffer.index(self.pos);
79 let r = value + d * feed_bck;
80 self.write(r);
81 d + r * feed_fwd
82 }
83
84 pub fn allpass(&mut self, value: f32, feed_fwd: f32) -> f32 {
86 self.comb(value, feed_fwd, -feed_fwd)
87 }
88}
89
90impl<B> Clone for DelayLine<B>
91where
92 B: Buffer,
93{
94 fn clone(&self) -> Self {
95 DelayLine {
96 pos: self.pos,
97 buffer: Buffer::clone(&self.buffer),
98 }
99 }
100}
101
102impl<B> ::std::fmt::Debug for DelayLine<B>
103where
104 B: Buffer,
105{
106 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
107 write!(
108 f,
109 "pos: {:?}, buffer: [f32; {:?}]",
110 self.pos,
111 self.buffer.len()
112 )
113 }
114}
115
116pub trait Buffer {
118 fn zeroed() -> Self;
119 fn clone(&self) -> Self;
120 fn len(&self) -> usize;
121 fn index(&self, idx: usize) -> &f32;
122 fn index_mut(&mut self, idx: usize) -> &mut f32;
123}