audio_engine_core/processor/
dsp_chain.rs1use super::traits::AudioProcessor;
34
35pub struct DspChain {
40 processors: Vec<Box<dyn AudioProcessor>>,
42}
43
44impl DspChain {
45 pub fn new(_sample_rate: f64) -> Self {
47 Self {
48 processors: Vec::new(),
49 }
50 }
51
52 pub fn with_capacity(capacity: usize, _sample_rate: f64) -> Self {
54 Self {
55 processors: Vec::with_capacity(capacity),
56 }
57 }
58
59 pub fn add<P: AudioProcessor + 'static>(&mut self, processor: P) -> &mut Self {
61 self.processors.push(Box::new(processor));
62 self
63 }
64
65 pub fn process(&mut self, buffer: &mut [f64], channels: usize) {
78 for processor in &mut self.processors {
79 processor.process(buffer, channels);
80 }
81 }
82
83 pub fn reset(&mut self) {
85 for processor in &mut self.processors {
86 processor.reset();
87 }
88 }
89
90 pub fn set_sample_rate(&mut self, sample_rate: f64) {
92 for processor in &mut self.processors {
93 processor.set_sample_rate(sample_rate);
94 }
95 }
96
97 pub fn len(&self) -> usize {
99 self.processors.len()
100 }
101
102 pub fn is_empty(&self) -> bool {
104 self.processors.is_empty()
105 }
106
107 pub fn clear(&mut self) {
109 self.processors.clear();
110 }
111}
112
113impl Default for DspChain {
114 fn default() -> Self {
115 Self::new(44100.0)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::super::traits::ProcessResult;
122 use super::*;
123
124 struct DoublerProcessor {
126 enabled: bool,
127 processed_count: u64,
128 }
129
130 impl DoublerProcessor {
131 fn new() -> Self {
132 Self {
133 enabled: true,
134 processed_count: 0,
135 }
136 }
137 }
138
139 impl AudioProcessor for DoublerProcessor {
140 fn name(&self) -> &'static str {
141 "Doubler"
142 }
143
144 fn process(&mut self, buffer: &mut [f64], _channels: usize) -> ProcessResult {
145 if !self.enabled {
146 return ProcessResult::Bypassed;
147 }
148 for sample in buffer.iter_mut() {
149 *sample *= 2.0;
150 }
151 self.processed_count += 1;
152 ProcessResult::Ok
153 }
154
155 fn reset(&mut self) {
156 self.processed_count = 0;
157 }
158
159 fn is_enabled(&self) -> bool {
160 self.enabled
161 }
162
163 fn set_enabled(&mut self, enabled: bool) {
164 self.enabled = enabled;
165 }
166 }
167
168 struct AdderProcessor {
170 enabled: bool,
171 }
172
173 impl AdderProcessor {
174 fn new() -> Self {
175 Self { enabled: true }
176 }
177 }
178
179 impl AudioProcessor for AdderProcessor {
180 fn name(&self) -> &'static str {
181 "Adder"
182 }
183
184 fn process(&mut self, buffer: &mut [f64], _channels: usize) -> ProcessResult {
185 if !self.enabled {
186 return ProcessResult::Bypassed;
187 }
188 for sample in buffer.iter_mut() {
189 *sample += 1.0;
190 }
191 ProcessResult::Ok
192 }
193
194 fn reset(&mut self) {}
195
196 fn is_enabled(&self) -> bool {
197 self.enabled
198 }
199
200 fn set_enabled(&mut self, enabled: bool) {
201 self.enabled = enabled;
202 }
203 }
204
205 #[test]
206 fn test_empty_chain() {
207 let mut chain = DspChain::new(44100.0);
208 let mut buffer = vec![1.0, 2.0, 3.0];
209 chain.process(&mut buffer, 1);
210 assert_eq!(buffer, vec![1.0, 2.0, 3.0]);
211 }
212
213 #[test]
214 fn test_single_processor() {
215 let mut chain = DspChain::new(44100.0);
216 chain.add(DoublerProcessor::new());
217
218 let mut buffer = vec![1.0, 2.0, 3.0];
219 chain.process(&mut buffer, 1);
220
221 assert_eq!(buffer, vec![2.0, 4.0, 6.0]);
222 }
223
224 #[test]
225 fn test_chain_order() {
226 let mut chain = DspChain::new(44100.0);
227 chain.add(DoublerProcessor::new()); chain.add(AdderProcessor::new()); let mut buffer = vec![1.0];
232 chain.process(&mut buffer, 1);
233 assert_eq!(buffer, vec![3.0]);
234 }
235
236 #[test]
237 fn test_bypassed_processor() {
238 let mut chain = DspChain::new(44100.0);
239 let mut doubler = DoublerProcessor::new();
240 doubler.set_enabled(false);
241 chain.add(doubler);
242
243 let mut buffer = vec![5.0];
244 chain.process(&mut buffer, 1);
245
246 assert_eq!(buffer, vec![5.0]);
248 }
249
250 #[test]
251 fn test_reset() {
252 let mut chain = DspChain::new(44100.0);
253 chain.add(DoublerProcessor::new());
254
255 let mut buffer = vec![1.0; 100];
256 chain.process(&mut buffer, 1);
257 chain.reset();
258 }
260}