Closed BenjaminNavarro closed 4 months ago
For FIR filters, you can fill fir_state
with values, pass it to fir
function with placeholder, then convert to filter.
fir_state<float> state;
// fill state with taps and delay line, set delayline_cursor = 0
auto expr = fir(state, placeholder()); // construct expression without data source
expression_filter<float> filter = to_filter(expr); // convert to filter
// use filter.apply(...)
For biquad filters (and IIR) you can change internal state of expression_biquads
after constructing biquad expression but before passing any data to it. You can convert biquad expression using to_filter
too.
More convenient and universal method to set initial state would be good for future versions.
I too recently ran into this issue of setting a non-zero initial filter state. My solution was as @dlevin256 proposed. Namely, I fill the FIR state object's delay line with my past samples and then I pass the initialized state to the fir()
expression. I stream
// At program startup, initilize fir_state with filter taps.
fir_state my_fir_state(taps);
// Initialize filter state when necessary (e.g. discontinuous input)
my_fir_state.delayline.ringbuf_write(my_fir_state.delayline_cursor, initial_state.data(), initial_state.size());
// Filter input (taking absolute value of filter output as an example) with initialized delayline state.
filtered_output = abs(fir(my_filter_state, input));
Formally documenting these technique, perhaps with a convenience method to initialize the delay line, would be nice.
The requested feature has been implemented in KFR 6. Refer to iir_state
struct.
Is it possible to force the initial value of a filter to be non-zero? I couldn't find a way to do it with the current API.
It's a nice thing to do when, for instance, you low pass a signal having a large offset since it allows to skip the possibly long convergence.