slider1:-120<-120,0,0.1>|---------------- Gate Threshold (dB)
slider2:50<1,100,1>Hold (ms)
slider3:1<1,100,0.1>Fade-in (ms)
slider4:100<1,1000,1>Fade-out (ms)
slider5:0<-30,0,0.1>|----- Compressor Threshold (dB)
slider6:2<1,20,0.1>Ratio
slider7:3<1,20,0.1>Attack (ms)
slider8:100<20,1000,1>Release (ms)
slider9:50<10,100,1>Env Decay (ms)
slider10:0<-24,24,0.1>Output (dB)

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

@init
silentcnt=0;
seekv=1;
seekto=1;

output = 1;
transfer_A = 0;
transfer_B = 1;
gain = 1;
env = 0;

log2dB = 8.6858896380650365530225783783321;
db2log = 0.11512925464970228420089957273422;
gr_meter = 1;
gr_meter_decay = exp(1/(1*srate));

@slider
thresh = 10 ^ (slider1/20);
sillen = slider2*srate/1000;
fadeout = 1/pow(10,1/(srate*slider4/1000));
fadein = 1/pow(10,1/(srate*slider3/1000));

threshold = 10 ^ (slider5/20);
transfer_A = (1/slider6)-1;
transfer_B = output * pow(threshold,-transfer_A);

attack = exp(-1/(slider7/1000*srate));
release = exp(-1/(slider8/1000*srate));
envelope_decay = exp(-1/(slider9/1000*srate));

vol = 10^(slider10/20);

@sample
// compressor
inL = spl0;
inR = spl1;

det = max(abs(inL),abs(inR));
det += 0.000000000001;
env = det >= env ? det : det+envelope_decay*(env-det);
transfer_gain = env > threshold ? pow(env,transfer_A)*transfer_B:output;
gain = transfer_gain < gain ? transfer_gain+attack*(gain-transfer_gain) : transfer_gain+release*(gain-transfer_gain);

out0 = inL * gain;
out1 = inR * gain;

// gate
a = abs(out0) > thresh || abs(out1) > thresh;

a ? (
silentcnt=0;
seekto=1;
) : (
(silentcnt+=1) > sillen ?  seekto=0;
);

seekto > 0.5 ? ( // fading in
seekv=seekv*fadein + (1-fadein);
):( // fading out
seekv=seekv*fadeout;
);

spl0 = out0 * seekv * vol;
spl1 = out1 * seekv * vol;

gr = log(gain)*log2dB;
grv = exp(gr*db2log);
grv < gr_meter ? gr_meter=grv : ( gr_meter*=gr_meter_decay; gr_meter>1?gr_meter=1; );
grmin = min( min(gr,gr) , grmin);

@gfx 0 36
gfx_r=1; gfx_g=gfx_b=0; gfx_a=0.8;

meter_bot=21;
meter_h=min(gfx_h,gfx_h-4);
xscale=gfx_w*20/meter_bot;

gfx_y=0;
gfx_x=gfx_w + log10(gr_meter)*xscale;
gfx_rectto(gfx_w,meter_h);

gfx_r=gfx_g=gfx_b=1; gfx_a=0.6;

s2=sqrt(2)/2;
g = s2;
while(
gfx_x=gfx_w + log10(g)*xscale;
gfx_x >= 0 ? (
gfx_y=0;
gfx_lineto(gfx_x,meter_h,0);
gfx_y=meter_h-gfx_texth;
gfx_x+=2;
gfx_drawnumber(log10(g)*20,0);
gfx_drawchar($'d');
gfx_drawchar($'B');
);
g*=s2;
gfx_x >=0;
);

(mouse_cap) ? (grmin=0;);
gfx_x=2;
gfx_y=meter_h/2 - gfx_texth/2;
gfx_drawnumber(grmin,1);
