unnieversal/crates/utils/src/envelope.rs

42 lines
1.0 KiB
Rust

// from https://www.musicdsp.org/en/latest/Analysis/97-envelope-detector.html
// with some modifications
pub struct EnvelopeFollower {
x1: f32,
x2: f32,
ga: f32,
gr: f32,
}
impl EnvelopeFollower {
pub fn new() -> Self {
Self {
x1: 0.0,
x2: 0.0,
ga: 0.0,
gr: 0.0,
}
}
/// attack and release are in seconds
pub fn set_attack_release(&mut self, sample_rate: f32, attack: f32, release: f32) {
self.ga = (-1.0 / (sample_rate * attack)).exp();
self.gr = (-1.0 / (sample_rate * release)).exp();
}
pub fn process(&mut self, input: f32) -> f32 {
let in_abs = input.abs();
// 2nd order lowpass
if self.x1 < in_abs {
self.x1 = in_abs + self.ga * (self.x1 - in_abs);
self.x2 = self.x1 + self.ga * (self.x2 - self.x1);
} else {
self.x1 = in_abs + self.gr * (self.x1 - in_abs);
self.x2 = self.x1 + self.gr * (self.x2 - self.x1);
}
self.x2
}
}