mirror of
https://github.com/airwindows/airwindows.git
synced 2026-05-15 06:05:55 -06:00
[GH-ISSUE #22] 'zippering' noise in a modulated environment, and what we did #18
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/airwindows#18
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @baconpaul on GitHub (Dec 4, 2020).
Original GitHub issue: https://github.com/airwindows/airwindows/issues/22
Hi Chris
This is not so much an issue as an observation. We are wrapping up our Surge 1.8 release candidate and our users love love love the Airwindows integration. Thank you so much for making the plugs open source.
Surge is an environment with lots of modulation and so I wanted to add a comment on how I integrated your effects and that modulation.
It seems almost all your effects assume parameters are constant over the block. Most of surge does not assume this. It basically takes control rate things (like parameters) and detects change and then does some equivalent of
param = param + dParam * samplewheredParam = (param_new - param_old ) / BLOCK_SIZE. It's not quite that dumb but its close in some places. Without this you get a real opportunity for 'zipper' noise (where you get high frequency aliasing because the params jump in tiny little square waves). Of course that linear interp has its own alias problems.So anyway to solve this when I integrated Airwindows in surge rather than passing a whole block to process, I divide my block into 8 and interpolate my params across that block. So basically instead of calling
setParam; processReplacing( data, 32)I callfor( i in 0..8 ) { setParam( p + dP ); processReplacing( data + i * 4, 4 ); }. This has the effect of having the parameter change more smoothly over a window. This comes at the cost of a bit of CPU because the standup/teardown code in processReplacing gets called more often.It was easy to make surge patches with modulation onto FX which demonstrated this and the above fix worked great so there's nothing to really 'do' here. But it occurred to me that modulating in a DAW could have the same problem. So I just wanted to kinda flag this to you, and also flag that of the ones we chose to integrate, one of the members of our team did a pretty exhaustive look for which params were impacted, which you can find here: https://github.com/surge-synthesizer/surge/issues/3315
Anyway like I said: no action required, just a way to let you know what we did. Please feel free to just close this issue of course. And thanks again for the great effects. They are part of a set of pretty awesome new Surge 1.8 features!
@airwindows commented on GitHub (Dec 4, 2020):
Sounds fine. If you're looking at the code, you can probably work out which things are assuming non-moving parameters, and which ones already have smoothing on them. For instance, PurestGain/PurestFade and some Console plugins, including the upcoming one, already 'chase' the parameters to avoid zipper noise, and some things (like delay buffers in things like reverbs) really can't chase parameters because it's not the discontinuous nature of the control input that makes the 'glitches': changing the size of a buffer is always going to make a noise even if it's just adding small gaps of silence.
The finest granularity is of course going sample-by-sample as in VCV Rack. I'm comfortable leaving many parameters un-smoothed for efficiency reasons, but you're absolutely right that when you modulate that throws a monkey wrench into things. By all means come up with workarounds: you might also want to implement something like 'gainchase' in Console5Channel, which doesn't incur the overhead of repeatedly invoking processReplacing, and smooths on a sample-by-sample basis. A danger area is when you can't 'snap' to the desired setting from a far-distant setting: some plugins will misbehave if they can't start up with the target value, for 'gainchase' it initializes to -90 and then upon reading the control, if the working setting is negative it automatically jumps to the target without smoothing.
@baconpaul commented on GitHub (Dec 4, 2020):
Yeah that sort of 'first time vs next time' flagging is the price you pay and what we did in a lot of surge builtins.
I've held the line on surge that we want to not change your DSP code - I figure I would only make it worse - which is why i externalized this stepping (but left it at 4 not 1).
Thanks for the inputs on ones where you've smoothed! Lemme close this now you've seen it :)