Skip to content

Fix for fixed point overflow in synthio #10288

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

gamblor21
Copy link
Member

Fix for #10286 and #10200.

There may still be more locations where fixed point could be handled better in synthio but this fix hits two big ones that I discovered so worth fixing those now.

Also refactored sat16 that will shift a fixed point result back into 16 bits out of audiofreeverb and into synthio to be used by any audio module that needs it. Potentially worth moving this to a generic "audiohelper" type module in the future in case someone builds without synthio but still wants audio effects.

@gamblor21
Copy link
Member Author

I updated the tests as this change breaks most of them. I looked and as far as I could tell it is small rounding differences due to how I fixed this issue. I also listened but would appreciate it if someone else can confirm that things sound right. The rounding changes were about 1 (for ints) or less then 0.0001 for floats so not large for audio.

@relic-se
Copy link

Potentially worth moving this to a generic "audiohelper" type module in the future in case someone builds without synthio but still wants audio effects.

Not that it's necessary for this PR, but would audiocore be a reasonable location in the future?

Copy link

@relic-se relic-se left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks clean so far. I haven't yet tested it, but I will extensively soon.

@@ -212,7 +213,7 @@ void synthio_biquad_filter_samples(mp_obj_t self_in, biquad_filter_state *st, in

for (size_t n = n_samples; n; --n, ++buffer) {
int32_t input = *buffer;
int32_t output = (b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))) >> BIQUAD_SHIFT;
int32_t output = synthio_sat16((b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))), 15);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be BIQUAD_SHIFT instead of 15.

@relic-se
Copy link

Just finished running tests. No more distortion across the board!

Now that we can push Q up to much higher values, I'm a bit disappointed that it doesn't appear to want to self-oscillate like you'd expect from an analog filter. After a bit of research, I was able to find some anecdotes about biquads not being able to self-oscillate without the help of additional processing (using an envelope follower controlling gain). For our purposes, I think we can live without it.

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

Successfully merging this pull request may close these issues.

2 participants