Skip to content

Recovering from unstable biquad filters? #1841

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

Closed
rtoy opened this issue Mar 18, 2019 · 12 comments
Closed

Recovering from unstable biquad filters? #1841

rtoy opened this issue Mar 18, 2019 · 12 comments
Labels
Needs Edits Decision has been made, the issue can be fixed. https://speced.github.io/spec-maintenance/about/
Milestone

Comments

@rtoy
Copy link
Member

rtoy commented Mar 18, 2019

Describe the issue
In , there is a report where a test modulates the detune parameter so fast that it appears as if the biquad filter becomes unstable (or at least unbounded for the given input). What is happening is that the filter quickly goes to +/- infinity, which quickly becomes NaN. This propagates forever because the filter internal state is now just NaN.

If the filter parameters and connections are changed so that the filter is now stable, the output is still NaN because the internal state is NaN, no input can ever change that.

Do we need to do anything about this? It's easy to say that the state should be reset to zero in this case, but that seems weird too.

I'm leaning towards Garbage In-Garbage out. Don't do that.

@rtoy
Copy link
Member Author

rtoy commented Mar 21, 2019

Teleconf: Garbage in-garbage out. Add a note to the spec that unstable filters can be created and we won't do anything about it. Similar to how IIRFilterNodes allow you to create unstable filters.

rtoy added a commit to rtoy/web-audio-api that referenced this issue Mar 28, 2019
It's the developers responsbility to handle this.  The spec does not
require anything be done.

Also fixed one minor typo.
@rsimmons
Copy link

I'm in favor of reseting the internal state if it becomes NaN. The problem with "garbage in garbage out" is that we can't precisely define what "garbage" is. This reliably occurs with certain AR modulation.. but how do we know it won't also occur with modulation from fast envelopes? This could come up in a web-based synth if the end-user sent a fast LFO to the filter cutoff. It would be extremely annoying for devs to have to add code to detect and correct for this (recreating nodes, etc.), so it seems better to fix the implementation.

@rtoy
Copy link
Member Author

rtoy commented Apr 1, 2019

I sympathize with your position, I just don't really know what to do. By "garbage-in/garbage out", I meant that the spec shouldn't try to determine the user's intent. If you specify something, then it happens. You want unstable IIRFilters? You can have them. Unstable biquads? Go for it; we won't stop you.

Resetting the state when NaN occurs just changes the problem from the graph going silent to the graph producing momentary silence (until the state is reset), then starting over with a new effect until it blows up again. In either case, it will be hard to determine what went wrong.

The main advantage of resetting the state is that the biquad could recover if you somehow magically changed the automations or audio input so as not to make it unstable. But you wouldn't know why it suddenly sounds good again. But maybe that's a good enough reason to reset. (But then what about IIRs? We should be consistent here.)

@rtoy rtoy added the Needs Discussion The issue needs more discussion before it can be fixed. label Apr 1, 2019
@hoch hoch added Needs Edits Decision has been made, the issue can be fixed. https://speced.github.io/spec-maintenance/about/ and removed Needs Discussion The issue needs more discussion before it can be fixed. labels Apr 11, 2019
@hoch
Copy link
Member

hoch commented Apr 11, 2019

Conclusion from Teleconf: We're going to add an informative note saying UA may warn users when a filter becomes unstable and starts producing NaN.

@hoch hoch reopened this Apr 11, 2019
rtoy added a commit to rtoy/web-audio-api that referenced this issue Apr 15, 2019
Add a note for both the BiquadFilterNode and the IIRFilterNode that
the UA may producing a warning if the filter state contains NaN.  This
is usually indicative of an unstable filter (but not always).
@rtoy rtoy added this to the Web Audio V1 milestone Apr 15, 2019
@rtoy rtoy closed this as completed in 1f50ed7 Apr 16, 2019
@rtoy
Copy link
Member Author

rtoy commented Apr 16, 2019

Just to add a little more detail on the conclusion. Basically no matter what action is taken the result will be hard for the developer to understand. Going silent due to NaN is hard to understand. Producing silence and then resetting the state to produce output is equally hard to understand. So the best course seems to be just producing a warning message to let the developer know that NaN has occurred in the state of the filter.

@adenflorian
Copy link

Is their a guaranteed way to prevent a biquad filter from becoming unstable, besides not automating the parameters?

If no, then that means our only option is to recover from an unstable filter, which first requires us to be able to detect when a filter is unstable, and then I believe we have to replace the filter with a new one?

I'm not trying to change the decision, just looking for guidance on what we're supposed to do.

It is the developers responsibility to manage this.

I guess I'm asking, how do we manage this?

@rtoy
Copy link
Member Author

rtoy commented Oct 18, 2019

I think k-rate automation is ok. But maybe that's because no one has come up with an automation and corresponding input that causes unbounded output.

Yes, currently it's basically up to you to detect that the output of the filter is infinity or NaN and then replace the filter. However, I wouldn't be opposed to adding, say, a resetState() method to reset the internal filter state. Might be useful too for other nodes with internal state.

@adenflorian
Copy link

resetState() sounds nice, and maybe also a filterunstable event that we can add a listener to?
Like filter.addEventListener('filterunstable', () => filter.resetState())

@rtoy
Copy link
Member Author

rtoy commented Oct 18, 2019

Determining if the filter is unstable is tricky. Chrome prints a console warning if the state has NaN in it, but that doesn't mean the filter is unstable. You can get that warning by feeding in NaN to a fixed biquad. Or maybe even by feeding a (very large) amplitude signal into the filter.

@yishengjiang99
Copy link

I reproduced this with much less dramatic repo steps..

@rtoy
Copy link
Member Author

rtoy commented Apr 22, 2020

Do you have a repro case you could share with us? Are you proposing the spec should be changed in some way?

@yishengjiang99
Copy link

yishengjiang99 commented Apr 22, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Edits Decision has been made, the issue can be fixed. https://speced.github.io/spec-maintenance/about/
Projects
None yet
Development

No branches or pull requests

5 participants