// mod with different 'envelope' algo...
// ...and synced 'hold' times. (trying to prevent clicks...???)
// 1/4 is not working very well...

slider1:1<0,1,0.01>threshold
slider2:1<0,1,0.01>decay
slider3:1<0,1,0.01>tune
slider4:1<0,1,0.01>tune fine
slider5:2<0,3,1{1/4,1/8,1/16,1/32}>hold
slider6:1<0,1,0.01>mix
slider7:1<0,1,1{Low,High}>quality

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

@init
size = srate*0.5|0;
buffer = size;
buffer2 = size;
memset(buffer, 0, size);
memset(buffer2, 0, size);

buf = 0;
buf2 = 0;

tim = size + 1;

x = 0;
x2 = 0;

ga = 0;

@slider
fParam1 = slider1; //threshold
fParam2 = slider2; //decay (env)
fParam3 = slider3; //tune
fParam4 = slider4; //tune fine
//fParam5 = slider5; //hold (minimum chunk length)
fParam6 = slider6; //mix
fParam7 = slider7; //quality

thr = pow(10,(1.5 * fParam1) - 1.5);

//(fParam2>0.5) ? ( env = (1 + 0.003 * pow(fParam2 - 0.5,5)); ):( env = (1 + 0.025 * pow(fParam2 - 0.5,5)); ); // default
//(fParam2>0.5) ? ( env = (1 + 0.01 * (fParam2 - 0.5)); ):( env = (1 + 0.01 * (fParam2 - 0.5)); ); // mod
//(fParam2>0.5) ? ( env = (1 + 0.001 * (fParam2-0.9)); ):( env = (1 + 0.001 * (fParam2-0.99)); ); // mod
env = (1 + 0.005 * (fParam2-1.05)); // mod

tun = (((((fParam3 * 24)|0) - 24) + (fParam4 - 1)) / 24);
tun = pow(10, 0.60206 * tun);
wet = 0.5 * sqrt(fParam6);
dry = sqrt(1 - fParam6);

@block
slider5==0?(
hold=1/4;
);
slider5==1?(
hold=1/8;
);
slider5==2?(
hold=1/16;
);
slider5==3?(
hold=1/32;
);

sync = ((hold*240)/tempo)*1000;
dtim = (sync*srate*0.001)|0;
fade = dtim*0.00625|0; //80;
fade2 = sync*0.0001; //0.0125;

@sample
(fParam7>0.5) ? // high quality
(
a = spl0;
b = spl1;

((a+b > thr) && (tim > dtim)) ? // trigger
(
ga = 1;
tim = 0;
);

(tim<size) ? // play out
(
(tim<fade) ? // fade in
(
(tim==0) ? ( buf=x; buf2=x2; );

bufx[buffer + tim] = a;
bufx[buffer2 + tim] = b;
x = bufx[buffer + ((tim * tun)|0)];
x2 = bufx[buffer2 + ((tim * tun)|0)];

x = (buf * (1 - (fade2 * tim)) + (x * fade2 * tim));
x2 = (buf2 * (1 - (fade2 * tim)) + (x2 * fade2 * tim));
):(
// update to/from buffer
bufx[buffer + tim] = a;
bufx[buffer2 + tim] = b;

it1 = tim * tun; // interpolation
of1 = it1|0;
of2 = of1 + 1;
it1 = it1 - of1;
it2 = 1 - it1;

x = (it2* bufx[buffer + of1]) + (it1* bufx[buffer + of2]);
x2 = (it2* bufx[buffer2 + of1]) + (it1* bufx[buffer2 + of2]);
);

tim += 1;
ga *= env;
):( // mute
ga = 0;
);

c = (a * dry) + (x * ga * wet*2); // output
d = (b * dry) + (x2 * ga * wet*2);

spl0 = c;
spl1 = d;

):( // low quality

a = spl0;
b = spl1;

((a+b > thr) && (tim > dtim)) ? // trigger
(
ga = 1;
tim = 0;
);

(tim<size) ? // play out
(
(tim<fade) ? // fade in
(
(tim==0) ? buf = x;

bufx[buffer + tim] = (a + b);
x = bufx[buffer + ((tim * tun)|0)];

x = (buf * (1 - (fade2 * tim)) + (x * fade2 * tim));
):(
// update to/from buffer
bufx[buffer + tim] = (a + b);
x = bufx[buffer + ((tim * tun)|0)];
);

tim += 1;
ga *= env;
):( // mute
ga = 0;
);

c = (a * dry) + (x * ga * wet); // output
d = (b * dry) + (x * ga * wet);

spl0 = c;
spl1 = d;

);

@gfx 0 140
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("%.1f",((24 * fParam1) - 24) );
gfx_x =70; gfx_y =10;  gfx_printf("dB");
gfx_x =130; gfx_y =10;  gfx_printf("Threshold");

gfx_x =20; gfx_y =30;  gfx_printf("%.0f",((fParam2) * 100) );
gfx_x =70; gfx_y =30;  gfx_drawchar($'%');
gfx_x =130; gfx_y =30;  gfx_printf("Decay");

gfx_x =20; gfx_y =50;  gfx_printf("%.0f",((24 * fParam3) - 24) );
gfx_x =70; gfx_y =50;  gfx_printf("semi");
gfx_x =130; gfx_y =50;  gfx_printf("Tune");

gfx_x =20; gfx_y =70;  gfx_printf("%.0f",((99 * fParam4) - 99) );
gfx_x =70; gfx_y =70;  gfx_printf("cent");
gfx_x =130; gfx_y =70;  gfx_printf("Tune fine");

gfx_x =20; gfx_y =90;  gfx_printf("%.0f",sync );
gfx_x =70; gfx_y =90;  gfx_printf("ms");
gfx_x =130; gfx_y =90;  gfx_printf("Hold  r/o");

gfx_x =20; gfx_y =110;  gfx_printf("%.0f",(100 * fParam6) );
gfx_x =70; gfx_y =110;  gfx_drawchar($'%');
gfx_x =130; gfx_y =110;  gfx_printf("Mix");
