desc: ReaFarm

slider1:-62<-120,0,1>Noise Reduction (dB)
slider2:0<-6,6,0.1>-Sensitivity (dB)
slider3:5<1,100,1>Gain (%)
slider4:0<-18,6,.1>-Mid-Stage (dB)
slider5:0<-12,12,.1>Bass (dB)
slider6:0<-12,12,.1>Mid (dB)
slider7:0<-12,12,.1>Treble (dB)
slider8:0<-12,12,.1>Presence (dB)
slider9:-3<-32,6,0.1>Master (dB) 
slider10:0<0,1,1{Off,On}>Bright - 
slider11:0<0,2,1{1 - Clean,2 - Drive,3 - Distortion}>Channel - 

slider12:/amp_models2:none:Amp / Cabinet - 
slider13:-9<-32,6,1>Line Output (dB) 
slider14:1<0,1,1{No,Yes}>-Upsample Impulse If Required
slider15:0<0,1,1{L-Stereo,Stereo-Stereo}>-Channel Mode
slider16:0,-Filter Size
slider17:0,-FFT Size

in_pin:left input
in_pin:right input
out_pin:left output
out_pin:right output

@init
cDenorm=10^-30;
lbq=-32;         
mbq=2.5;         
hbq=-64;         
band1=2^(lbq)/6; 
band2=2^(mbq)/6; 
band3=2^(hbq)/6; 
silentcnt=0;
seekv=1; seekto=1;
splitLow=600;    
splitHigh=2400;  
gateFadeIn=30;
gateFadeOut=150;
toneLow=600;     
toneHigh=3000;   
toneVHigh=16000;


fftsize=-1;
need_refft=1;
convsrc=128*1024;
lslider1=-1;
impbuf=256*1024;

@slider
pregate=2 ^ (slider1/6);
preGain=2 ^ (slider2/6);
selectedDist = min(slider3/100,.999);
distGain = 2*selectedDist/(1-selectedDist);
midCut=2 ^ (slider4/6);
slider10 == 0 ?
(
  toneControlL=2 ^ ((slider5+22.5)/6);
  toneControlM=2 ^ (((slider6*4)-8)/6);
  toneControlH=2 ^ ((slider7+26)/6);
  toneControlVH=2 ^ ((slider8*2)/6);
  mstrOut=2 ^ ((slider9-18)/6);
) : (
  toneControlL=2 ^ (slider5/6);
  toneControlM=2 ^ (slider6/6);
  toneControlH=2 ^ (slider7/6);
  toneControlVH=2 ^ ((slider8*2)/6);
  mstrOut=2 ^ ((slider9+2)/6);
);
stageNumbers=slider11+1;

freqHP = min(splitHigh,srate);      
xHP = exp(-2.0*$pi*freqHP/srate);    
a0HP = 1.0-xHP;          
b1HP = -xHP;         

freqLP = min(min(splitLow,srate),splitHigh);
xLP = exp(-2.0*$pi*freqLP/srate);
a0LP = 1.0-xLP;
b1LP = -xLP;

freqHI = max(min(toneVHigh,srate),toneHigh);
xHI = exp(-2.0*$pi*freqHI/srate);
a0HI = 1.0-xHI;
b1HI = -xHI;

freqMID = max(min(min(toneHigh,srate),toneVHigh),toneLow);
xMID = exp(-2.0*$pi*freqMID/srate);
a0MID = 1.0-xMID;
b1MID = -xMID;

freqLOW = min(min(toneLow,srate),toneHigh);
xLOW = exp(-2.0*$pi*freqLOW/srate);
a0LOW = 1.0-xLOW;
b1LOW = -xLOW;

sillen=50*srate/1000;        
fadeout = 1/pow(10,1/(srate*gateFadeOut/1000));
fadein  = 1/pow(10,1/(srate*gateFadeIn/1000));


tmp=slider12|0;
  tmp != lslider1 ?
  (
    lslider1=tmp;

    filehandle=file_open(slider12);
    impbuf_l=impbuf_nch=impbuf_srate=0;
    filehandle > 0 ? 
    (
      file_riff(filehandle,impbuf_nch,impbuf_srate);
      impbuf_nch ?
      (
        impbuf_l=(file_avail(filehandle)/impbuf_nch)|0; 
        need_refft=1; 
        file_mem(filehandle,impbuf,impbuf_l*impbuf_nch);
      );
      file_close(filehandle);
    );
  );
  !stereo_mode != !slider15 ? ( need_refft=1; stereo_mode=slider15; );



  useresample != slider14 ? (useresample=slider14; need_refft=1; );
  preamp=2^(slider13/6);

  slider17=fftsize;
  slider16=filtersize;

@block
need_refft ? (  
  useresample && srate > impbuf_srate && impbuf_srate > 1 ? 
  (
    filtersize = ((srate*impbuf_l)/impbuf_srate)|0;
    isc=impbuf_srate/srate;
  )
  : 
  (
    filtersize=impbuf_l;
    isc=1.0;
  );

  fftsize=32;

  while(
    filtersize > fftsize*0.5 ? 
    (
      fftsize += fftsize;
    ) : 0;
  );
  slider16=filtersize;
  slider17=fftsize;
  sliderchange(slider16);
  sliderchange(slider17); 
  chunksize=fftsize-filtersize-1; 
  chunksize2=chunksize*2;
  bpos=0; 
  curblock=0;
  lastblock=64*1024;
  invfsize=1/fftsize;
  i=0;
  i2=0;
  loop(min(fftsize,filtersize),
     ipos=i|0;
     ipart=(i-ipos);
     convsrc[i2]=impbuf[ipos*impbuf_nch]*(1-ipart) + impbuf[(ipos+1)*impbuf_nch]*ipart;
     convsrc[i2+1]=stereo_mode ? 0.0 : (impbuf[(ipos+1)*impbuf_nch-1]*(1-ipart) +
                   impbuf[(ipos+1)*impbuf_nch-1]*(ipart));
     i += isc;
     i2+=2;
  );
  loop(fftsize-filtersize,
     convsrc[i2]=convsrc[i2+1]=0;
     i2+=2;
  );
  fft(convsrc,fftsize);
  i=0;
  loop(fftsize*2, convsrc[i] *= invfsize; i+=1; );
  need_refft=0;
);

@sample
a=abs(spl0) > preGate;        
a ? 
(
   silentcnt=0; 
   seekto=1;
) : (
   (silentcnt+=1) > sillen ?  seekto=0;
);
seekto > 0.5 ? 
( 
  seekv=seekv*fadein + (1-fadein);
)
:
( 
  seekv=seekv*fadeout;
);            

spl0=spl0*seekv*preGain;    
spl0 = min(max(spl0,-1),1);    

toneSpank=abs(spl0)*0.5;  
        
s0 = spl0;
lowSpl = (tmplLP = a0LP*s0 - b1LP*tmplLP + cDenorm);       
highSpl = s0 - (tmplHP = a0HP*s0 - b1HP*tmplHP + cDenorm); 
midSpl = s0 - lowSpl - highSpl;

lowSpl=lowSpl*band1*(1-toneSpank);  
midSpl=midSpl*band2;
highSpl=highSpl*band3*(toneSpank+0.5);

spl0=(lowSpl+midSpl+highSpl);  

spl0 > 0 ? (spl0 = (1+distGain)*spl0/(1+distGain*spl0));   
stageNumbers > 1 ?
(
spl0=spl0*midCut;            
spl0 > 0 ? (spl0 = (1+distGain)*spl0/(1+distGain*spl0));
);
stageNumbers > 2 ?
(
spl0=spl0*midCut;            
spl0 > 0 ? (spl0 = (1+distGain)*spl0/(1+distGain*spl0));
);

s0 = spl0;
low0 = (tmplMID = a0MID*s0 - b1MID*tmplMID + cDenorm);
spl0 = (tmplLOW = a0LOW*low0 - b1LOW*tmplLOW + cDenorm);
lowS0 = low0 - spl0;
hi0 = s0 - low0;
midS0 = (tmplHI = a0HI*hi0 - b1HI*tmplHI + cDenorm);
highS0 = hi0 - midS0;

spl0 = (spl0*toneControlL + lowS0*toneControlM + midS0*toneControlH + highS0*toneControlVH)*mstrOut;

spl1=spl0;        


filtersize > 0 ?
(

bpos >= chunksize ? 
(
  t=lastblock;
  lastblock=curblock;
  curblock=t;

  memset(curblock+chunksize*2,0,(fftsize-chunksize)*2);

  fft(curblock,fftsize);
  convolve_c(curblock,convsrc,fftsize);

  ifft(curblock,fftsize);

  bpos=0;
);

bp2=bpos*2;
lastblock[bp2]=spl0*preamp;
lastblock[bp2+1]=stereo_mode ? (spl1*preamp) : 0;

spl0=curblock[bp2];
spl1=curblock[bp2+1];

bpos < fftsize-chunksize ? 
(
  spl0+=lastblock[chunksize2+bp2];
  spl1+=lastblock[chunksize2+bp2+1];
);


bpos += 1;

);
