// testing some formulas...
// plugin needs better graphics...

slider1:0<0,36,1{z+abs(x),z+x^slider8,x^slider9,z+exp(-1/x^slider8),z+log(1+(cos(x)-1)),z+(4*x^3-3*x),sin(atan(x)),((0.5*x^3)+(0.48*x^2)+(0.55*x))*0.5,-(x/abs(x)*(1-exp((x^2)/abs(x))))*0.5,z+(cos(x)*sin(x)),z+cos(x*($pi/4))-0.4+exp(x-0.25)/100,sin(z)+(abs(sin(x)))^slider8-0.2,(x-a*x^2-b*x^3+a)*0.5,x-(x^slider9)/(2*slider9),-0.5*log((1-x/1.5)/(1+x/1.5)),x-(x^3)/(3*2)+(x^5)/(5*4*3*2)-(x^7)/(7*6*5*4*3*2)+(x^9)/(9*8*7*6*5*4*3*2),z+sin(x)*(x-x^3/6+x^5/120),x^3/(1+abs(x^3)),1.5*x*(1-x*x/3),2/(1+exp(-c*x))-1,atan(x*c)/atan(c),atan(x*c)/(0.2+atan(c)),(x-atan((x*c)*(x*c)*(x*c))/atan(6*c)),1-exp(-x),x*(1+x^2)/(1+abs(x*(1+x^2))),(a*x+b*x^2+c*x^3)/(1+abs(a*x)+b*x^2+abs(c*x^3)),x*(1+x^4)/(1+abs(x*(1+x^4))),(x*abs(x)+x)/(x*x+abs(x)+1),x/(0.25*x*x+1),x/(1+abs(x)+abs(a)*$pi*(0.5*x^2-abs(x))),c*$pi*x/(1+c*$pi*abs(x)),x*(27+x*x)/(27+9*x*x),z+x^slider8/slider9,(2shiftright1)*atan(x)*0.6333,(z+x^slider8)*w or x^slider9,tanh0(x),cosh(x)}>mode
slider2:1<0,1,1{off,on}>z (fundamental)
slider3:1<0,1,1{off,on}>pre-limit
slider4:0<0,1,1{off,on}>post-limit
slider5:0<0,48,1>pre-gain (dB)
slider6:-6<-48,0,1>post-gain (dB)
slider8:2<2,10,2>slider8
slider9:3<3,11,2>slider9
slider11:0<-1,1,0.01>a
slider12:0<-1,1,0.01>b
slider13:1<1,20,0.01>c
slider15:0<-1,1,0.000001>L offset (r/o)
slider16:0<-1,1,0.000001>R offset (r/o)

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

@init
ext_nodenorm=1;

itm1=slider15;
itm2=slider16;
otm1=otm2=0;

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

function cosh(x)
(
(exp(x) + exp(-x))/2;
);

//First antiderivative of tanh(x)
function tanh0(x)
(
log(cosh(x));
);

@slider
mode=slider1;
fundamental=slider2;
prelimit=slider3;
postlimit=slider4;
pregain=10^(slider5/20);
postgain=10^(slider6/20);

a=slider11; // 1/8
b=slider12; // 1/18

c=slider13;

@sample
prelimit==1?(
x0=tanh(spl0*pregain);
x1=tanh(spl1*pregain);
):(
x0=spl0*pregain;
x1=spl1*pregain;
);

fundamental==1?(
z0=x0;
z1=x1;
w=0.5;
):(
z0=0;
z1=0;
w=1;
);

mode==0?(
y0=(z0+abs(x0))*w;
y1=(z1+abs(x1))*w;
);

mode==1?(
y0=(z0+x0^slider8)*w;
y1=(z1+x1^slider8)*w;
);

mode==2?(
y0=x0^slider9;
y1=x1^slider9;
);

mode==3?(
(x0<0||x0>0)?y0=(z0+exp(-1/x0^slider8))*w;
(x0=0)?y0=0;
(x1<0||x1>0)?y1=(z1+exp(-1/x1^slider8))*w;
(x1=0)?y1=0;
);

mode==4?(
y0=(z0+log(1+(cos(x0)-1)))*w;
y1=(z1+log(1+(cos(x1)-1)))*w;
);

mode==5?(
y0=(z0+(4*x0^3-3*x0))*w;
y1=(z1+(4*x1^3-3*x1))*w;
);

mode==6?(
y0=sin(atan(x0));
y1=sin(atan(x1));
);

mode==7?(
y0=((0.5*x0^3)+(0.48*x0^2)+(0.55*x0))*0.5;
y1=((0.5*x1^3)+(0.48*x1^2)+(0.55*x1))*0.5;
);

mode==8?(
y0=-(x0/abs(x0)*(1-exp((x0^2)/abs(x0))))*0.5;
y1=-(x1/abs(x1)*(1-exp((x1^2)/abs(x1))))*0.5;
);

mode==9?(
y0=(z0+(cos(x0)*sin(x0)))*w;
y1=(z1+(cos(x1)*sin(x1)))*w;
);

mode==10?(
y0=(z0+cos(x0*($pi/4))-0.4+exp(x0-0.25)/100)*w;
y1=(z1+cos(x1*($pi/4))-0.4+exp(x1-0.25)/100)*w;
);

mode==11?(
y0=(sin(z0)+(abs(sin(x0)))^slider8-0.2)*w; // -0.2 or below
y1=(sin(z1)+(abs(sin(x1)))^slider8-0.2)*w; // -0.2 or below
);

mode==12?(
y0=(x0-a*x0^2-b*x0^3+a)*0.5;
y1=(x1-a*x1^2-b*x1^3+a)*0.5;
);

mode==13?(
y0=x0-(x0^slider9)/(2*slider9);
y1=x1-(x1^slider9)/(2*slider9);
);

mode==14?(
y0=-0.5*log((1-x0/1.5)/(1+x0/1.5));
y1=-0.5*log((1-x1/1.5)/(1+x1/1.5));
);

mode==15?(
y0=x0-(x0^3)/(3*2)+(x0^5)/(5*4*3*2)-(x0^7)/(7*6*5*4*3*2)+(x0^9)/(9*8*7*6*5*4*3*2);
y1=x1-(x1^3)/(3*2)+(x1^5)/(5*4*3*2)-(x1^7)/(7*6*5*4*3*2)+(x1^9)/(9*8*7*6*5*4*3*2);
);

mode==16?(
y0=(z0+sin(x0)*(x0-x0^3/6+x0^5/120))*w;
y1=(z1+sin(x1)*(x1-x1^3/6+x1^5/120))*w;
);

mode==17?(
y0=x0^3/(1+abs(x0^3));
y1=x1^3/(1+abs(x1^3));
);

mode==18?(
y0=1.5*x0*(1-x0*x0/3);
y1=1.5*x1*(1-x0*x1/3);
);

mode==19?(
y0=2/(1+exp(-c*x0))-1;
y1=2/(1+exp(-c*x1))-1;
);

mode==20?(
y0=atan(x0*c)/atan(c);
y1=atan(x1*c)/atan(c);
);

mode==21?(
y0=atan(x0*c)/(0.2+atan(c));
y1=atan(x1*c)/(0.2+atan(c));
);

mode==22?(
y0=(x0-atan((x0*c)*(x0*c)*(x0*c))/atan(6*c));
y1=(x1-atan((x1*c)*(x1*c)*(x1*c))/atan(6*c));
);

mode==23?(
(x0>0)?y0=1-exp(-x0):y0=-1+exp(x0);
(x1>0)?y1=1-exp(-x1):y1=-1+exp(x1);
);

mode==24?(
y0=x0*(1+x0^2)/(1+abs(x0*(1+x0^2)));
y1=x1*(1+x1^2)/(1+abs(x1*(1+x1^2)));
);

mode==25?(
y0=(a*x0+b*x0^2+c*x0^3)/(1+abs(a*x0)+b*x0^2+abs(c*x0^3));
y1=(a*x1+b*x1^2+c*x1^3)/(1+abs(a*x1)+b*x1^2+abs(c*x1^3));
);

mode==26?(
y0=x0*(1+x0^4)/(1+abs(x0*(1+x0^4)));
y1=x1*(1+x1^4)/(1+abs(x1*(1+x1^4)));
);

mode==27?(
y0=(x0*abs(x0)+x0)/(x0*x0+abs(x0)+1);
y1=(x1*abs(x1)+x1)/(x1*x1+abs(x1)+1);
);

mode==28?(
y0=x0/(0.25*x0*x0+1);
y1=x1/(0.25*x1*x1+1);
);

mode==29?(
y0=x0/(1+abs(x0)+abs(a)*$pi*(0.5*x0^2-abs(x0)));
y1=x1/(1+abs(x1)+abs(a)*$pi*(0.5*x1^2-abs(x1)));
);

mode==30?(
y0=c*$pi*x0/(1+c*$pi*abs(x0));
y1=c*$pi*x1/(1+c*$pi*abs(x1));
);

mode==31?(
y0=x0*(27+x0*x0)/(27+9*x0*x0);
y1=x1*(27+x1*x1)/(27+9*x1*x1);
);

mode==32?(
y0=(z0+x0^slider8/slider9)*w;
y1=(z1+x1^slider8/slider9)*w;
);

mode==33?(
y0=(2>>1)*atan(x0)*0.6333;
y1=(2>>1)*atan(x1)*0.6333;
);

mode==34?(
(x0>0)?y0=(z0+x0^slider8)*w:y0=x0^slider9;
(x1>0)?y1=(z1+x1^slider8)*w:y1=x1^slider9;
);

mode==35?(
y0=(z0+tanh0(x0))*w;
y1=(z1+tanh0(x1))*w;
);

mode==36?(
y0=(z0+cosh(x0))*w;
y1=(z1+cosh(x1))*w;
);

postlimit==1?(
spl0=tanh(y0*postgain);
spl1=tanh(y1*postgain);
):(
spl0=y0*postgain;
spl1=y1*postgain;
);

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

// initial value (send to @init) used to remove dc offset at playback start
slider15=itm1;
sliderchange(slider15);
slider16=itm2;
sliderchange(slider16);

@gfx 0 200
gfx_clear = 0;
gfx_a = 1;

w2 = gfx_w * 0.5;
h2 = gfx_h * 0.5;

gfx_r=0.5; gfx_g=0; gfx_b=0;
gfx_x=0; gfx_y=h2;
gfx_lineto(gfx_w,h2,0);
gfx_x=w2; gfx_y=0;
gfx_lineto(w2,gfx_h,0);

n = -1;
nadd = 2 / gfx_w;
k = 0;

loop(gfx_w,

mode==0 ? ( m  = abs(n); ) :
mode==1 ? ( m  = n^slider8; ) :
mode==2 ? ( m  = n^slider9; ) :
mode==3 ? ( m  = exp(-1/n^slider8); ) :
mode==4 ? ( m  = log(1+(cos(n)-1)); ) :
mode==5 ? ( m  = (4*n^3-3*n); ) :
mode==6 ? ( m  = sin(atan(n)); ) :
mode==7 ? ( m  = ((0.5*n^3)+(0.48*n^2)+(0.55*n))*0.5; ) :
mode==8 ? ( m  = -(n/abs(n)*(1-exp((n^2)/abs(n))))*0.5; ) :
mode==9 ? ( m  = cos(n)*sin(n); ) :
mode==10 ? ( m  = cos(n*($pi/4))-0.4+exp(n-0.25)/100; ) :
mode==11 ? ( m  = (abs(sin(n)))^slider8-0.2; ) : // -0.2 or below
mode==12 ? ( m  = (n-a*n^2-b*n^3+a)*0.5; ) :
mode==13 ? ( m  = n-(n^slider9)/(2*slider9); ) :
mode==14 ? ( m  = -0.5*log((1-n/1.5)/(1+n/1.5)); ) :
mode==15 ? ( m  = n-(n^3)/(3*2)+(n^5)/(5*4*3*2)-(n^7)/(7*6*5*4*3*2)+(n^9)/(9*8*7*6*5*4*3*2); ) :
mode==16 ? ( m  = sin(n)*(n-n^3/6+n^5/120); ) :
mode==17 ? ( m  = n^3/(1+abs(n^3)); ) :
mode==18 ? ( m  = 1.5*n*(1-n*n/3); ) :
mode==19 ? ( m  = 2/(1+exp(-c*n))-1; ) :
mode==20 ? ( m  = atan(n*c)/atan(c); ) :
mode==21 ? ( m  = atan(n*c)/(0.2+atan(c)); ) :
mode==22 ? ( m  = (n-atan((n*c)*(n*c)*(n*c))/atan(6*c)); ) :
mode==23 ? ( (n>0)? m  = 1-exp(-n): m  = -1+exp(n); ) :
mode==24 ? ( m  = n*(1+n^2)/(1+abs(n*(1+n^2))); ) :
mode==25 ? ( m  = (a*n+b*n^2+c*n^3)/(1+abs(a*n)+b*n^2+abs(c*n^3)); ) :
mode==26 ? ( m  = n*(1+n^4)/(1+abs(n*(1+n^4))); ) :
mode==27 ? ( m  = (n*abs(n)+n)/(n*n+abs(n)+1); ) :
mode==28 ? ( m  = n/(0.25*n*n+1); ) :
mode==29 ? ( m  = n/(1+abs(n)+abs(a)*$pi*(0.5*n^2-abs(n))); ) :
mode==30 ? ( m  = c*$pi*n/(1+c*$pi*abs(n)); ) :
mode==31 ? ( m  = n*(27+n*n)/(27+9*n*n); ) :
mode==32 ? ( m  = n^slider8/slider9; ) :
mode==33 ? ( m  = (2>>1)*atan(n)*0.6333; ) :
mode==34 ? ( (n>0)? m  = (n^slider8): m  = n^slider9; ) :
mode==35 ? ( m  = tanh0(n); ) :
mode==36 ? ( m  = cosh(n); );

prelimit==1?(
m = tanh(m*pregain);
):(
m = m * pregain;
);

gfx_x = k;

postlimit==1?(
gfx_y = ( h2 - (tanh(m * postgain) * h2) );
):(
gfx_y = ( h2 - (m * postgain * h2) );
);

gfx_setpixel(1,1,1); 
n += nadd;
k += 1;
);
