/*
For kick drums (or other single drum hits...)

This plugin splits the signal into 2 bands.
Only the highs get compressed.
You can mix in a bandpassed signal.

HOW TO START:
Set the dry fader to -48dB and
set the lows and bp to -12dB. (...which is -inf)
Set the split frequency while listening to the highs.
Add some compression to the highs.
Now mix the lows and the highs to your taste.
Finally add some bandpassed signal at a
certain frequency where it sounds best.

You can mix in some dry signal again, if you want.
*/

slider1:0<-30,0,0.1>Threshold (dB)
slider2:2<1,20,0.1>Ratio
slider3:3<1,20,0.1>Attack (ms)
slider4:100<20,1000,1>Release (ms)
slider5:50<10,100,1>Env Decay (ms)

slider8:120<50,250,1>(Low/High) Split Freq (Hz)
slider9:6000<400,8000,1>BP Freq (Hz)
slider10:0.8<0.5,1.5,0.01>BP Q

slider12:0<-48,12,1>Dry (dB)
slider13:-12<-12,24,1>Lows (dB)
slider14:-12<-12,24,1>(Comp) Highs (dB)
slider15:-12<-12,24,1>BP (dB)

slider17:0<-48,12,1>Output (dB)

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

@init
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
threshold = 10^(slider1/20);

transfer_A = (1/slider2)-1;
transfer_B = output * pow(threshold,-transfer_A);

attack = exp(-1/(slider3/1000*srate));
release = exp(-1/(slider4/1000*srate));
envelope_decay = exp(-1/(slider5/1000*srate));

vol1 = slider12 <= -48.0 ? 0.0 : 10^(slider12/20);
vol2 = slider13 <= -12.0 ? 0.0 : 10^(slider13/20);
vol4 = slider14 <= -12.0 ? 0.0 : 10^(slider14/20);
vol3 = slider15 <= -12.0 ? 0.0 : 10^(slider15/20);
vol5 = 10^(slider17/20);

// LP
fA = 2*$pi * min(slider8, 0.49 * srate) / srate;
qA =0.707;

w0A = fA;
cos_w0A = cos(w0A);
alphaA = sin(w0A) / (2*qA);

b1A = 1 - cos_w0A;
b0A = b2A = 0.5 * b1A;
a0A = 1 + alphaA;
a1A = -2 * cos_w0A;
a2A = 1 - alphaA;

a1A /= a0A;
a2A /= a0A;
b0A /= a0A;
b1A /= a0A;
b2A /= a0A;

// HP
fB = 2*$pi * min(slider8, 0.49 * srate) / srate;
qB =0.707;

w0B = fB;
cos_w0B = cos(w0B);
alphaB = sin(w0B) / (2*qB);

b1B = -1 - cos_w0B;
b0B = b2B = -0.5 * b1B;
a0B = 1 + alphaB;
a1B = -2 * cos_w0B;
a2B = 1 - alphaB;

a1B /= a0B;
a2B /= a0B;
b0B /= a0B;
b1B /= a0B;
b2B /= a0B;

// BP
fC = 2*$pi * min(slider9, 0.49 * srate) / srate;
qC =max(min(slider10,4),0.01);

w0C = fC;
alphaC = sin(w0C) / (2*qC);

b0C = alphaC;
b1C = 0;
b2C = -alphaC;
a0C = 1 + alphaC;
a1C = -2 * cos(w0C);
a2C = 1 - alphaC;

a1C /= a0C;
a2C /= a0C;
b0C /= a0C;
b1C /= a0C;
b2C /= a0C;

@sample
inA = spl0;
inB = spl1;

//Left LP
x2AA = x1AA;
x1AA = x0AA;
x0AA = inA;

y2AA = y1AA;
y1AA = y0AA;
y0AA = b0A*x0AA + b1A*x1AA + b2A*x2AA - a1A*y1AA - a2A*y2AA;

//Right LP
x2BA = x1BA;
x1BA = x0BA;
x0BA = inB;

y2BA = y1BA;
y1BA = y0BA;
y0BA = b0A*x0BA + b1A*x1BA + b2A*x2BA - a1A*y1BA - a2A*y2BA;

//Output LP
out0 = y0AA;
out1 = y0BA;

//Left HP
x2AB = x1AB;
x1AB = x0AB;
x0AB = inA;

y2AB = y1AB;
y1AB = y0AB;
y0AB = b0B*x0AB + b1B*x1AB + b2B*x2AB - a1B*y1AB - a2B*y2AB;

//Right HP
x2BB = x1BB;
x1BB = x0BB;
x0BB = inB;

y2BB = y1BB;
y1BB = y0BB;
y0BB = b0B*x0BB + b1B*x1BB + b2B*x2BB - a1B*y1BB - a2B*y2BB;

//Output HP
out2 = y0AB;
out3 = y0BB;

//Left BP
x2AC = x1AC;
x1AC = x0AC;
x0AC = inA;

y2AC = y1AC;
y1AC = y0AC;
y0AC = b0C*x0AC + b1C*x1AC + b2C*x2AC - a1C*y1AC - a2C*y2AC;

//Right BP
x2BC = x1BC;
x1BC = x0BC;
x0BC = inB;

y2BC = y1BC;
y1BC = y0BC;
y0BC = b0C*x0BC + b1C*x1BC + b2C*x2BC - a1C*y1BC - a2C*y2BC;

//Output BP
out4 = y0AC;
out5 = y0BC;

det = max(abs(out2),abs(out3));
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);

out6 = out2 * gain;
out7 = out3 * gain;

spl0 = (inA*vol1 + out0*vol2 + out4*vol3 + out6*vol4) * vol5;
spl1 = (inB*vol1 + out1*vol2 + out5*vol3 + out7*vol4) * vol5;

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);
