int_iir: use taylor for lowpass
This commit is contained in:
parent
7b9fc3b2b3
commit
d1f41b3ad5
@ -1,4 +1,4 @@
|
|||||||
use super::cossin;
|
use core::f64::consts::PI;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Generic vector for integer IIR filter.
|
/// Generic vector for integer IIR filter.
|
||||||
@ -13,16 +13,19 @@ impl IIRState {
|
|||||||
///
|
///
|
||||||
/// # Args
|
/// # Args
|
||||||
/// * `f` - Corner frequency, or 3dB cutoff frequency (in units of sample rate).
|
/// * `f` - Corner frequency, or 3dB cutoff frequency (in units of sample rate).
|
||||||
|
/// This is only accurate for low corner frequencies less than ~0.01.
|
||||||
/// * `q` - Quality factor (1/sqrt(2) for critical).
|
/// * `q` - Quality factor (1/sqrt(2) for critical).
|
||||||
/// * `k` - DC gain.
|
/// * `k` - DC gain.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// 2nd-order IIR filter coefficients in the form [b0,b1,b2,a1,a2]. a0 is set to -1.
|
/// 2nd-order IIR filter coefficients in the form [b0,b1,b2,a1,a2]. a0 is set to -1.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
pub fn lowpass(f: f64, q: f64, k: f64) -> IIRState {
|
pub fn lowpass(f: f64, q: f64, k: f64) -> IIRState {
|
||||||
let scale = (1i64 << 32) as f64;
|
// 3rd order Taylor approximation of sin and cos.
|
||||||
let fcossin = cossin((f * scale) as u32 as i32);
|
let f = f * 2. * PI;
|
||||||
let fcos = fcossin.0 as f64 / scale;
|
let fsin = f - f * f * f / 6.;
|
||||||
let fsin = fcossin.1 as f64 / scale;
|
let fcos = 1. - f * f / 2.;
|
||||||
let alpha = fsin / (2. * q);
|
let alpha = fsin / (2. * q);
|
||||||
// IIR uses Q2.30 fixed point
|
// IIR uses Q2.30 fixed point
|
||||||
let a0 = (1. + alpha) / (1 << IIR::SHIFT) as f64;
|
let a0 = (1. + alpha) / (1 << IIR::SHIFT) as f64;
|
||||||
@ -88,3 +91,14 @@ impl IIR {
|
|||||||
y0
|
y0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::IIRState;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lowpass_gen() {
|
||||||
|
let ba = IIRState::lowpass(1e-3, 1. / 2f64.sqrt(), 2.);
|
||||||
|
println!("{:?}", ba.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user