Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set a non-zero filter initial state ? #78

Closed
BenjaminNavarro opened this issue Feb 25, 2020 · 3 comments
Closed

How to set a non-zero filter initial state ? #78

BenjaminNavarro opened this issue Feb 25, 2020 · 3 comments
Milestone

Comments

@BenjaminNavarro
Copy link
Contributor

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.

@BenjaminNavarro BenjaminNavarro changed the title How to set a non-zero filter initial state How to set a non-zero filter initial state ? Feb 25, 2020
@dancazarin
Copy link
Member

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.

@slarew
Copy link
Contributor

slarew commented Mar 13, 2020

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.

@dancazarin dancazarin mentioned this issue Oct 13, 2023
@dancazarin dancazarin added this to the KFR 6 milestone Feb 2, 2024
@kfrlib kfrlib deleted a comment from user706 May 1, 2024
@kfrlib kfrlib deleted a comment from user706 May 1, 2024
@kfrlib kfrlib deleted a comment from user706 May 1, 2024
@dancazarin
Copy link
Member

The requested feature has been implemented in KFR 6. Refer to iir_state struct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants