Looking for a noise gate algorithm

Hello,

I’m looking for a noise gate algorithm, similar to how Logic Pro’s noise gate works. For example removing the snare and hi-hat bleed from a kick drum mic. If anyone can share or point me in the right direction, I’d appreciate it!

Thanks!

You can get Noise Gates implemented as Pure Data ‘patches’,
for example:

and there is a more or less doable way to convert most of them to C, see

There might be easier ways, I haven’t done this.

1 Like

Cool, I’ll check it out, thanks!

also - there is a pd2dsy utility to make things easier - see the Pure Data topic under ‘integrations’ in this forum.

1 Like

Hello again,

So I found a noise gate example, in a Dynamics processing patch, from the Max audio app by Cycling '74.

I started with the multi effect pod example and added the noise gate as a 4th effect in the following function

Some notes…

  • Similar to the other effect functions I pass in/out audio signals
  • Starting with the patch from the Dynamics processing example in Max
  • More info about a noise gate for ref…
    • Similar to a compressor with an envelope follower and a threshold

    • But instead of reducing the gain of the audio energy that exceeds the threshold, a gate attenuates that fall below the threshold.

    • Instead of a ratio, the gate has a knee which is proportional of the threshold within which the audio is attenuated rather than cut altogether

    • with default settings: attack = 1, decay = 20, threshold = .5, knee = .75…

      • sound above 0.5 are left alone (i.e. gain = 1, no change)
      • sound below 0.5 and above 0.375 (the threshold * the knee) are scaled between 0 and 1
      • sound below 0.375 are gated out (i.e. g = 0, no sound)
    • gate formula g = (e-(tk)) / (t-(tk))
      where:

      • g = gain 0 to 1
      • e = envelope signal
      • t = threshold
      • k = knee

I broke down the steps, from the patch, as follows…

void GetNoiseGateSample(float &outl, float &outr, float inl, float inr)
{
// 1. attack param X 44.1 (sample rate?)
//float attackl = attackNg * sample_rate; // attackNg is the parameter the user can change
//float attackr = attackNg * sample_rate;

// 2. decay param X 44.1 (sample rate?)
//float decayl = decayNg * sample_rate;   // decayNg is the parameter the user can change
//float decayr = decayNg * sample_rate;

// 3. convert incoming signal to abs value
float inlAbs = fabsf(inl);               // convert inl float to a single precision version
float inrAbs = fabsf(inr);

// 4. smooth incoming signal: incoming signal (step 3), ramp up attack param (step 1), ramp down decay param (step 2)
float rampSmoothl = inlAbs;    // don't know the equivalent in DaisySP
float rampSmoothr = inrAbs;    

// 5. convert threshold param into a signal (doesn't seem to change the value)
// is this needed?

// 6. convert knee param into a signal (doesn't seem to change the value)
// is this needed?

// 7. multiply threshold (step 5) X knee (step 6)
float thresXknee = thresholdNg * kneeNg;

// 8. subtract threshold (step 5) - threshold x knee (step 7)
float thresDelta = thresholdNg - (thresXknee);

// 9. subtract rampsmooth (step 4) - threshold x knee (step 7)
float rampSmoothDeltal = rampSmoothl - thresXknee;  // from step 4 don't know the equivalent in DaisySP
float rampSmoothDeltar = rampSmoothr - thresXknee;  

// 10. divide rampsmooth (step 9) / threshold result (step 8)
float preclampl = rampSmoothDeltal / thresDelta;
float preclampr = rampSmoothDeltar / thresDelta;

// 11. clamp result of (step 10) range 0 to 1
float gainl = clip(preclampl,0.0f,1.0f);
float gainr = clip(preclampr,0.0f,1.0f);

// 12. out signal = camp (step 11) * incoming signal 
outl = gainl * inl;
outr = gainr * inr;

}

The cool thing, minus some distortion at certain settings, the gate is working. I have an audio sample from my kick drum mic which contains snare and hi-hat bleed, adjusting k1 - threshold and k2 - knee I can remove the bleed. But I do have a few questions…

  1. the gate example uses the term envelope signal, do the in/out vars from the pod meet this requirement as is, or is there additional processing I have to do, to convert them into an envelope signal?

  2. step 1 & 2 multiply the attack and decay parameters by 44.1, the output is used in step 4, in a RampSmooth function (unique to max app?) that takes 3 inputs, the incoming signal, the attack as a ramp up value and the decay as a ramp down value. The ref states the func smooths an incoming signal, ramp up = the number of samples to ramp up, ramp down = the number of samples to ramp down. So is there an equivalent in DaisySP or a way to achieve this in Daisy?

  3. step 5&6 use a max node to convert the threshold and knee values into a signal format, for later use, it’s unclear to me if I have to do the same, looking at examples like the compressor I don’t think so, but?

  4. lastly, anything else that seems wonky.

Apologies for the wall of text :slight_smile: any help or thoughts would be appreciated, thanks!

While it’s not a simple one off noise gate - I wrote this a while back - and does work really well as a noise gate!

The one I’ve written is very similar to the dynamics processor you’ve posted. It’s a classic way to get high quality gating without the snappy signal cut off - it’s a really great way to do it. And you can use the core code to do other freaky fun stuff.

You could also smooth the knee to reduce the distortion when the waveform crosses the threshold. Just add the following between steps 11 and 12:

auto sq = [] (float x) { return x * x; };
gainl = 1 - sq (1 - gainl);
gainr = 1 - sq (1 - gainr);

Graph

Nice, thank you that helps!