removed other moog variants and replaced it with a slightly nicer/different one.

This commit is contained in:
Weird Constructor 2021-08-06 05:14:42 +02:00
parent da08c8d85e
commit 80e9fa0d8e
5 changed files with 67 additions and 353 deletions

View file

@ -1096,9 +1096,8 @@ pub fn process_simper_svf(
(v2, v1, input - k * v1 - v2) (v2, v1, input - k * v1 - v2)
} }
/// This function implements a simple Stilson/Moog filter with 24dB. /// This function implements a simple Stilson/Moog low pass filter with 24dB.
/// It provides multiple outputs for low, high and band pass and a notch /// It provides only a low pass output.
/// output.
/// ///
/// * `input` - Input sample. /// * `input` - Input sample.
/// * `freq` - Frequency in Hz. /// * `freq` - Frequency in Hz.
@ -1106,7 +1105,8 @@ pub fn process_simper_svf(
/// * `res` - Resonance from 0.0 to 0.99. Resonance of 1.0 is not recommended, /// * `res` - Resonance from 0.0 to 0.99. Resonance of 1.0 is not recommended,
/// as the filter will then oscillate itself out of control. /// as the filter will then oscillate itself out of control.
/// * `israte` - 1.0 divided by the sampling rate (`1.0 / 44100.0`). /// * `israte` - 1.0 divided by the sampling rate (`1.0 / 44100.0`).
/// * `b0` to `b4` - Internal values used for filtering. /// * `b0` to `b3` - Internal values used for filtering.
/// * `delay` - A buffer holding other delayed samples.
/// ///
///``` ///```
/// use hexodsp::dsp::helpers::*; /// use hexodsp::dsp::helpers::*;
@ -1116,51 +1116,62 @@ pub fn process_simper_svf(
/// let mut b1 = 0.0; /// let mut b1 = 0.0;
/// let mut b2 = 0.0; /// let mut b2 = 0.0;
/// let mut b3 = 0.0; /// let mut b3 = 0.0;
/// let mut b4 = 0.0; /// let mut delay = [0.0; 4];
/// let mut freq = 1000.0; /// let mut freq = 1000.0;
/// ///
/// for s in samples.iter() { /// for s in samples.iter() {
/// let (low, band, high, notch) = /// let low =
/// process_stilson_moog( /// process_stilson_moog(
/// *s, freq, 0.5, 1.0 / 44100.0, /// *s, freq, 0.5, 1.0 / 44100.0,
/// &mut b0, &mut b1, &mut b2, &mut b3, &mut b4); /// &mut b0, &mut b1, &mut b2, &mut b3,
/// &mut delay);
/// ///
/// // ... do something with the result here. /// // ... do something with the result here.
/// } /// }
///``` ///```
// Stilson/Moog implementation partly translated from SynthV1 by rncbc // Stilson/Moog implementation partly translated from here:
// https://github.com/rncbc/synthv1/blob/master/src/synthv1_filter.h#L103 // https://github.com/ddiakopoulos/MoogLadders/blob/master/src/MusicDSPModel.h
// under GPLv2 or any later. // without any copyright as found on musicdsp.org
// (http://www.musicdsp.org/showone.php?id=24).
// //
// It's also found on MusicDSP and has probably no proper license anyways. // It's also found on MusicDSP and has probably no proper license anyways.
// See also: https://github.com/ddiakopoulos/MoogLadders // See also: https://github.com/ddiakopoulos/MoogLadders
// and https://github.com/rncbc/synthv1/blob/master/src/synthv1_filter.h#L103
// and https://github.com/ddiakopoulos/MoogLadders/blob/master/src/MusicDSPModel.h // and https://github.com/ddiakopoulos/MoogLadders/blob/master/src/MusicDSPModel.h
#[inline] #[inline]
pub fn process_stilson_moog( pub fn process_stilson_moog(
input: f32, freq: f32, res: f32, israte: f32, input: f32, freq: f32, res: f32, israte: f32,
b0: &mut f32, b1: &mut f32, b2: &mut f32, b3: &mut f32, b4: &mut f32 b0: &mut f32, b1: &mut f32, b2: &mut f32, b3: &mut f32,
) -> (f32, f32, f32, f32) { delay: &mut [f32; 4],
) -> f32 {
let cutoff = 2.0 * freq * israte; let cutoff = 2.0 * freq * israte;
let c = 1.0 - cutoff; let p = cutoff * (1.8 - 0.8 * cutoff);
let p = cutoff + 0.8 * cutoff * c; let k = 2.0 * (cutoff * std::f32::consts::PI * 0.5).sin() - 1.0;
let f = p + p - 1.0;
let q = res * (1.0 + 0.5 * c * (1.0 - c + 5.6 * c * c));
let inp = input - q * *b4; let t1 = (1.0 - p) * 1.386249;
let t1 = *b1; *b1 = (inp + *b0) * p - *b1 * f; let t2 = 12.0 + t1 * t1;
let t2 = *b2; *b2 = (*b1 + t1) * p - *b2 * f;
let t1 = *b3; *b3 = (*b2 + t2) * p - *b3 * f;
*b4 = (*b3 + t1) * p - *b4 * f;
*b4 = *b4 - *b4 * *b4 * *b4 * 0.166667; // clipping let res = res * (t2 + 6.0 * t1) / (t2 - 6.0 * t1);
*b0 = inp; let x = input - res * *b3;
let band = 3.0 * (*b3 - *b4); // Four cascaded one-pole filters (bilinear transform)
*b0 = x * p + delay[0] * p - k * *b0;
*b1 = *b0 * p + delay[1] * p - k * *b1;
*b2 = *b1 * p + delay[2] * p - k * *b2;
*b3 = *b2 * p + delay[3] * p - k * *b3;
// low, band, high, notch // Clipping band-limited sigmoid
(*b4, band, inp - *b4, band - inp) *b3 -= (*b3 * *b3 * *b3) * 0.166667;
delay[0] = x;
delay[1] = *b0;
delay[2] = *b1;
delay[3] = *b2;
*b3
} }
// translated from Odin 2 Synthesizer Plugin // translated from Odin 2 Synthesizer Plugin

View file

@ -660,7 +660,7 @@ macro_rules! node_list {
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) (0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)
(1 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 1000.0) (1 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 1000.0)
(2 res n_id d_id r_id f_def stp_d 0.0, 1.0, 0.5) (2 res n_id d_id r_id f_def stp_d 0.0, 1.0, 0.5)
{3 0 ftype setting(8) fa_sfilter_type 0 16} {3 0 ftype setting(8) fa_sfilter_type 0 13}
[0 sig], [0 sig],
biqfilt => BiqFilt UIType::Generic UICategory::Signal biqfilt => BiqFilt UIType::Generic UICategory::Signal
(0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) (0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0)

View file

@ -34,7 +34,9 @@ impl Comb {
pub const inp : &'static str = pub const inp : &'static str =
"Comb inp\nThe signal input for the comb filter.\nRange: (-1..1)"; "Comb inp\nThe signal input for the comb filter.\nRange: (-1..1)";
pub const g : &'static str = pub const g : &'static str =
"Comb g\nThe internal factor for the comb filter.\nRange: (-1..1)"; "Comb g\nThe internal factor for the comb filter. Be careful with high 'g' \
values (> 0.75) in feedback mode, you will probably have to attenuate \
the output a bit yourself.\nRange: (-1..1)";
pub const time : &'static str = pub const time : &'static str =
"Comb time\nThe comb delay time.\nRange: (0..1)"; "Comb time\nThe comb delay time.\nRange: (0..1)";
pub const sig : &'static str = pub const sig : &'static str =
@ -55,6 +57,10 @@ This is a comb filter that can be used for filtering
as well as for building reverbs or anything you might as well as for building reverbs or anything you might
find it useful for. find it useful for.
Attention: Be careful with high 'g' values, you might need to
attenuate the output manually for the feedback combfilter mode,
because the feedback adds up quickly.
For typical arrangements in combination with allpass filters, For typical arrangements in combination with allpass filters,
see the documentation of the 'Comb' node! see the documentation of the 'Comb' node!
"#; "#;

View file

@ -32,9 +32,6 @@ macro_rules! fa_sfilter_type { ($formatter: expr, $v: expr, $denorm_v: expr) =>
11 => "NO 12s", 11 => "NO 12s",
12 => "PK 12s", 12 => "PK 12s",
13 => "LP 24m", 13 => "LP 24m",
14 => "HP 24m",
15 => "BP 24m",
16 => "NO 24m",
_ => "?", _ => "?",
}; };
write!($formatter, "{}", s) write!($formatter, "{}", s)
@ -48,7 +45,7 @@ pub struct SFilter {
y: f32, y: f32,
k: f32, k: f32,
h: f32, h: f32,
m: f32, delay: [f32; 4],
otype: i8, otype: i8,
} }
@ -60,7 +57,7 @@ impl SFilter {
y: 0.0, y: 0.0,
k: 0.0, k: 0.0,
h: 0.0, h: 0.0,
m: 0.0, delay: [0.0; 4],
otype: -1, otype: -1,
} }
} }
@ -126,9 +123,6 @@ fall off per octave. Beware high cutoff frequencies for this filter,
as it can become quite unstable. as it can become quite unstable.
LP 24m - Low-pass Stilson/Moog filter (24dB) LP 24m - Low-pass Stilson/Moog filter (24dB)
HP 24m - High-pass Stilson/Moog filter (24dB)
BP 24m - Band-pass Stilson/Moog filter (24dB)
NO 24m - Notch Stilson/Moog filter (24dB)
"#; "#;
} }
@ -243,7 +237,7 @@ impl DspNode for SFilter {
self.y = 0.0; self.y = 0.0;
self.k = 0.0; self.k = 0.0;
self.h = 0.0; self.h = 0.0;
self.m = 0.0; self.delay = [0.0; 4];
self.otype = -1; self.otype = -1;
} }
@ -269,7 +263,7 @@ impl DspNode for SFilter {
self.z = 0.0; self.z = 0.0;
self.k = 0.0; self.k = 0.0;
self.h = 0.0; self.h = 0.0;
self.m = 0.0; self.delay = [0.0; 4];
self.otype = ftype; self.otype = ftype;
} }
@ -394,46 +388,14 @@ impl DspNode for SFilter {
}, },
13 => { // Stilson/Moog Low Pass 13 => { // Stilson/Moog Low Pass
process_filter_fun32!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, { ctx.nframes(), inp, out, freq, res, 1.0, input, 20000.0, {
let (low, _band, _high, _notch) = // Clip here, to prevent blowups, because the
// moog filter is quite touchy...
let input = input.clamp(-1.0, 1.0);
process_stilson_moog( process_stilson_moog(
input, freq, res, self.israte, input, freq, res, self.israte,
&mut self.z, &mut self.y, &mut self.k, &mut self.z, &mut self.y, &mut self.k,
&mut self.h, &mut self.m); &mut self.h, &mut self.delay)
low
});
},
14 => { // Stilson/Moog High Pass
process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, {
let (_low, _band, high, _notch) =
process_stilson_moog(
input, freq, res, self.israte,
&mut self.z, &mut self.y, &mut self.k,
&mut self.h, &mut self.m);
high
});
},
15 => { // Stilson/Moog Band Pass
process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, {
let (_low, band, _high, _notch) =
process_stilson_moog(
input, freq, res, self.israte,
&mut self.z, &mut self.y, &mut self.k,
&mut self.h, &mut self.m);
band
});
},
16 => { // Stilson/Moog Notch
process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, {
let (_low, _band, _high, notch) =
process_stilson_moog(
input, freq, res, self.israte,
&mut self.z, &mut self.y, &mut self.k,
&mut self.h, &mut self.m);
notch
}); });
}, },
_ => {}, _ => {},

View file

@ -1012,7 +1012,7 @@ fn check_node_sfilter_moog_lowpass() {
1500, 2000, 3000, 4000, 6000, 12000 1500, 2000, 3000, 4000, 6000, 12000
], &fft[..]), vec![ ], &fft[..]), vec![
(0, 0), (100, 4), (200, 4), (400, 0), (500, 4), (700, 4), (0, 0), (100, 4), (200, 4), (400, 0), (500, 4), (700, 4),
(900, 12), (1000, 36), (1100, 80), (1200, 8), (900, 12), (1000, 148), (1100, 64), (1200, 4),
(1500, 0), (2000, 0), (3000, 0), (4000, 0), (6000, 0) (1500, 0), (2000, 0), (3000, 0), (4000, 0), (6000, 0)
]); ]);
@ -1023,8 +1023,8 @@ fn check_node_sfilter_moog_lowpass() {
100, 200, 400, 500, 700, 900, 1000, 1100, 1200, 100, 200, 400, 500, 700, 900, 1000, 1100, 1200,
1500, 2000, 3000, 4000, 6000, 12000 1500, 2000, 3000, 4000, 6000, 12000
], &fft[..]), vec![ ], &fft[..]), vec![
(0, 4), (100, 4), (200, 4), (400, 4), (500, 8), (0, 4), (100, 4), (200, 8), (400, 8), (500, 8),
(700, 12), (900, 16), (1000, 12), (1100, 8), (1200, 4), (700, 24), (900, 48), (1000, 28), (1100, 16), (1200, 4),
(1500, 0), (2000, 0), (3000, 0), (4000, 0), (6000, 0) (1500, 0), (2000, 0), (3000, 0), (4000, 0), (6000, 0)
]); ]);
@ -1035,8 +1035,8 @@ fn check_node_sfilter_moog_lowpass() {
100, 200, 400, 500, 700, 900, 1000, 1100, 1200, 100, 200, 400, 500, 700, 900, 1000, 1100, 1200,
1500, 2000, 3000, 4000, 6000, 12000 1500, 2000, 3000, 4000, 6000, 12000
], &fft[..]), vec![ ], &fft[..]), vec![
(0, 16), (100, 16), (200, 16), (400, 4), (500, 12), (700, 8), (0, 28), (100, 24), (200, 24), (400, 8), (500, 16), (700, 8),
(900, 4), (1000, 4), (1100, 0), (1200, 0), (1500, 0), (2000, 0), (900, 8), (1000, 4), (1100, 4), (1200, 4), (1500, 0), (2000, 0),
(3000, 0), (4000, 0), (6000, 0) (3000, 0), (4000, 0), (6000, 0)
]); ]);
@ -1046,8 +1046,8 @@ fn check_node_sfilter_moog_lowpass() {
avg_fft_freqs(4.0, &[ avg_fft_freqs(4.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000 100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![ ], &fft[..]), vec![
(0, 4), (100, 4), (500, 4), (1000, 4), (2000, 4), (0, 4), (100, 0), (500, 4), (1000, 4), (2000, 4),
(3500, 20), (4000, 52), (5000, 4), (6000, 0), (8000, 0) (3500, 28), (4000, 60), (5000, 4), (6000, 0), (8000, 0)
]); ]);
// Low Pass Stilson/Moog @ 4000Hz RES=0.0 // Low Pass Stilson/Moog @ 4000Hz RES=0.0
@ -1056,8 +1056,8 @@ fn check_node_sfilter_moog_lowpass() {
avg_fft_freqs(4.0, &[ avg_fft_freqs(4.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000 100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![ ], &fft[..]), vec![
(0, 20), (100, 12), (500, 16), (1000, 16), (2000, 12), (3500, 8), (0, 28), (100, 16), (500, 20), (1000, 20), (2000, 12), (3500, 8),
(4000, 4), (5000, 4), (6000, 0), (8000, 0) (4000, 8), (5000, 4), (6000, 0), (8000, 0)
]); ]);
// Low Pass Stilson/Moog @ 22050Hz RES=0.0 // Low Pass Stilson/Moog @ 22050Hz RES=0.0
@ -1065,7 +1065,7 @@ fn check_node_sfilter_moog_lowpass() {
assert_eq!( assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050, 22051], &fft[..]), vec![ avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050, 22051], &fft[..]), vec![
(0, 16), (100, 16), (1000, 16), (4000, 16), (12000, 16), (0, 16), (100, 16), (1000, 16), (4000, 16), (12000, 16),
(16000, 16), (20000, 8), (22050, 0) (16000, 16), (20000, 8), (22050, 8)
]); ]);
// Low Pass Stilson/Moog @ 22050Hz RES=1.0 // Low Pass Stilson/Moog @ 22050Hz RES=1.0
@ -1092,268 +1092,3 @@ fn check_node_sfilter_moog_lowpass() {
(4000, 0), (12000, 0), (22050, 0) (4000, 0), (12000, 0), (22050, 0)
]); ]);
} }
#[test]
fn check_node_sfilter_moog_highpass() {
let (mut matrix, mut node_exec) = setup_sfilter_matrix();
// High Pass Stilson/Moog @ 1000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 1000.0, 1.0);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (500, 10), (700, 20), (900, 40), (1000, 140),
(1500, 30), (2000, 10), (3000, 10), (4000, 10)
]);
// High Pass Stilson/Moog @ 1000Hz RES=0.5
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 1000.0, 0.5);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (500, 10), (700, 40), (900, 50), (1000, 40),
(1500, 20), (2000, 20), (3000, 10), (4000, 10)
]);
// High Pass Stilson/Moog @ 1000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 1000.0, 0.0);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 10), (500, 20), (700, 20), (900, 20), (1000, 20),
(1500, 20), (2000, 10), (3000, 20), (4000, 10)
]);
// High Pass Stilson/Moog @ 4000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 4000.0, 1.0);
assert_eq!(
avg_fft_freqs(4.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 0), (100, 0), (500, 0), (1000, 4), (2000, 16),
(3500, 68), (4000, 200), (5000, 36), (6000, 24), (8000, 16)
]);
// High Pass Stilson/Moog @ 4000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 4000.0, 0.0);
assert_eq!(
avg_fft_freqs(4.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 0), (100, 0), (500, 8), (1000, 16), (2000, 24), (3500, 28),
(4000, 24), (5000, 20), (6000, 20), (8000, 20)
]);
// High Pass Stilson/Moog @ 22050Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 22050.0, 0.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 0), (100, 0), (1000, 0), (4000, 0),
(12000, 0), (16000, 0), (20000, 8)
]);
// High Pass Stilson/Moog @ 22050Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 22050.0, 1.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0),
(16000, 0), (20000, 0)
]);
// High Pass Stilson/Moog @ 0Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 0.0, 0.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
// High Pass Stilson/Moog @ 0Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 14, 0.0, 1.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
}
#[test]
fn check_node_sfilter_moog_bandpass() {
let (mut matrix, mut node_exec) = setup_sfilter_matrix();
// Band Pass Stilson/Moog @ 1000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 1000.0, 1.0);
assert_eq!(
avg_fft_freqs(10.0, &[
250, 500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (250, 0), (500, 0), (700, 10), (900, 30),
(1000, 80), (1500, 10), (2000, 0), (3000, 0), (4000, 0)
]);
// Band Pass Stilson/Moog @ 1000Hz RES=0.5
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 1000.0, 0.5);
assert_eq!(
avg_fft_freqs(10.0, &[
250, 500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (250, 0), (500, 10), (700, 30), (900, 30), (1000, 20),
(1500, 0), (2000, 0), (3000, 0), (4000, 0)
]);
// Band Pass Stilson/Moog @ 1000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 1000.0, 0.0);
assert_eq!(
avg_fft_freqs(4.0, &[
250, 500, 700, 900, 1000, 1500, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 4), (250, 8), (500, 16), (700, 16), (900, 12), (1000, 12),
(1500, 4), (2000, 4), (3000, 0), (4000, 0)
]);
// Band Pass Stilson/Moog @ 4000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 4000.0, 1.0);
assert_eq!(
avg_fft_freqs(10.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 0), (100, 0), (500, 0), (1000, 0), (2000, 10),
(3500, 50), (4000, 130), (5000, 20), (6000, 10), (8000, 0)
]);
// Band Pass Stilson/Moog @ 4000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 4000.0, 0.0);
assert_eq!(
avg_fft_freqs(10.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 0), (100, 0), (500, 0), (1000, 10), (2000, 10), (3500, 10),
(4000, 10), (5000, 10), (6000, 10), (8000, 0)
]);
// Band Pass Stilson/Moog @ 22050Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 22050.0, 0.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 0), (100, 0), (1000, 0), (4000, 0),
(12000, 0), (16000, 8), (20000, 32)
]);
// Band Pass Stilson/Moog @ 22050Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 22050.0, 1.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0),
(16000, 0), (20000, 0)
]);
// Band Pass Stilson/Moog @ 0Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 0.0, 0.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
// Band Pass Stilson/Moog @ 0Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 15, 0.0, 1.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
}
#[test]
fn check_node_sfilter_moog_notch() {
let (mut matrix, mut node_exec) = setup_sfilter_matrix();
// Notch Stilson/Moog @ 1000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 1000.0, 1.0);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 850, 900, 950, 1000, 1100, 1200, 1400, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (500, 0), (700, 10), (850, 20), (900, 40), (950, 30),
(1000, 150), (1100, 370), (1200, 80), (1400, 40), (2000, 20),
(3000, 10), (4000, 10)
]);
// Notch Stilson/Moog @ 1000Hz RES=0.5
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 1000.0, 0.5);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 850, 900, 950, 1000, 1100, 1200, 1400, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 0), (500, 0), (700, 10), (850, 30), (900, 30), (950, 50),
(1000, 50), (1100, 50), (1200, 30), (1400, 30), (2000, 20),
(3000, 20), (4000, 10)
]);
// Notch Stilson/Moog @ 1000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 1000.0, 0.0);
assert_eq!(
avg_fft_freqs(10.0, &[
500, 700, 850, 900, 950, 1000, 1100, 1200, 1400, 2000, 3000, 4000, 12000
], &fft[..]), vec![
(0, 10), (500, 0), (700, 10), (850, 10), (900, 10), (950, 10),
(1000, 20), (1100, 10), (1200, 20), (1400, 20), (2000, 20),
(3000, 20), (4000, 10)
]);
// Notch Stilson/Moog @ 4000Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 4000.0, 1.0);
assert_eq!(
avg_fft_freqs(10.0, &[
100, 500, 1000, 2000, 3500, 4000, 4500, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 0), (100, 0), (500, 0), (1000, 0), (2000, 10), (3500, 50),
(4000, 260), (4500, 60), (5000, 40), (6000, 20), (8000, 20)
]);
// Notch Stilson/Moog @ 4000Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 4000.0, 0.0);
assert_eq!(
avg_fft_freqs(10.0, &[
100, 500, 1000, 2000, 3500, 4000, 5000, 6000, 8000, 12000
], &fft[..]), vec![
(0, 20), (100, 10), (500, 10), (1000, 0), (2000, 0), (3500, 10),
(4000, 20), (5000, 20), (6000, 20), (8000, 20)
]);
// Notch Stilson/Moog @ 22050Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 22050.0, 0.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 8), (100, 8), (1000, 16), (4000, 16), (12000, 8),
(16000, 16), (20000, 16)
]);
// Notch Stilson/Moog @ 22050Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 22050.0, 1.0);
assert_eq!(
avg_fft_freqs(8.0, &[100, 1000, 4000, 12000, 16000, 20000, 22050], &fft[..]),
vec![
(0, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0),
(16000, 0), (20000, 0)
]);
// Notch Stilson/Moog @ 0Hz RES=0.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 0.0, 0.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
// Notch Stilson/Moog @ 0Hz RES=1.0
let fft = fft_with_freq_res_type(&mut matrix, &mut node_exec, 16, 0.0, 1.0);
assert_eq!(
avg_fft_freqs(4.0, &[10, 100, 1000, 4000, 12000, 22050], &fft[..]), vec![
(0, 0), (10, 0), (100, 0), (1000, 0), (4000, 0), (12000, 0)
]);
}