58 lines
1.6 KiB
Rust
58 lines
1.6 KiB
Rust
|
/// Very small amount
|
||
|
const VSA: f32 = 1.0 / 4294967295.0;
|
||
|
|
||
|
/// Splits the input into three bands
|
||
|
#[derive(Default)]
|
||
|
pub struct ThreeBandSplitter {
|
||
|
// Filter #1 (Low band)
|
||
|
f1p0: f32, // Poles ...
|
||
|
f1p1: f32,
|
||
|
f1p2: f32,
|
||
|
f1p3: f32,
|
||
|
|
||
|
// Filter #2 (High band)
|
||
|
f2p0: f32, // Poles ...
|
||
|
f2p1: f32,
|
||
|
f2p2: f32,
|
||
|
f2p3: f32,
|
||
|
|
||
|
// Sample history buffer
|
||
|
sdm1: f32, // Sample data minus 1
|
||
|
sdm2: f32, // 2
|
||
|
sdm3: f32, // 3
|
||
|
}
|
||
|
impl ThreeBandSplitter {
|
||
|
/// Returns (low, mid, high) bands
|
||
|
pub fn process(&mut self, input: f32, lf: f32, hf: f32, sample_rate: f32) -> (f32, f32, f32) {
|
||
|
let lf = 2.0 * (std::f32::consts::PI * (lf / sample_rate)).sin();
|
||
|
let hf = 2.0 * (std::f32::consts::PI * (hf / sample_rate)).sin();
|
||
|
|
||
|
// Filter #1 (low pass)
|
||
|
self.f1p0 += lf * (input - self.f1p0) + VSA;
|
||
|
self.f1p1 += lf * (self.f1p0 - self.f1p1);
|
||
|
self.f1p2 += lf * (self.f1p1 - self.f1p2);
|
||
|
self.f1p3 += lf * (self.f1p2 - self.f1p3);
|
||
|
|
||
|
let l = self.f1p3;
|
||
|
|
||
|
// Filter #2 (high pass)
|
||
|
self.f2p0 += hf * (input - self.f2p0) + VSA;
|
||
|
self.f2p1 += hf * (self.f2p0 - self.f2p1);
|
||
|
self.f2p2 += hf * (self.f2p1 - self.f2p2);
|
||
|
self.f2p3 += hf * (self.f2p2 - self.f2p3);
|
||
|
|
||
|
// we subtract from sdm3 because the filter has a three sample delay
|
||
|
let h = self.sdm3 - self.f2p3;
|
||
|
|
||
|
// Calculate midrange (signal - (low + high))
|
||
|
let m = self.sdm3 - (h + l);
|
||
|
|
||
|
// Shuffle history buffer
|
||
|
self.sdm3 = self.sdm2;
|
||
|
self.sdm2 = self.sdm1;
|
||
|
self.sdm1 = input;
|
||
|
|
||
|
(l, m, h)
|
||
|
}
|
||
|
}
|