use std::f32::consts;
pub trait FirstOrderFilter {
fn process(&mut self, input_sample: f32) -> f32;
}
fn get_alpha(frequency: u64, sample_rate: f32) -> f32 {
let rc = 1.0 / (2.0 * consts::PI * frequency as f32);
let dt = 1.0 / sample_rate;
rc / (rc + dt)
}
pub struct LowPassFilter {
prev_input_sample: f32,
prev_output_sample: f32,
alpha: f32,
}
impl LowPassFilter {
pub fn new(frequency: u64, sample_rate: f32) -> Self {
LowPassFilter {
prev_input_sample: 0.0,
prev_output_sample: 0.0,
alpha: get_alpha(frequency, sample_rate),
}
}
}
impl FirstOrderFilter for LowPassFilter {
fn process(&mut self, input_sample: f32) -> f32 {
let output_sample =
self.prev_output_sample + self.alpha * (input_sample - self.prev_output_sample);
self.prev_input_sample = input_sample;
self.prev_output_sample = output_sample;
output_sample
}
}
pub struct HighPassFilter {
prev_input_sample: f32,
prev_output_sample: f32,
alpha: f32,
}
impl HighPassFilter {
pub fn new(frequency: u64, sample_rate: f32) -> Self {
HighPassFilter {
prev_input_sample: 0.0,
prev_output_sample: 0.0,
alpha: get_alpha(frequency, sample_rate),
}
}
}
impl FirstOrderFilter for HighPassFilter {
fn process(&mut self, input_sample: f32) -> f32 {
let output_sample =
self.alpha * (self.prev_output_sample + input_sample - self.prev_input_sample);
self.prev_input_sample = input_sample;
self.prev_output_sample = output_sample;
output_sample
}
}