feat(common-dsp): second-order SVF allpass
SvfCoef::allpass has the phase of a Linkwitz-Riley split at the same frequency, so a crossover tree can keep its lower bands in phase with the upper ones. The test checks it against a real LR4 split sample by sample and for flat magnitude.
This commit is contained in:
1 parent
53bc26d14d
commit
22870127c8
2 files changed
+40
No files matched your search
@@ -46,6 +46,31 @@ fn svf_bell_at_zero_db_is_an_exact_identity() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn svf_allpass_matches_a_linkwitz_riley_split() {
|
||||
let q = std::f32::consts::FRAC_1_SQRT_2;
|
||||
let (low, high, all) = (
|
||||
SvfCoef::lowpass(RATE, 300., q),
|
||||
SvfCoef::highpass(RATE, 300., q),
|
||||
SvfCoef::allpass(RATE, 300., q),
|
||||
);
|
||||
let mut s = [Svf::default(); 5];
|
||||
let mut saw = Saw::new(RATE, 55.);
|
||||
for _ in 0..9600 {
|
||||
let x = saw.sample();
|
||||
let l = s[0].process(&low, x);
|
||||
let l = s[1].process(&low, l);
|
||||
let h = s[2].process(&high, x);
|
||||
let h = s[3].process(&high, h);
|
||||
let a = s[4].process(&all, x);
|
||||
assert!((l + h - a).abs() < 1e-4, "{} vs {a}", l + h);
|
||||
}
|
||||
let mut s = Svf::default();
|
||||
for hz in [30., 300., 3000.] {
|
||||
assert!(sine_gain(|x| s.process(&all, x), hz).abs() < 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn svf_survives_retuning_every_sample() {
|
||||
let mut s = Svf::default();
|
||||
|
||||
Reference in new issue
Block a user