use crate::engine::audio::effects::processors::super_trait::EffectProcessor;
use std::fmt::Debug;
#[derive(Debug, Clone)]
pub struct ReverbProcessor {
room_size: f32,
damping: f32,
mix: f32,
decay: f32,
comb_buffers: Vec<Vec<f32>>,
comb_positions: Vec<usize>,
comb_feedback: Vec<f32>,
allpass_buffers: Vec<Vec<f32>>,
allpass_positions: Vec<usize>,
}
impl ReverbProcessor {
pub fn new(room_size: f32, damping: f32, decay: f32, mix: f32) -> Self {
let room_size = room_size.clamp(0.0, 1.0);
let damping = damping.clamp(0.0, 1.0);
let decay = decay.clamp(0.0, 2.0);
let comb_delays = [1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617];
let mut comb_buffers = Vec::new();
let mut comb_feedback = Vec::new();
for &delay in &comb_delays {
comb_buffers.push(vec![0.0; delay]);
let base = 0.78 + room_size * 0.14; let mult = 0.6 + decay * 0.2; let mut fb = base * mult;
if fb >= 0.995 {
fb = 0.995;
}
comb_feedback.push(fb);
}
let allpass_delays = [556, 441, 341, 225];
let mut allpass_buffers = Vec::new();
for &delay in &allpass_delays {
allpass_buffers.push(vec![0.0; delay]);
}
Self {
room_size,
damping,
mix: mix.clamp(0.0, 1.0),
decay,
comb_buffers,
comb_positions: vec![0; 8],
comb_feedback,
allpass_buffers,
allpass_positions: vec![0; 4],
}
}
}
impl Default for ReverbProcessor {
fn default() -> Self {
Self::new(0.5, 0.5, 0.5, 0.3)
}
}
impl EffectProcessor for ReverbProcessor {
fn process(&mut self, samples: &mut [f32], _sample_rate: u32) {
for i in 0..samples.len() {
let input = samples[i];
let mut output = 0.0;
for (j, buffer) in self.comb_buffers.iter_mut().enumerate() {
let pos = self.comb_positions[j];
let delayed = buffer[pos];
let filtered = delayed * (1.0 - self.damping);
buffer[pos] = input + filtered * self.comb_feedback[j];
output += delayed;
self.comb_positions[j] = (pos + 1) % buffer.len();
}
output /= self.comb_buffers.len() as f32;
for (j, buffer) in self.allpass_buffers.iter_mut().enumerate() {
let pos = self.allpass_positions[j];
let delayed = buffer[pos];
buffer[pos] = output + delayed * 0.5;
output = delayed - output * 0.5;
self.allpass_positions[j] = (pos + 1) % buffer.len();
}
samples[i] = input * (1.0 - self.mix) + output * self.mix;
}
}
fn reset(&mut self) {
for buffer in &mut self.comb_buffers {
buffer.fill(0.0);
}
for buffer in &mut self.allpass_buffers {
buffer.fill(0.0);
}
self.comb_positions.fill(0);
self.allpass_positions.fill(0);
}
fn name(&self) -> &str {
"Reverb"
}
}