iir: more generic math helpers, use core::intrinsics
This commit is contained in:
parent
ea3e343c39
commit
74349e5d68
|
@ -1,4 +1,4 @@
|
||||||
use core::ops::{Add, Mul};
|
use core::ops::{Add, Mul, Neg};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use core::f32;
|
use core::f32;
|
||||||
|
@ -8,16 +8,24 @@ use core::f32;
|
||||||
// `compiler-intrinsics`/llvm should have better (robust, universal, and
|
// `compiler-intrinsics`/llvm should have better (robust, universal, and
|
||||||
// faster) implementations.
|
// faster) implementations.
|
||||||
|
|
||||||
fn abs(x: f32) -> f32 {
|
fn abs<T>(x: T) -> T
|
||||||
if x >= 0. {
|
where
|
||||||
|
T: PartialOrd + Default + Neg<Output = T>,
|
||||||
|
{
|
||||||
|
if x >= T::default() {
|
||||||
x
|
x
|
||||||
} else {
|
} else {
|
||||||
-x
|
-x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copysign(x: f32, y: f32) -> f32 {
|
fn copysign<T>(x: T, y: T) -> T
|
||||||
if (x >= 0. && y >= 0.) || (x <= 0. && y <= 0.) {
|
where
|
||||||
|
T: PartialOrd + Default + Neg<Output = T>,
|
||||||
|
{
|
||||||
|
if (x >= T::default() && y >= T::default())
|
||||||
|
|| (x <= T::default() && y <= T::default())
|
||||||
|
{
|
||||||
x
|
x
|
||||||
} else {
|
} else {
|
||||||
-x
|
-x
|
||||||
|
@ -25,7 +33,10 @@ fn copysign(x: f32, y: f32) -> f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
fn max(x: f32, y: f32) -> f32 {
|
fn max<T>(x: T, y: T) -> T
|
||||||
|
where
|
||||||
|
T: PartialOrd,
|
||||||
|
{
|
||||||
if x > y {
|
if x > y {
|
||||||
x
|
x
|
||||||
} else {
|
} else {
|
||||||
|
@ -34,7 +45,10 @@ fn max(x: f32, y: f32) -> f32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "nightly"))]
|
#[cfg(not(feature = "nightly"))]
|
||||||
fn min(x: f32, y: f32) -> f32 {
|
fn min<T>(x: T, y: T) -> T
|
||||||
|
where
|
||||||
|
T: PartialOrd,
|
||||||
|
{
|
||||||
if x < y {
|
if x < y {
|
||||||
x
|
x
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,26 +58,12 @@ fn min(x: f32, y: f32) -> f32 {
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
fn max(x: f32, y: f32) -> f32 {
|
fn max(x: f32, y: f32) -> f32 {
|
||||||
let o: f32;
|
core::intrinsics::maxnumf32(x, y)
|
||||||
unsafe {
|
|
||||||
asm!("vmaxnm.f32 {}, {}, {}",
|
|
||||||
lateout(sreg) o, in(sreg) x, in(sreg) y,
|
|
||||||
options(pure, nomem, nostack, preserves_flags)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
o
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
fn min(x: f32, y: f32) -> f32 {
|
fn min(x: f32, y: f32) -> f32 {
|
||||||
let o: f32;
|
core::intrinsics::minnumf32(x, y)
|
||||||
unsafe {
|
|
||||||
asm!("vminnm.f32 {}, {}, {}",
|
|
||||||
lateout(sreg) o, in(sreg) x, in(sreg) y,
|
|
||||||
options(pure, nomem, nostack, preserves_flags)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
o
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply-accumulate vectors `x` and `a`.
|
// Multiply-accumulate vectors `x` and `a`.
|
||||||
|
@ -76,7 +76,7 @@ where
|
||||||
{
|
{
|
||||||
x.iter()
|
x.iter()
|
||||||
.zip(a)
|
.zip(a)
|
||||||
.map(|(&x, &a)| x * a)
|
.map(|(x, a)| *x * *a)
|
||||||
.fold(y0, |y, xa| y + xa)
|
.fold(y0, |y, xa| y + xa)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +84,10 @@ where
|
||||||
///
|
///
|
||||||
/// To represent the IIR state (input and output memory) during the filter update
|
/// 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)
|
/// 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
|
/// To represent the IIR coefficients, this contains the feed-forward
|
||||||
/// coefficients (b0, b1, b2) followd by the feed-back coefficients (a1, a2),
|
/// coefficients (b0, b1, b2) followd by the negated feed-back coefficients
|
||||||
/// all normalized such that a0 = 1.
|
/// (-a1, -a2), all five normalized such that a0 = 1.
|
||||||
pub type IIRState = [f32; 5];
|
pub type IIRState = [f32; 5];
|
||||||
|
|
||||||
/// IIR configuration.
|
/// IIR configuration.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![cfg_attr(feature = "nightly", feature(asm))]
|
#![cfg_attr(feature = "nightly", feature(asm, core_intrinsics))]
|
||||||
|
|
||||||
pub mod iir;
|
pub mod iir;
|
||||||
|
|
Loading…
Reference in New Issue