// This effect Copyright (C) 2004 and later Cockos Incorporated
// License: GPL - http://www.gnu.org/licenses/gpl.html


desc: amp modeler
slider1:/amp_models:none:Model
slider2:0<-120,30,1>preamp (dB)
slider3:1<0,1,1{no,yes}>upsample impulse if required
slider4:0<0,1,1{L-stereo,stereo-stereo}>channel mode
slider5:0,filter size
slider6:0,FFT size



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


@slider
  tmp=slider1|0;
  tmp != lslider1 ?
  (
    lslider1=tmp;

    filehandle=file_open(slider1);
    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 != !slider4 ? ( need_refft=1; stereo_mode=slider4; );



  useresample != slider3 ? (useresample=slider3; need_refft=1; );
  preamp=2^(slider2/6);

  slider6=fftsize;
  slider5=filtersize;

@block

need_refft ? (  // prepare convolution source, here...
  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;
  );
  slider5=filtersize;
  slider6=fftsize;
  sliderchange(slider5);
  sliderchange(slider6); 
  chunksize=fftsize-filtersize-1; // size of chunk size of audio to use
  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

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);


/*
  i=0;
  loop(fftsize,
    r=curblock[i]; im=curblock[i+1];   
    cr=convsrc[i]; ci=convsrc[i+1];
    curblock[i]=r*cr-im*ci;
    curblock[i+1]=r*ci+im*cr;
    i+=2;
  );
*/

  ifft(curblock,fftsize);

  bpos=0;
);

// save sample
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;

);
