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 preferrable 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 optimmize 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, expluding 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.
Trait Implementations§
impl<'a, T: Copy, const M: usize, const N: usize> Copy for SymFir<'a, T, M, N>
Auto Trait Implementations§
impl<'a, T, const M: usize, const N: usize> Freeze for SymFir<'a, T, M, N>where
T: Freeze,
impl<'a, T, const M: usize, const N: usize> RefUnwindSafe for SymFir<'a, T, M, N>where
T: RefUnwindSafe,
impl<'a, T, const M: usize, const N: usize> Send for SymFir<'a, T, M, N>
impl<'a, T, const M: usize, const N: usize> Sync for SymFir<'a, T, M, N>where
T: Sync,
impl<'a, T, const M: usize, const N: usize> Unpin for SymFir<'a, T, M, N>where
T: Unpin,
impl<'a, T, const M: usize, const N: usize> UnwindSafe for SymFir<'a, T, M, N>where
T: UnwindSafe + RefUnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)