slider1:1<0.1,10,0.1>Drive
slider2:1<-10,10,0.1>Blend
slider3:0<-24,24,0.1>Input (dB)
slider4:0<-24,24,0.1>Output (dB)
slider5:0<0,1,1{Mono,Stereo}>Mode

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

@init
m1 = m0 = 0;

prev_med = 0;
prev_out = 0;
prev_med0 = 0;
prev_out0 = 0;
prev_med1 = 0;
prev_out1 = 0;

rdrive = 0;
rbdr = 0;
kpa = 0;
kpb = 0;
kna = 0;
knb = 0;
ap = 0;
an = 0;
imr = 0;
kc = 0;
srct = 0;
sq = 0;
pwrq = 0;

// These are out of band to force param recalc upon first run
prev_drive = -1;
prev_blend = -11;

EPS = 0.000000001;
function M(x) (
((x > EPS) || (x < -EPS)) ? x=x : x=0;
);
function D(x) (
(x > EPS) ? x=sqrt(x) : (x < -EPS) ? x=sqrt(-x) : x=0;
);

function tanh(x) (
x = exp(2*x);
(x-1) / (x+1);
);

@slider
drive = slider1;
blend = slider2;
input = 10^(slider3/20);
output = 10^(slider4/20);
mode = slider5;

((prev_drive != drive) || (prev_blend != blend)) ? (
rdrive = 12 / drive;
rbdr = rdrive / (10.5 - blend) * 780 / 33;
kpa = D(2 * (rdrive*rdrive) - 1) + 1;
kpb = (2 - kpa) / 2;
ap = ((rdrive*rdrive) - kpa + 1) / 2;
kc = kpa / D(2 * D(2 * (rdrive*rdrive) - 1) - 2 * rdrive*rdrive);

srct = (0.1 * srate) / (0.1 * srate + 1);
sq = kc*kc + 1;
knb = -1 * rbdr / D(sq);
kna = 2 * kc * rbdr / D(sq);
an = rbdr*rbdr / sq;
imr = 2 * knb + D(2 * kna + 4 * an - 1);
pwrq = 2 / (imr + 1);

prev_drive = drive;
prev_blend = blend;
);

@sample
mode==0 ? (
in = tanh((spl0+spl1) * 0.5 * input);

prev_med = prev_med;
prev_out = prev_out;

(in >= 0) ? (
med = (D(ap + in * (kpa - in)) + kpb) * pwrq;
):(
med = (D(an - in * (kna + in)) + knb) * pwrq * -1;
);

out = srct * (med - prev_med + prev_out);

(out < -1) ? out = -1;

spl1 = spl0 = out * output;

prev_med = M(med);
prev_out = M(out);
);

mode==1 ? (
in0 = tanh(spl0*input);
in1 = tanh(spl1*input);

//left
prev_med0 = prev_med0;
prev_out0 = prev_out0;

(in0 >= 0) ? (
med0 = (D(ap + in0 * (kpa - in0)) + kpb) * pwrq;
):(
med0 = (D(an - in0 * (kna + in0)) + knb) * pwrq * -1;
);

out0 = srct * (med0 - prev_med0 + prev_out0);

(out0 < -1) ? out0 = -1;

spl0 = out0 * output;

prev_med0 = M(med0);
prev_out0 = M(out0);

//right
prev_med1 = prev_med1;
prev_out1 = prev_out1;

(in1 >= 0) ? (
med1 = (D(ap + in1 * (kpa - in1)) + kpb) * pwrq;
):(
med1 = (D(an - in1 * (kna + in1)) + knb) * pwrq * -1;
);

out1 = srct * (med1 - prev_med1 + prev_out1);

(out1 < -1) ? out1 = -1;

spl1 = out1 * output;

prev_med1 = M(med1);
prev_out1 = M(out1);
);

m1 = m0;
spl0 = 0.5 * (m1+m0 = spl0);
spl1 = 0.5 * (m1+m0 = spl1);
