diff --git a/dsp/src/iir.rs b/dsp/src/iir.rs index 33d8fdf..c6f2100 100644 --- a/dsp/src/iir.rs +++ b/dsp/src/iir.rs @@ -1,4 +1,4 @@ -use core::ops::{Add, Mul}; +use core::ops::{Add, Mul, Neg}; use serde::{Deserialize, Serialize}; use core::f32; @@ -8,16 +8,24 @@ use core::f32; // `compiler-intrinsics`/llvm should have better (robust, universal, and // faster) implementations. -fn abs(x: f32) -> f32 { - if x >= 0. { +fn abs(x: T) -> T +where + T: PartialOrd + Default + Neg, +{ + if x >= T::default() { x } else { -x } } -fn copysign(x: f32, y: f32) -> f32 { - if (x >= 0. && y >= 0.) || (x <= 0. && y <= 0.) { +fn copysign(x: T, y: T) -> T +where + T: PartialOrd + Default + Neg, +{ + if (x >= T::default() && y >= T::default()) + || (x <= T::default() && y <= T::default()) + { x } else { -x @@ -25,7 +33,10 @@ fn copysign(x: f32, y: f32) -> f32 { } #[cfg(not(feature = "nightly"))] -fn max(x: f32, y: f32) -> f32 { +fn max(x: T, y: T) -> T +where + T: PartialOrd, +{ if x > y { x } else { @@ -34,7 +45,10 @@ fn max(x: f32, y: f32) -> f32 { } #[cfg(not(feature = "nightly"))] -fn min(x: f32, y: f32) -> f32 { +fn min(x: T, y: T) -> T +where + T: PartialOrd, +{ if x < y { x } else { @@ -44,26 +58,12 @@ fn min(x: f32, y: f32) -> f32 { #[cfg(feature = "nightly")] fn max(x: f32, y: f32) -> f32 { - let o: f32; - unsafe { - asm!("vmaxnm.f32 {}, {}, {}", - lateout(sreg) o, in(sreg) x, in(sreg) y, - options(pure, nomem, nostack, preserves_flags) - ); - } - o + core::intrinsics::maxnumf32(x, y) } #[cfg(feature = "nightly")] fn min(x: f32, y: f32) -> f32 { - let o: f32; - unsafe { - asm!("vminnm.f32 {}, {}, {}", - lateout(sreg) o, in(sreg) x, in(sreg) y, - options(pure, nomem, nostack, preserves_flags) - ); - } - o + core::intrinsics::minnumf32(x, y) } // Multiply-accumulate vectors `x` and `a`. @@ -76,7 +76,7 @@ where { x.iter() .zip(a) - .map(|(&x, &a)| x * a) + .map(|(x, a)| *x * *a) .fold(y0, |y, xa| y + xa) } @@ -84,10 +84,10 @@ where /// /// To represent the IIR state (input and output memory) during the filter update /// this contains the three inputs (x0, x1, x2) and the two outputs (y1, y2) -/// concatenated. +/// concatenated. Lower indices correspond to more recent samples. /// To represent the IIR coefficients, this contains the feed-forward -/// coefficients (b0, b1, b2) followd by the feed-back coefficients (a1, a2), -/// all normalized such that a0 = 1. +/// coefficients (b0, b1, b2) followd by the negated feed-back coefficients +/// (-a1, -a2), all five normalized such that a0 = 1. pub type IIRState = [f32; 5]; /// IIR configuration. diff --git a/dsp/src/lib.rs b/dsp/src/lib.rs index ac25d1e..b2acf34 100644 --- a/dsp/src/lib.rs +++ b/dsp/src/lib.rs @@ -1,4 +1,4 @@ #![no_std] -#![cfg_attr(feature = "nightly", feature(asm))] +#![cfg_attr(feature = "nightly", feature(asm, core_intrinsics))] pub mod iir;