Multi-channel Audio Filtering¶
audio_filter applies a stateful FIR, IIR, or convolution filter independently to every channel of planar audio_data_planar. It owns one filter instance per channel, so channel histories remain isolated while streaming audio blocks are processed.
Include <kfr/audio.hpp> for the audio filtering API.
Creating a filter¶
Use the fir, iir, or convolution factory and pass the number of channels to process. Every factory initializes an equivalent independent filter for each channel. The channel count must be greater than zero and no greater than max_audio_channels.
audio_filter filter = audio_filter::fir(audio.channels, taps);
filter.apply(audio);
The available factories are:
| Factory | Per-channel filter |
|---|---|
| audio_filter::fir | FIR filter configured from fir_params taps. |
| audio_filter::iir | IIR filter configured from dynamic IIR parameters or one biquad_section. |
| audio_filter::convolution | Streaming overlap-add FFT convolution configured with an impulse response and optional block size. |
Applying and resetting¶
.apply(audio_data_planar &) processes planar data in place. .apply(audio_data_planar &, const audio_data_planar &) writes to a distinct planar destination; source and destination must have the same frame count. In either case, both buffers must have exactly the channel count used to construct the filter.
Like a scalar runtime filter, audio_filter retains state between calls. Keep the same object for successive blocks of the same stream. Call .reset() before starting an unrelated stream to reset the state of every channel filter.
filter.apply(block1);
filter.apply(output, block2); // continues each channel's state from block1
filter.reset();
audio_filter requires planar audio. Convert interleaved input before filtering and convert it back afterward when required by an encoder or audio device:
audio_data_planar planar = interleaved;
audio_filter filter = audio_filter::fir(2, univector<fbase>{ 1.0 });
filter.apply(planar);
interleaved = planar;