basic_reverb/
basic_reverb.rs

1use crate::diffuser::diffuser_half_lengths::DiffuserHalfLengths;
2use crate::multi_channel_mixed_feedback::MultiChannelMixedFeedback;
3use array_init::array_init;
4
5pub struct BasicReverb<const CHANNELS: usize, const SAMPLE_RATE: u32> {
6    dry: f64,
7    wet: f64,
8    diffuser: DiffuserHalfLengths<CHANNELS, SAMPLE_RATE>,
9    feedback: MultiChannelMixedFeedback<CHANNELS, SAMPLE_RATE>,
10}
11
12impl<const CHANNELS: usize, const SAMPLE_RATE: u32> BasicReverb<CHANNELS, SAMPLE_RATE> {
13    pub fn new(room_size_ms: f64, rt60: f64, dry: f64, wet: f64) -> Self {
14        let diffuser = DiffuserHalfLengths::new(room_size_ms);
15
16        // How long does our signal take to go around the feedback loop?
17        let typical_loop_ms = room_size_ms * 1.5;
18        // How many times will it do that during our RT60 period?
19        let loops_per_rt_60 = rt60 / (typical_loop_ms * 0.001);
20        // This tells us how many dB to reduce per loop
21        let db_per_cycle = -60. / loops_per_rt_60;
22
23        let delay_ms = room_size_ms;
24        let decay_gain = f64::powf(10., db_per_cycle * 0.05);
25        let feedback = MultiChannelMixedFeedback::new(delay_ms, decay_gain);
26
27        Self {
28            dry,
29            wet,
30            feedback,
31            diffuser,
32        }
33    }
34
35    pub fn process(&mut self, input: [f64; CHANNELS]) -> [f64; CHANNELS] {
36        let diffuse = self.diffuser.process(input);
37        let long_lasting = self.feedback.process(diffuse);
38
39        let output = array_init(|i| {
40            let dry = self.dry * input[i];
41            let wet = self.wet * long_lasting[i];
42            dry + wet
43        });
44
45        output
46    }
47}