26 releases (10 stable)
Uses new Rust 2024
new 1.3.0 | Apr 4, 2025 |
---|---|
1.2.3 | Mar 31, 2025 |
1.0.8 | Aug 27, 2024 |
0.6.9 | Jan 21, 2024 |
0.5.0 | Dec 15, 2022 |
#40 in Audio
779 downloads per month
Used in saturation
485KB
12K
SLoC
real_time_fir_iir_filters
Ever needed a low pass filter for your VST? This crate has a wide selection of filters for real-time usage. It's designed to have as little runtime overhead as possible.
How does it work?
Everything that can be computed at compile-time, will be, and the filter coefficients will be cached as well.
I then use the following algorithm to process the signal with as few steps as possible given the filter's coefficients:
(The figure is from: Alan V. Oppenheimer & Ronald W. Schafer - Discrete-Time Signal Processing)
Example
use core::f64::consts::TAU;
use real_time_fir_iir_filters::{
conf::LowPass,
param::OmegaEpsilonXi,
rtf::Rtf,
filters::iir::second::SecondOrderEllipticFilter
};
// Initialize a 2. order elliptic low-pass filter at 440Hz
let mut filter = SecondOrderEllipticFilter::new::<LowPass>(
OmegaEpsilonXi {
omega: 440.0*TAU,
epsilon: 0.5,
xi: 1.5
}
);
const N: usize = 10;
const RATE: f64 = 8000.0;
{
// Unit impulse
let mut imp_resp = [0.0; N];
imp_resp[0] = 1.0;
// Apply filter to imp_resp
for x in &mut imp_resp
{
[*x] = filter.filter(RATE, *x);
}
// Prints the impulse response of the filter.
println!("h[n] = {:?}", imp_resp);
}
// Resets internal state of filter to zero
filter.reset();
{
// Generate frequency response for ω ∈ [0, 2π)
let freq_resp = core::array::from_fn::<_, N, _>(|i| {
let omega = i as f64/N as f64*TAU;
filter.frequency_response(RATE, omega)
});
println!("H = {:?}", freq_resp);
}
Available filters
Order | Filter | Parameterization | Configuration |
---|---|---|---|
1 | FirstOrderAllPassFilter |
Tau |
AllPass |
1 | FirstOrderFilter |
Omega RC LR |
LowPass HighPass |
1 | FirstOrderLRFilter |
LR |
LowPass HighPass |
1 | FirstOrderRCFilter |
RC |
LowPass HighPass |
1 | PIFilter |
PI |
- |
2 | PIDFilter |
PI PID |
- |
2 | SecondOrderButterworthFilter |
Omega |
LowPass Peak HighPass |
2 | SecondOrderChebyshev1Filter |
Omega OmegaEpsilon |
LowPass HighPass |
2 | SecondOrderChebyshev2Filter |
Omega OmegaEpsilon |
LowPass HighPass |
2 | SecondOrderEllipticFilter |
Omega OmegaEpsilon OmegaEpsilonXi |
LowPass HighPass |
2 | SecondOrderFilter |
Omega OmegaZeta |
LowPass Peak HighPass |
2 | SecondOrderRCFilter |
RC RC2 |
LowPass BandPass<1> BandPass<2> HighPass |
2 | SecondOrderRLCFilter |
RC LR RLC |
LowPass BandStop BandPass HighPass |
2 | SecondOrderSallenKeyFilter |
RC2SallenKey RC2GSallenKey |
LowPass BandPass<1> BandPass<2> HighPass |
3 | ThirdOrderButterworthFilter |
Omega |
LowPass Peak<1> Peak<2> HighPass |
3 | ThirdOrderFilter |
Omega OmegaZeta Omega2Zeta |
LowPass Peak<1> Peak<2> HighPass |
3 | ThirdOrderSallenKeyFilter |
RC RC2SallenKey RC2GSallenKey RC3SallenKey RC3GSallenKey |
LowPass BandPass<1> BandPass<2> BandPass<3> BandPass<4> BandPass<5> BandPass<6> HighPass |
4 | WahFilter |
CrybabyGCB95 VoxV847 ColorsoundWow |
- |
...and more to come!
Adding your own filter
You can also implement your own filter, by using the macro def_rtf!
. See how i did it with the other filters for an example on how to use the macro.
Dependencies
~1–1.6MB
~32K SLoC