Module dsp::sample_filter
streaming DSP as composable traits.
std/dsp's streaming filters share one shape: process() one sample, process_block() a buffer (out may alias in), reset() the state to silence. The traits below name each capability on its own and compose into the roles generic code asks for (trait composition: 'trait SampleFilter : SampleProcessor + BlockProcessor + Resettable {}' requires all three). The generic helpers after them are written once and ask only for what they use; each call is resolved at compile time (no dispatch at run time, so a generic wrapper around a hand-tuned method costs nothing).
SampleProcessor process(x): one sample in, one out
BlockProcessor process_block(in, out) (slices)
Resettable reset(): back to silence
SampleFilter SampleProcessor + BlockProcessor + Resettable:
double FirFilter, IirFilter, Biquad, CombFF, CombFB
float FirFilter32, IirFilter32, Biquad32,
CombFF32, CombFB32
Q8.24 FFirFilter, FIirFilter, FBiquad,
FCombFF, FCombFB
and FilterChain<S, A, B> of any two of one type
SampleGenerator next(): one sample out, no input: KarplusStrong,
KarplusStrong32, FKarplusStrong
One set of traits covers all three sample types. A trait is satisfied by method name, so the signatures below are written with double, and a float or Q8.24 (Fixed) filter conforms the same way; the helpers take the sample type as a parameter of their own (S), inferred from the buffers. Your own filter works with them (and with any generic<F: SampleFilter> code) as soon as it has the methods.
struct Biquad hp = Biquad::highpass(48000.0, 80.0, 0.7071);
struct Biquad lp = Biquad::lowpass(48000.0, 8000.0, 0.7071);
struct FilterChain<double, struct Biquad, struct Biquad> band =
FilterChain::of(hp, lp);
band.process_block(in, out); // band-limit a block (slices)
double h[64];
filter_impulse_response(&fir, h[0..64]); // h[i] = taps, then 0
The per-type process_block bodies with a fast path of their own (FIR's sliding dot products, the biquad's look-ahead recurrence) stay hand- written; the others are filter_process_each over process().
Structs
| FilterChain |
Traits
| SampleProcessor | |
| BlockProcessor | |
| SampleFilter | |
| SampleGenerator |
Functions
| sample_one | |
| filter_process_each | |
| filter_impulse_response | |
| filter_step_response | |
| generate_block |