#[derive(Clone)]
pub struct StereoLimiter {
threshold: f32,
knee_width: f32,
}
impl StereoLimiter {
pub fn new(threshold: f32, knee_width: f32) -> Self {
StereoLimiter {
threshold,
knee_width,
}
}
pub fn update(&mut self, knee_width: f32, threshold: f32) {
self.threshold = threshold;
self.knee_width = knee_width;
}
pub fn process(&self, left_in: f32, right_in: f32) -> (f32, f32) {
let left_gain = self.limit(left_in);
let right_gain = self.limit(right_in);
(left_gain, right_gain)
}
pub fn limit(&self, input: f32) -> f32 {
let knee_range = self.knee_width / 2.0;
let soft_threshold = self.threshold + knee_range;
if input.abs() > soft_threshold {
let gain_reduction = (input.abs() - soft_threshold) / knee_range;
let gain = 1.0 / (1.0 + gain_reduction);
gain * input.signum() * soft_threshold.abs()
} else {
input
}
}
}