Declicking

UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Declicking

Post by UrbanCyborg »

If anyone who's done it would care to share, how did you go about dealing with the square-wave noise introduced by switching a signal on or off? Filtering? Wave modification? What? I've tried several routes, and am not having much luck coming up with anything that doesn't introduce more noise than it takes out.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Declicking

Post by ColinP »

Hi Reid,

After quite a lot of experimentation I settled on doing a fade in/out that lasts about 4 ms using a polynomial function. If you do it with a linear function you might need roughly twice that.

But it all depends on how much noise you can tolerate. Mathematically you need an infinitely long fade to remove all distortion.
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Declicking

Post by UrbanCyborg »

Well, that's reassuring, at least. My current attempt uses a linear ramp. I'm having trouble getting the ramp to start where it needs to, though. Button presses are handled in Notify(), where I set flags, but the actual handling is in ProcessSample(). Getting it wrong by even a sample means creating more noise, not less, and I'm not exactly sanguine about the chances of accurate timing between threads. I'm currently using a 1 ms ramp; I'll try longer. Thanks, Colin.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Declicking

Post by ColinP »

Hmm, I don't understand your point as presumably the ProcessSample() code won't do anything until the flag is set in Notify(). Yes there will be a jitter delay up to the Notify() timer duration but as long as ProcessSample() waits for the flag there shouldn't be any noise.

The problem with using a linear ramp is the discontinuity on start and end as there is instantaneous change rather than it being band-limited. Hence the need to have a much slower fade to attempt to mask this.

The following demonstrates what I mean...
declick.png
declick.png (43.98 KiB) Viewed 1555 times
In the interval [0,1] the linear function has nasty "kinks" at 0 and 1 while the cubic function gently accelerates and decelerates.

This particular polynomial function is well known in games and graphics programming and can be implemented very efficiently but I'll leave the details as a homework project as I don't want to give away too many tricks of the trade. ;)
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Declicking

Post by UrbanCyborg »

Yeah, I recognize the curve. Over the range from 0 to 1 it's sigmoid in character. I imagine other types of sigmoid would work here as well, although this one might be a bit cheaper to compute. Of course, I'm holding the ramp in a buffer, so it only gets computed once (and its reverse saved, as well, for spots where the signal stops, instead of starts). I was hoping to get by on the cheap, but you're right, the second-order C1 continuity is a definite plus.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Declicking

Post by ColinP »

These days LUTs are rarely a good idea because hitting the cache generally costs more than actually computing the function live, unless it's a really complex function and this polynomial only costs three multiplications and a subtraction if your algebra is up to scratch.
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Declicking

Post by ColinP »

I should mention that the approximate 4 ms I mentioned is the minimum fade time I found usable. It still produces a thud or a pop in many circumstances. To attenuate the noise more you might need a fade that lasts ten times longer than that. It depends on the application.

The thing is a tradeoff though as once you get above a certain amount of time it's no longer reallly acting as a switch as it begins to sound like a noticable fade.

I've been thinking a little more about what's happening in the frequency domain and one could maybe see the de-clicking as amplitude modulation that briefly generates sidebands to the content spectrum.

In effect what we end up with is something like a brief burst of ring modulation.

So the content we are trying to switch on and off is the carrier and the modulator is 0.5 / fadePeriod (when the modulator is strongly band-limited).

So with a fade period of 1 ms the modulatior is kind of like a 500 Hz sine wave so we'll get sidebands at +/- 500 Hz which will sound pretty unpleasant.

But if we increase the fade period to say 50 ms then the sidebands will be at +/- 10Hz and so the spectrum will be far less mangled.

As the fade period increases the modulation frequency tends to zero and the sidebands converge on the carrier so effectlively disappear.

I'm simplfying things here a bit but I think it makes some sense.
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Declicking

Post by UrbanCyborg »

That agrees with what I see on a spectrum analyzer. Switching on an un-declicked 125 Hz signal results in extra frequencies at around 8 KHz, declicking that I've tried via several different methods tends to spread that extra signal out quite a lot, as well as smearing the original signal in an area around 125 Hz.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Declicking

Post by UrbanCyborg »

Incidentally, you can also get that cubic in two multiplications and four additions. Which is more efficient, I dunno. Once the processors started doing on-the-fly optimizations, sometime around the x686, as I recall, any calculations you could do for clock cycles and latency went out the window, because you had no idea of what the CPU was going to do to your finely-crafted assembly code. I used to be good at that, had Agner Fog pretty well memorized, along with large swathes of the "secret" addendum to the CPU manuals ;) ; now, I don't even bother.

Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Declicking

Post by UrbanCyborg »

Here's the version I mentioned:

Code: Select all

    // Computes 3x**2 - 2x**3
    // Takes input in the range [0,1), outputs a cubic sigmoid in the same range
    // Smooth transitions at the endpoints
    private double Sigmoid(double input) {
        double squared = input   * input;
        double cubed   = squared * input;
        return squared + squared + squared - (cubed + cubed);
    }   // Sigmoid()
Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
Post Reply

Return to “Module Designer”