pub struct SymFir<'a, T, const M: usize, const N: usize> { /* private fields */ }
Expand description
Symmetric FIR filter prototype.
§Generics
M
: number of taps, one-sided. The filter has effectively 2*M DSP tapsN
: state size: N = 2*M - 1 + {input/output}.len()
§Half band decimation/interpolation filters
Half-band filters (rate change of 2) and cascades of HBFs are implemented in
HbfDec
and HbfInt
etc.
The half-band filter has unique properties that make it preferable in many cases:
- only needs M multiplications (fused multiply accumulate) for 4*M taps
- HBF decimator stores less state than a generic FIR filter
- as a FIR filter has linear phase/flat group delay
- very small passband ripple and excellent stopband attenuation
- as a cascade of decimation/interpolation filters, the higher-rate filters need successively fewer taps, allowing the filtering to be dominated by only the highest rate filter with the fewest taps
- In a cascade of HBF the overall latency, group delay, and impulse response length are dominated by the lowest-rate filter which, due to its manageable transition band width (compared to single-stage filters) can be smaller, shorter, and faster.
- high dynamic range and inherent stability compared with an IIR filter
- can be combined with a CIC filter for non-power-of-two or even higher rate changes
The implementations here are all no_std
and no-alloc
.
They support (but don’t require) in-place filtering to reduce memory usage.
They unroll and optimize extremely well targetting current architectures,
e.g. requiring less than 4 instructions per input item for the full HbfDecCascade
on Skylake.
The filters are optimized for decent block sizes and perform best (i.e. with negligible
overhead) for blocks of 32 high-rate items or more, depending very much on architecture.
Implementations§
Source§impl<'a, T: Copy + Zero + Add + Mul<Output = T> + Sum, const M: usize, const N: usize> SymFir<'a, T, M, N>
impl<'a, T: Copy + Zero + Add + Mul<Output = T> + Sum, const M: usize, const N: usize> SymFir<'a, T, M, N>
Sourcepub fn new(taps: &'a [T; M]) -> Self
pub fn new(taps: &'a [T; M]) -> Self
Create a new SymFir
.
§Args
taps
: one-sided FIR coefficients, excluding center tap, oldest to one-before-center
Sourcepub fn buf_mut(&mut self) -> &mut [T]
pub fn buf_mut(&mut self) -> &mut [T]
Obtain a mutable reference to the input items buffer space.
Sourcepub fn get(&self) -> impl Iterator<Item = T> + '_
pub fn get(&self) -> impl Iterator<Item = T> + '_
Perform the FIR convolution and yield results iteratively.
Sourcepub fn keep_state(&mut self, offset: usize)
pub fn keep_state(&mut self, offset: usize)
Move items as new filter state.
§Args
offset
: Keep the2*M-1
items atoffset
as the new filter state.