/*
Splitter

2-way signal splitter.

Mode 	NORMAL		- Output as selected with Frequency and Level controls
	INVERSE		- Inverse of shown selection (e.g. everything except low frequencies at high level)
	NORM INV	- Left / Right split of above
	INV NORM	- Right / Left split of above
Frequency	Crossover frequency
Frequency switch	Select crossover output: LOW frequencies / ALL frequencies / HIGH frequencies
Level		Gate threshold
Level switch	Select gate output: LOW levels / ALL levels / HIGH levels
Envelope		Attack/Release - Gate envelope speed
Output		Level trim

This plug-in can split a signal based on frequency or level,
for example for producing dynamic effects where only loud drum hits are sent to a reverb.
Other functions include a simple "spectral gate" in INVERSE mode
and a conventional gate and filter for separating drum sounds in NORMAL mode.
*/

slider1:0<0,3,1{Normal,Inverse,Normal/Inverse,Inverse/Normal}>mode
slider2:0.5<0,1,0.01>frequency
slider3:1<0,2,1{Below,All,Above}>frequency switch
slider4:0.5<0,1,0.01>level
slider5:0<0,2,1{Below,All,Above}>level switch
slider6:0.6<0,1,0.01>attack
slider7:0.45<0,1,0.01>release
slider8:0.5<0,1,0.01>output

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

@init
env = buf0 = buf1 = buf2 = buf3 = 0;

itm1=itm2=otm1=otm2=0;

@slider
fParam0=slider1; //mode
fParam1=slider2; //freq
fParam2=slider3; //freq switch
fParam3=slider4; //level
fParam4=slider5; //level switch
fParam5=slider6; //attack
fParam6=slider7; //release
fParam7=slider8; //output

freq = fParam1;
fdisp = pow(10, 2 + 2 * freq)|0; //frequency
freq = 5.5 * fdisp / srate;
(freq>1) ? freq = 1;

ff = -1;			//above
tmpA = fParam2;		//frequency switching
(tmpA==0) ? ff = 0;	//below
(tmpA==1) ? freq = 0.001;	//all

ldisp = 40 * fParam3 - 40;	//level
level = pow(10, 0.05 * ldisp + 0.3);

ll = 0;			//above
tmpB = fParam4;		//level switching
(tmpB==0) ? ll = -1;	//below
(tmpB==1) ? level = 0;	//all

pp = -1;			//phase correction
(ff==ll) ? pp = 1;
(ff==0 && ll==-1) ? ( ll *= -1; );

att = pow(10, -0.002 - 4 * fParam5);
rel = 1 - pow(10, -2 - 3 * fParam6);

i2l = i2r = o2l = o2r = pow(10, 2 * fParam7 - 1); //gain

mode = fParam0;

mode == 0 ? (
i2l = 0;
i2r = 0;
);
mode == 1 ? (
o2l *= -1;
o2r *= -1;
);
mode == 2 ? (
i2l = 0;
o2r *= -1;
);
mode == 3 ? (
o2l *= -1;
i2r = 0;
);

@sample
a0=buf0;
a1=buf1;
b0=buf2;
b1=buf3;

e=env;

a = spl0;
b = spl1;

a0 += freq * (a - a0 - a1); //frequency split
a1 += freq * a0;
aa = a1 + ff * a;

b0 += freq * (b - b0 - b1);
b1 += freq * b0;
bb = b1 + ff * b;

ee = aa + bb;
(ee < 0) ? ee = -ee;
(ee > level) ? e += att * (pp - e); //level split
e *= rel;

a = i2l * a + o2l * aa * (e + ll);
b = i2r * b + o2r * bb * (e + ll);

spl0 = a;
spl1 = b;

otm1=0.999*otm1 + spl0 - itm1; itm1=spl0; spl0=otm1;
otm2=0.999*otm2 + spl1 - itm2; itm2=spl1; spl1=otm2;

(abs(e)<0.0000000001) ? ( env = 0; ):( env = e; );

buf0 = a0;
buf1 = a1;
buf2 = b0;
buf3 = b1;

(abs(a0)<0.0000000001) ? ( buf0 = buf1 = buf2 = buf3 = 0; ); //catch denormals

@gfx 0 120
gfx_r=0; gfx_g=0.9; gfx_b=0; gfx_a=1;
gfx_setfont(1,"Arial", 16);

gfx_x =20; gfx_y =10;  gfx_printf("%.0f",fdisp );
gfx_x =80; gfx_y =10;  gfx_printf("Hz");
gfx_x =110; gfx_y =10;  gfx_printf("Frequency");

gfx_x =20; gfx_y =30;  gfx_printf("%.1f",ldisp );
gfx_x =80; gfx_y =30;  gfx_printf("dB");
gfx_x =110; gfx_y =30;  gfx_printf("Level");

gfx_x =20; gfx_y =50;  gfx_printf("%.1f",pow(10, 3*fParam5) );
gfx_x =80; gfx_y =50;  gfx_printf("ms");
gfx_x =110; gfx_y =50;  gfx_printf("Attack");

gfx_x =20; gfx_y =70;  gfx_printf("%.1f",pow(10, 4*fParam6) );
gfx_x =80; gfx_y =70;  gfx_printf("ms");
gfx_x =110; gfx_y =70;  gfx_printf("Release");

gfx_x =20; gfx_y =90;  gfx_printf("%.1f",(40 * fParam7 - 20) );
gfx_x =80; gfx_y =90;  gfx_printf("dB");
gfx_x =110; gfx_y =90;  gfx_printf("Output");
