// limits above threshold and
// expands (downward) below -30dB

slider1:0<-30,0,0.1>Threshold (dB)
slider2:750<1,1000,1>Release (ms)
slider3:0<0,1,1{envelope 1,envelope 2}>Mode
slider4:0<-24,24,0.1>Output (dB)

in_pin:L in
in_pin:R in
out_pin:L out
out_pin:R out

@init
CBSZ = 882; // 0.02*srate
_envelope = 0;

i=0;
while(i<CBSZ) ? (
i+=1;
_inq[i] = 0;
);

@slider
_threshold = 10^(slider1 / 20);
_release = pow(0.01, 1 / (slider2 * 0.001 * srate));
_mode = slider3;
_output = 10^(slider4 / 20);

@sample
inL = spl0;
inR = spl1;
val = max(abs(inL),abs(inR));
val += 0.000000000001;

// do RMS
oldInput2 = _inq[_fp];
val2 = val * val;
_inq[_fp] = val2;
_fp = (_fp + 1) % CBSZ;
_total += val2;
_total -= oldInput2;
rms = sqrt(_total / CBSZ);

_mode ? (
// build that fast attack slow release envelope
_envelope = (rms >= _envelope) ? (
_envelope = rms;
):(
_envelope = rms +_release*(_envelope-rms);
);
):(
// build that fast attack slow release envelope
(rms > _envelope) ? (
_envelope = rms;
):(
_envelope *= _release;
);
);

// do adaptive gain
gain = 1;
(_envelope > _threshold) ? (
gain = _threshold / _envelope;
):
(_envelope < 0.03) ? (
gain = _envelope / 0.03;
//):(
//gain = 1;
);

spl0 = inL * gain * _output;
spl1 = inR * gain * _output;
