-
Notifications
You must be signed in to change notification settings - Fork 1.3k
synthio filters glitch at certain frequencies with Q > 1.41 #10200
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
Comments
Took a quick look, the waveform (in Audacity) looks like a overflow error. Quickly traced it back and in:
there is a likely overflow error (int32_t * int16_t into a int32_t) that Jeff noticed when we were discussing fixed point. I think this is the same error that was causing some random distortion I was getting with louder volumes and multiple voices. |
That makes sense. At higher resonance, you can get large volume peaks. I think some other filter emulations handle this by having a rate-limiter or some other cheap way to "soft-saturate" the output. I also hear distortion at times with many voices that I bet it's due to this. So if we find a good cheap fixed-point saturation algorithm, maybe we put it in |
I use one already in Reverb so when I have a moment I'm going to look through |
I've not looked, but it seems that whatever """ .... set up audio system including a mixer and synth """
filter1 = audiofilters.Filter(buffer_size=1024,
channel_count=CHANNEL_COUNT,
sample_rate=SAMPLE_RATE,
mix=1.0)
filter1.filter = synthio.Biquad(synthio.FilterMode.LOW_PASS,
frequency=200, Q=1.5)
mixer.voice[0].play(filter1)
filter1.play(synth)
midi_notes = [ 49, # glitch near 170 & 150 Hz
37, # loud near 100, 70, & 60 Hz
36, # loud near 70 & 60 Hz
42, # loud near 100 Hz
47, # loud near 120 Hz
]
while True:
for n in midi_notes:
midi_note_f = synthio.midi_to_hz(n)
note = synthio.Note(midi_note_f)
synth.press(note)
for f in range(21): # modulate the filter down by hand to find glitches
filter_freq = 200 - (10*f)
print("Q: %.2f filter freq: %3d note freq: %3.2f" %
(filter1.filter.Q, filter_freq, midi_note_f))
filter1.filter.frequency = filter_freq
time.sleep(0.3)
synth.release(note) |
|
Thank you for researching into this, @todbot! I think all of us synthio folks have been aware of this problem for a while. I'd love to push the filter harder, but it doesn't take long to run into this error. I'm sure that |
Oh my goodness, yes! Thank you. The #10288 patch makes the filter distortion non-existent! Much easier to do chords other other multi-note stuff now too. |
Fixed by #10288 |
CircuitPython version and board name
Code/REPL
Behavior
When
synthio.BlockBiquad
is set to certain frequencies with Q>1.41, strange oscillations / "glitches" occur that should not. In general it seems to be around the pitch of the playing note and lower.Description
Here's a video showing the above code running on a Pico2 RP2350 driving an I2S DAC.
The behavior is the same on a Pico RP2040 with I2S DAC. The behavior is also the same with
PWMOut
.This behavior has existed since
synthio
has had filters, but withBlockBiquad
it's more noticeable because we can easily modulate the filter frequency.synthio_filter_glitch.mp4
Additional information
No response
The text was updated successfully, but these errors were encountered: