Nyquist code with the opposite of the Compressor effect

Noisegate.ny (8.56 KB)
I am compiling some music in which I want to leave the peak amplitude as is, but reduce the amplitude of lower volume sounds in order to create a strong Marcato sound with a sharp attack and a tapering dynamic. I would want something that is opposite the Compressor function. I looked at the Noise Gate function and thought I could replace the {;control level-red"Level reduction" real “db” -12 -100 0} slider with a variable level reduction based on a formula similar to the following non-nyquist code:

level percent change = ((current level - peak level)/peak level)
if (level percent change < 1, then new level=current level*level percent change, else new level=current level)

Below is an example of the calculation:
current level % change
current level peak level - peak level of peak new level
-4 -3 -1 300% -4
-6 -3 -3 100% -6
-7 -3 -4 75% -9.33
-8 -3 -5 60% -13.33
etc.

Thanks for any help you might have to offer.

That’s called an “expander”.
A compressor reduces the range between loud and quiet sounds (compresses the “dynamic range”), either by lowering peaks or by raising quiet parts.
An expander increases the range between loud and quiet sounds (expands the “dynamic range”), either by raising peaks or by lowering quiet parts.

The core function in the audio processing of this effect is the “gate” function at line 213:

(gate gatefollow lookahead risetime falltime  floor threshold)

“gatefollow” is a copy of the input signal that has passed through a high pass filter (to remove DC offset and low frequency rumble), and been converted to mono (if it was a stereo track).

The GATE function is described in the manual here: Nyquist Functions

(gate sound lookahead risetime falltime floor threshold) > > [LISP]
Generate an exponential rise and decay intended for noise gate implementation. The decay starts when the signal drops below threshold and stays there for longer than lookahead (a FLONUM in seconds). (The signal begins to drop when the signal crosses threshold, not after lookahead.) Decay continues until the value reaches floor (a FLONUM), at which point the decay stops and the output value is held constant. Either during the decay or after the floor is reached, if the signal goes above threshold, then the ouptut value will rise to unity (1.0) at the point the signal crosses the threshold. Because of internal lookahead, the signal actually begins to rise before the signal crosses threshold. The rise is a constant-rate exponential and set so that a rise from floor to unity occurs in risetime. Similary, the fall is a constant-rate exponential such that a fall from unity to floor takes falltime.

The plug-in modifies the behaviour of GATE to give the function GATE-S.

To strip down the NOISEGATE function to its basics:

(defun noisegate (s-in gatefollow lookahead risetime falltime floor threshold Hz)
  (mult s-in
    (gate gatefollow lookahead risetime falltime  floor threshold)))

However, there’s a problem that the GATE function can create very high gain in some circumstances, which will cause unwanted level boost.
To prevent that from happening, the output from the GATE function needs to be pegged to a maximum level of 1.0 (unity gain). We can do that by clipping the output from GATE:

(defun noisegate (s-in gatefollow lookahead risetime falltime floor threshold Hz)
  (mult s-in
    (clip (gate gatefollow lookahead risetime falltime  floor threshold) 1.0)))

Beyond that, you can modify the gain envelope any way you like.