slider1:20<20,250,1>Hi-Pass (Hz)
slider2:0.3<0,1,0.001>Even Harmonics
slider3:0.3<0,1,0.001>Odd Harmonics
slider4:0<0,0.2,0.001>Fluctuation
slider5:0<-24,24,0.1>Harmonics (dB)
slider6:50<0,100,1>Mix (%)

slider8:0<-30,0,0.1>Threshold (dB)
slider9:2<1,20,0.1>Ratio
slider10:3<1,20,0.1>Attack (ms)
slider11:100<20,1000,1>Release (ms)
slider12:50<10,100,1>Env Decay (ms)
slider13:0<-24,24,0.1>Output (dB)

filename:0,w_comp_tubegfx/A.png
filename:1,w_comp_tubegfx/B.png
filename:2,w_comp_tubegfx/lampA.png
filename:3,w_comp_tubegfx/lampB.png

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

@init
ext_noinit=1;

seed0=rand(999)|0;
while (
seed1=rand(999)|0;
seed1==seed0;
);

sc_y0=sc_y1=1;
ka=0.97;
kb=1-ka;
lim=0.5;

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
// filter calculation
f= 2*$pi * min(slider1, 0.49 * srate) / srate;
q = 0.707;

//HPF:
w0 = f;
cos_w0 = cos(w0);
alpha = sin(w0) / (2*q);

b1 = -1 - cos_w0;
b0 = b2 = -0.5 * b1;
a0 = 1 + alpha;
a1 = -2 * cos_w0;
a2 = 1 - alpha;

a1 /= a0;
a2 /= a0;
b0 /= a0;
b1 /= a0;
b2 /= a0;

hgain = 10^(slider5/20);
mix = slider6/100;

threshold = 10^(slider8/20);
transfer_A = (1/slider9)-1;
transfer_B = output * pow(threshold,-transfer_A);
attack = exp(-1/(slider10/1000*srate));
release = exp(-1/(slider11/1000*srate));
envelope_decay = exp(-1/(slider12/1000*srate));
vol = 10^(slider13/20);

@block
tgt_drve=slider2*4;
drvo=slider3*9;
kr=slider4;
kabs=slider4*10;

//interpolate parameters

d_drve=(tgt_drve-src_drve)/samplesblock;
drve=src_drve;
src_drve=tgt_drve;

sc_y0=sin((seed0+=1)*sc_y0);
tgt_y0=sc_y0*kr;
d_y0=(tgt_y0-src_y0)/samplesblock;
y0=src_y0;
src_y0=tgt_y0;

sc_y1=sin((seed1+=1)*sc_y1);
tgt_y1=sc_y1*kr;
d_y1=(tgt_y1-src_y1)/samplesblock;
y1=src_y1;
src_y1=tgt_y1;

tgt_abs0=abs(ch0)*kabs;
d_abs0=(tgt_abs0-src_abs0)/samplesblock;
abs0=src_abs0;
src_abs0=tgt_abs0;

tgt_abs1=abs(ch1)*kabs;
d_abs1=(tgt_abs1-src_abs1)/samplesblock;
abs1=src_abs1;
src_abs1=tgt_abs1;

@sample
inA = spl0;
inB = spl1;

//Left
x2A = x1A;
x1A = x0A;
x0A = inA;

y2A = y1A;
y1A = y0A;
y0A = b0*x0A + b1*x1A + b2*x2A - a1*y1A - a2*y2A;

//Right
x2B = x1B;
x1B = x0B;
x0B = inB;

y2B = y1B;
y1B = y0B;
y0B = b0*x0B + b1*x1B + b2*x2B - a1*y1B - a2*y2B;

//Output
spl0 = y0A*mix;
spl1 = y0B*mix;

spl0 += inA * (1-mix);
spl1 += inB * (1-mix);

// set in gain
ch0 = spl0;
ch1 = spl1;

//interpolate
y0+=d_y0;
y1+=d_y1;
abs0+=d_abs0;
abs1+=d_abs1;
drve+=d_drve;

//set drive values
drve_rnd0=drve-abs0;
drve_rnd1=drve-abs1;
drvo_rnd0=drvo-abs0-y0;
drvo_rnd1=drvo-abs1-y1;

//apply harmonics
h0=sin(ch0)/sin(ch0*2)*drve_rnd0+(ch0-tan(ch0))*drvo_rnd0;
h1=sin(ch1)/sin(ch1*2)*drve_rnd1+(ch1-tan(ch1))*drvo_rnd1;

//dc filter i
dc00=h0-(dcf00=h0*kb+dcf00*ka);
dc01=h1-(dcf01=h1*kb+dcf01*ka);

//limiter
lim0=min(max(dc00*hgain,-lim),lim);
lim1=min(max(dc01*hgain,-lim),lim);

//fir filter
m01=m00;m03=m02;m05=m04;
fir0=0.5*(m05+m04=0.5*(m03+m02=0.5*(m01+m00=lim0)));
m11=m10;m13=m12;m15=m14;
fir1=0.5*(m15+m14=0.5*(m13+m12=0.5*(m11+m10=lim1)));

//dc filter ii
dc10=fir0-(dcf10=fir0*kb+dcf10*ka);
dc11=fir1-(dcf11=fir1*kb+dcf11*ka);

//sum
spl0 = (spl0+dc10)*mix;
spl1 = (spl1+dc11)*mix;

spl0 += ch0 * (1-mix);
spl1 += ch1 * (1-mix);

inL = spl0;
inR = spl1;

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

spl0 = inL * gain * vol;
spl1 = inR * gain * 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 425 135
gfx_r=1; gfx_g=gfx_b=0; gfx_a=0.8;

meter_bot=21;
meter_h=min(gfx_h,25);
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.0; 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);


drva=(drve+0.1+drvo*0.2)*0.5;

gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=40;
gfx_y=40;
gfx_blit(0,1,0);

gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=220;
gfx_y=40;
gfx_blit(0,1,0);

gfx_a=max(min(drva,1)-abs0,0);
gfx_r=gfx_g=gfx_b=0;
gfx_x=40;
gfx_y=40;
gfx_blit(1,1,0);

gfx_a=max(min(drva,1)-abs1,0);
gfx_r=gfx_g=gfx_b=0;
gfx_x=220;
gfx_y=40;
gfx_blit(1,1,0);


gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=9;
gfx_y=85;
gfx_blit(2,1,0);
drva>2?(
gfx_a=max(min(drva-2,1)-abs0*0.05,0.7);
gfx_r=gfx_g=gfx_b=0;
gfx_x=9;
gfx_y=85;
gfx_blit(3,1,0);
);

gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=9;
gfx_y=50;
gfx_blit(2,1,0);
drva>1?(
gfx_a=max(min(drva-1,1)-abs0*0.05,0.7);
gfx_r=gfx_g=gfx_b=0;
gfx_x=9;
gfx_y=50;
gfx_blit(3,1,0);
);


gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=386;
gfx_y=85;
gfx_blit(2,1,0);
drva>2?(
gfx_a=max(min(drva-2,1)-abs1*0.05,0.7);
gfx_r=gfx_g=gfx_b=0;
gfx_x=386;
gfx_y=85;
gfx_blit(3,1,0);
);

gfx_a=1;
gfx_r=gfx_g=gfx_b=0;
gfx_x=386;
gfx_y=50;
gfx_blit(2,1,0);
drva>1?(
gfx_a=max(min(drva-1,1)-abs1*0.05,0.7);
gfx_r=gfx_g=gfx_b=0;
gfx_x=386;
gfx_y=50;
gfx_blit(3,1,0);
);
