home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February / PCWorld_2008-02_cd.bin / audio-video / reaper / reaper2028-install.exe / Effects / Pitch / fft-ps next >
Text File  |  2007-12-03  |  3KB  |  125 lines

  1. desc: New FFT pitch-experimenter
  2. slider1:10<6,12,1>FFT size (bits)
  3. slider2:0<-1,1,0.01>slide amt (linear)
  4. slider3:0<-48,48,1>shift amt (scale semitones)
  5. slider4:1<0,1,0.01>width around peak
  6. slider5:0<-120,6,1>passthru mix
  7.  
  8. @init 
  9. fftsize=-1;
  10.  
  11. @slider
  12.   fftsize != (0|(2^slider1)) ? (
  13.     fftsize=(2^slider1)|0;
  14.     bpos=0; 
  15.     curblock=0;
  16.     lastblock=curblock+65536*2;
  17.     window=lastblock+65536*2;
  18.     hist=window+32768;
  19.     invfsize=1/fftsize;
  20.     hfftsize=fftsize*0.5;
  21.     tmp=0;
  22.     tsc=3.14159/hfftsize;
  23.     memset(curblock,0,fftsize*4);
  24.     memset(lastblock,0,fftsize*4);
  25.     memset(hist,0,fftsize*2);
  26.     loop(hfftsize,
  27.       window[tmp]=0.42-0.50*cos(tmp*tsc)+0.08*cos(2*tmp*tsc);
  28.       tmp+=1;
  29.     );
  30.   );
  31.   slideramt=(slider2*hfftsize)|0;
  32.   shiftamt=2^(slider3/12);
  33.   ptmix=2^(slider5/6);
  34.  
  35. @sample
  36.  
  37. bpos >= fftsize ? (
  38.  
  39.   t=curblock;
  40.   curblock=lastblock;
  41.   lastblock=t;
  42.  
  43.   fft(curblock,fftsize);
  44.   fft_permute(curblock,fftsize);
  45.   i=0;
  46.   swidth=slider4*hfftsize;
  47.   peakpos=fftsize*0.25;
  48.   slider4 < 1.0 ? (
  49.      peakval=0.0;
  50.      loop(hfftsize*0.25,
  51.         u=curblock[i]; v=curblock[i+1];
  52.         cval=(u*u+v*v);
  53.         cval > peakval ? (peakval=cval; peakpos=i*0.5; );
  54.         i+=2;
  55.         peakval*=1.01;
  56.      );
  57.   );
  58.   i=0;
  59.   cbout=curblock+fftsize*2;
  60.   memset(cbout,0,fftsize*2);
  61.   endpos=fftsize*2-2;
  62.   loop(hfftsize, 
  63.     i2=endpos-i;
  64.  
  65.     abs(i*0.5 - peakpos)>swidth ? (
  66.       cbout[i]+=curblock[i]*invfsize*ptmix;
  67.       cbout[i+1]+=curblock[i+1]*invfsize*ptmix;
  68.  
  69.       cbout[i2]+=curblock[i2]*invfsize*ptmix;
  70.       cbout[i2+1]+=curblock[i2+1]*invfsize*ptmix; 
  71.      ) : (
  72.     opos=((i*0.5+slideramt)*shiftamt)|0;
  73.     opos >= 0 && opos < hfftsize ? (
  74.       opos+=opos;
  75.  
  76.      0?(
  77.       cbout[opos]+=curblock[i]*invfsize;
  78.       cbout[opos+1]+=curblock[i+1]*invfsize;
  79.  
  80.       cbout[endpos-opos]+=curblock[i2]*invfsize;
  81.       cbout[endpos-opos+1]+=curblock[i2+1]*invfsize; 
  82.       ):(
  83.       u=curblock[i]; v=curblock[i+1];
  84.       u2=cbout[opos]; v2=cbout[opos+1];
  85.       phase1=(atan2(u,v)+atan2(u2,v2))*0.5;
  86.       mag1=sqrt(u2*u2+v2*v2)+sqrt(u*u+v*v);
  87.       mag1*=invfsize;
  88.       cbout[opos]=sin(phase1)*mag1;
  89.       cbout[opos+1]=cos(phase1)*mag1;
  90.  
  91.       u=curblock[i2]; v=curblock[i2+1];
  92.       u2=cbout[endpos-opos]; v2=cbout[endpos-opos+1];
  93.       phase1=(atan2(u,v)+atan2(u2,v2));
  94.       mag1=sqrt(u2*u2+v2*v2)+sqrt(u*u+v*v);
  95.       mag1*=invfsize;
  96.       cbout[endpos-opos]=sin(phase1)*mag1;
  97.       cbout[endpos-opos+1]=cos(phase1)*mag1;
  98.    );
  99.     );
  100.     );
  101.     i+=2; 
  102.   );
  103.   fft_ipermute(cbout,fftsize);
  104.   ifft(cbout,fftsize);
  105.   bpos=0;
  106. );
  107.  
  108. // make sample
  109. w=window[bpos*0.5];
  110. iw=1-w;
  111.  
  112. lastblock[bpos]=hist[bpos];
  113. lastblock[bpos+1]=hist[bpos+1];
  114. lastblock[fftsize+bpos]=spl0;
  115. lastblock[fftsize+bpos+1]=spl1;
  116.  
  117. hist[bpos]=spl0;
  118. hist[bpos+1]=spl1;
  119.  
  120. spl0=(curblock[fftsize*2+bpos]*w + lastblock[fftsize*3+bpos]*iw);
  121. spl1=(curblock[fftsize*2+bpos+1]*w + lastblock[fftsize*3+bpos+1]*iw);
  122.  
  123.  
  124. bpos+=2;
  125.