use f32 instead of f64 for filtering

This commit is contained in:
Weird Constructor 2021-07-15 06:28:44 +02:00
parent 7f7b8a0837
commit 7a46c38a00
2 changed files with 87 additions and 29 deletions

View file

@ -791,8 +791,8 @@ impl Comb {
/// // ... do something with the result here. /// // ... do something with the result here.
/// } /// }
///``` ///```
pub fn process_1pole_lowpass(input: f64, freq: f64, israte: f64, z: &mut f64) -> f64 { pub fn process_1pole_lowpass(input: f32, freq: f32, israte: f32, z: &mut f32) -> f32 {
let b = (-std::f64::consts::TAU * freq * israte).exp(); let b = (-std::f32::consts::TAU * freq * israte).exp();
let a = 1.0 - b; let a = 1.0 - b;
*z = a * input + *z * b; *z = a * input + *z * b;
*z *z
@ -824,8 +824,8 @@ pub fn process_1pole_lowpass(input: f64, freq: f64, israte: f64, z: &mut f64) ->
/// // ... do something with the result here. /// // ... do something with the result here.
/// } /// }
///``` ///```
pub fn process_1pole_highpass(input: f64, freq: f64, israte: f64, z: &mut f64, y: &mut f64) -> f64 { pub fn process_1pole_highpass(input: f32, freq: f32, israte: f32, z: &mut f32, y: &mut f32) -> f32 {
let b = (-std::f64::consts::TAU * freq * israte).exp(); let b = (-std::f32::consts::TAU * freq * israte).exp();
let a = (1.0 + b) / 2.0; let a = (1.0 + b) / 2.0;
let v = let v =
@ -863,8 +863,8 @@ pub fn process_1pole_highpass(input: f64, freq: f64, israte: f64, z: &mut f64, y
/// // ... do something with the result here. /// // ... do something with the result here.
/// } /// }
///``` ///```
pub fn process_1pole_tpt_lowpass(input: f64, freq: f64, israte: f64, z: &mut f64) -> f64 { pub fn process_1pole_tpt_lowpass(input: f32, freq: f32, israte: f32, z: &mut f32) -> f32 {
let g = (std::f64::consts::PI * freq * israte).tan(); let g = (std::f32::consts::PI * freq * israte).tan();
let a = g / (1.0 + g); let a = g / (1.0 + g);
let v1 = a * (input - *z); let v1 = a * (input - *z);
@ -901,8 +901,8 @@ pub fn process_1pole_tpt_lowpass(input: f64, freq: f64, israte: f64, z: &mut f64
/// // ... do something with the result here. /// // ... do something with the result here.
/// } /// }
///``` ///```
pub fn process_1pole_tpt_highpass(input: f64, freq: f64, israte: f64, z: &mut f64) -> f64 { pub fn process_1pole_tpt_highpass(input: f32, freq: f32, israte: f32, z: &mut f32) -> f32 {
let g = (std::f64::consts::PI * freq * israte).tan(); let g = (std::f32::consts::PI * freq * israte).tan();
let a1 = g / (1.0 + g); let a1 = g / (1.0 + g);
let v1 = a1 * (input - *z); let v1 = a1 * (input - *z);
@ -952,11 +952,11 @@ const FILTER_OVERSAMPLE_HAL_CHAMBERLIN : usize = 2;
///``` ///```
#[inline] #[inline]
pub fn process_hal_chamberlin_svf( pub fn process_hal_chamberlin_svf(
input: f64, freq: f64, res: f64, israte: f64, band: &mut f64, low: &mut f64) input: f32, freq: f32, res: f32, israte: f32, band: &mut f32, low: &mut f32)
-> (f64, f64) -> (f32, f32)
{ {
let q = 1.0 - res; let q = 1.0 - res;
let cutoff = 2.0 * (std::f64::consts::PI * freq * 0.5 * israte).sin(); let cutoff = 2.0 * (std::f32::consts::PI * freq * 0.5 * israte).sin();
let mut high = 0.0; let mut high = 0.0;
let mut notch = 0.0; let mut notch = 0.0;
@ -1015,11 +1015,11 @@ pub fn process_hal_chamberlin_svf(
// thanks, andy! // thanks, andy!
#[inline] #[inline]
pub fn process_simper_svf( pub fn process_simper_svf(
input: f64, freq: f64, res: f64, israte: f64, ic1eq: &mut f64, ic2eq: &mut f64 input: f32, freq: f32, res: f32, israte: f32, ic1eq: &mut f32, ic2eq: &mut f32
) -> (f64, f64, f64) { ) -> (f32, f32, f32) {
let g = (std::f64::consts::PI * freq * israte).tan(); let g = (std::f32::consts::PI * freq * israte).tan();
// XXX: the 1.989 were tuned by hand, so the resonance is more audible. // XXX: the 1.989 were tuned by hand, so the resonance is more audible.
let k = 2f64 - (1.989f64 * res); let k = 2f32 - (1.989f32 * res);
let a1 = 1.0 / (1.0 + (g * (g + k))); let a1 = 1.0 / (1.0 + (g * (g + k)));
let a2 = g * a1; let a2 = g * a1;

View file

@ -38,9 +38,11 @@ macro_rules! fa_sfilter_type { ($formatter: expr, $v: expr, $denorm_v: expr) =>
/// A simple amplifier /// A simple amplifier
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SFilter { pub struct SFilter {
israte: f64, israte: f32,
z: f64, z: f32,
y: f64, y: f32,
k: f32,
h: f32,
otype: i8, otype: i8,
} }
@ -50,6 +52,8 @@ impl SFilter {
israte: 1.0 / 44100.0, israte: 1.0 / 44100.0,
z: 0.0, z: 0.0,
y: 0.0, y: 0.0,
k: 0.0,
h: 0.0,
otype: -1, otype: -1,
} }
} }
@ -102,6 +106,56 @@ The (Andrew) Simper state variable filter is a newer design.
"#; "#;
} }
macro_rules! process_filter_fun32 {
($nframes: expr, $inp: expr, $out: ident, $freq: ident, $res: ident,
$input: ident, $minfreq: expr, $maxfreq: expr, $block: block) => { {
for frame in 0..$nframes {
let $input = $inp.read(frame);
let $freq = denorm::SFilter::freq($freq, frame);
let $freq = $freq.clamp($minfreq, $maxfreq);
let $res = denorm::SFilter::res($res, frame);
let $res = $res.clamp(0.0, 0.99);
let s = $block;
$out.write(frame, s);
}
} };
($nframes: expr, $inp: expr, $out: ident, $freq: ident, $res: ident,
$input: ident, $maxfreq: expr, $block: block) => { {
for frame in 0..$nframes {
let $input = $inp.read(frame);
let $freq = denorm::SFilter::freq($freq, frame);
let $freq = $freq.clamp(1.0, $maxfreq);
let $res = denorm::SFilter::res($res, frame);
let $res = $res.clamp(0.0, 0.99);
let s = $block;
$out.write(frame, s);
}
} };
($nframes: expr, $inp: expr, $out: ident, $freq: ident, $res: ident,
$maxres: expr, $input: ident, $maxfreq: expr, $block: block) => { {
for frame in 0..$nframes {
let $input = $inp.read(frame);
let $freq = denorm::SFilter::freq($freq, frame);
let $freq = $freq.clamp(1.0, $maxfreq);
let $res = denorm::SFilter::res($res, frame);
let $res = $res.clamp(0.0, $maxres);
let s = $block;
$out.write(frame, s);
}
} };
($nframes: expr, $inp: expr, $out: ident, $freq: ident,
$input: ident, $maxfreq: expr, $block: block) => { {
for frame in 0..$nframes {
let $input = $inp.read(frame);
let $freq = denorm::SFilter::freq($freq, frame);
let $freq = $freq.clamp(1.0, $maxfreq);
let s = $block;
$out.write(frame, s);
}
} }
}
macro_rules! process_filter_fun { macro_rules! process_filter_fun {
($nframes: expr, $inp: expr, $out: ident, $freq: ident, $res: ident, ($nframes: expr, $inp: expr, $out: ident, $freq: ident, $res: ident,
$input: ident, $minfreq: expr, $maxfreq: expr, $block: block) => { { $input: ident, $minfreq: expr, $maxfreq: expr, $block: block) => { {
@ -155,11 +209,13 @@ impl DspNode for SFilter {
fn outputs() -> usize { 1 } fn outputs() -> usize { 1 }
fn set_sample_rate(&mut self, srate: f32) { fn set_sample_rate(&mut self, srate: f32) {
self.israte = 1.0 / (srate as f64); self.israte = 1.0 / srate;
} }
fn reset(&mut self) { fn reset(&mut self) {
self.z = 0.0; self.z = 0.0;
self.y = 0.0; self.y = 0.0;
self.k = 0.0;
self.h = 0.0;
self.otype = -1; self.otype = -1;
} }
@ -183,40 +239,42 @@ impl DspNode for SFilter {
if ftype != self.otype { if ftype != self.otype {
self.y = 0.0; self.y = 0.0;
self.z = 0.0; self.z = 0.0;
self.k = 0.0;
self.h = 0.0;
self.otype = ftype; self.otype = ftype;
} }
match ftype { match ftype {
0 => { // Lowpass 0 => { // Lowpass
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, input, 22000.0, { ctx.nframes(), inp, out, freq, input, 22000.0, {
process_1pole_lowpass( process_1pole_lowpass(
input, freq, self.israte, &mut self.z) input, freq, self.israte, &mut self.z)
}) })
}, },
1 => { // Lowpass TPT 1 => { // Lowpass TPT
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, input, 22000.0, { ctx.nframes(), inp, out, freq, input, 22000.0, {
process_1pole_tpt_lowpass( process_1pole_tpt_lowpass(
input, freq, self.israte, &mut self.z) input, freq, self.israte, &mut self.z)
}) })
}, },
2 => { // Highpass 2 => { // Highpass
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, input, 22000.0, { ctx.nframes(), inp, out, freq, input, 22000.0, {
process_1pole_highpass( process_1pole_highpass(
input, freq, self.israte, &mut self.z, &mut self.y) input, freq, self.israte, &mut self.z, &mut self.y)
}) })
}, },
3 => { // Highpass TPT 3 => { // Highpass TPT
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, input, 22000.0, { ctx.nframes(), inp, out, freq, input, 22000.0, {
process_1pole_tpt_highpass( process_1pole_tpt_highpass(
input, freq, self.israte, &mut self.z) input, freq, self.israte, &mut self.z)
}) })
}, },
4 => { // Low Pass Hal Chamberlin SVF 4 => { // Low Pass Hal Chamberlin SVF
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, input, 2.0, 16000.0, { ctx.nframes(), inp, out, freq, res, input, 2.0, 16000.0, {
let (_high, _notch) = let (_high, _notch) =
process_hal_chamberlin_svf( process_hal_chamberlin_svf(
@ -226,7 +284,7 @@ impl DspNode for SFilter {
}); });
}, },
5 => { // High Pass Hal Chamberlin SVF 5 => { // High Pass Hal Chamberlin SVF
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, input, 16000.0, { ctx.nframes(), inp, out, freq, res, input, 16000.0, {
let (high, _notch) = let (high, _notch) =
process_hal_chamberlin_svf( process_hal_chamberlin_svf(
@ -236,7 +294,7 @@ impl DspNode for SFilter {
}); });
}, },
6 => { // Band Pass Hal Chamberlin SVF 6 => { // Band Pass Hal Chamberlin SVF
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, input, 16000.0, { ctx.nframes(), inp, out, freq, res, input, 16000.0, {
let (_high, _notch) = let (_high, _notch) =
process_hal_chamberlin_svf( process_hal_chamberlin_svf(
@ -246,7 +304,7 @@ impl DspNode for SFilter {
}); });
}, },
7 => { // Notch Hal Chamberlin SVF 7 => { // Notch Hal Chamberlin SVF
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, input, 16000.0, { ctx.nframes(), inp, out, freq, res, input, 16000.0, {
let (_high, notch) = let (_high, notch) =
process_hal_chamberlin_svf( process_hal_chamberlin_svf(
@ -256,12 +314,12 @@ impl DspNode for SFilter {
}); });
}, },
8 => { // Simper SVF Low Pass 8 => { // Simper SVF Low Pass
process_filter_fun!( process_filter_fun32!(
ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, { ctx.nframes(), inp, out, freq, res, 1.0, input, 22000.0, {
let (low, _band, _high) = let (low, _band, _high) =
process_simper_svf( process_simper_svf(
input, freq, res, self.israte, input, freq, res, self.israte,
&mut self.z, &mut self.y); &mut self.k, &mut self.h);
low low
}); });
}, },