Blame lib/cdda_interface/smallft.c

Packit cb6d3d
/*
Packit cb6d3d
  Copyright (C) 2008 Rocky Bernstein <rocky@gnu.org>
Packit cb6d3d
  Copyright (C) 1998 Monty xiphmont@mit.edu
Packit cb6d3d
Packit cb6d3d
  This program is free software: you can redistribute it and/or modify
Packit cb6d3d
  it under the terms of the GNU General Public License as published by
Packit cb6d3d
  the Free Software Foundation, either version 3 of the License, or
Packit cb6d3d
  (at your option) any later version.
Packit cb6d3d
Packit cb6d3d
  This program is distributed in the hope that it will be useful,
Packit cb6d3d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cb6d3d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit cb6d3d
  GNU General Public License for more details.
Packit cb6d3d
Packit cb6d3d
  You should have received a copy of the GNU General Public License
Packit cb6d3d
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit cb6d3d
*/
Packit cb6d3d
Packit cb6d3d
/******************************************************************
Packit cb6d3d
 * FFT implementation from OggSquish, minus cosine transforms,
Packit cb6d3d
 * minus all but radix 2/4 case
Packit cb6d3d
 *
Packit cb6d3d
 * See OggSquish or NetLib for the version that can do other than just
Packit cb6d3d
 * power-of-two sized vectors.
Packit cb6d3d
 ******************************************************************/
Packit cb6d3d
Packit cb6d3d
#include <stdlib.h>
Packit cb6d3d
#include <math.h>
Packit cb6d3d
#include "smallft.h"
Packit cb6d3d
Packit cb6d3d
static void drfti1(int n, float *wa, int *ifac){
Packit cb6d3d
  static int ntryh[4] = { 4,2,3,5 };
Packit cb6d3d
  static float tpi = 6.28318530717958647692528676655900577;
Packit cb6d3d
  float arg,argh,argld,fi;
Packit cb6d3d
  int ntry=0,i,j=-1;
Packit cb6d3d
  int k1, l1, l2, ib;
Packit cb6d3d
  int ld, ii, ip, is, nq, nr;
Packit cb6d3d
  int ido, ipm, nfm1;
Packit cb6d3d
  int nl=n;
Packit cb6d3d
  int nf=0;
Packit cb6d3d
Packit cb6d3d
 L101:
Packit cb6d3d
  j++;
Packit cb6d3d
  if (j < 4)
Packit cb6d3d
    ntry=ntryh[j];
Packit cb6d3d
  else
Packit cb6d3d
    ntry+=2;
Packit cb6d3d
Packit cb6d3d
 L104:
Packit cb6d3d
  nq=nl/ntry;
Packit cb6d3d
  nr=nl-ntry*nq;
Packit cb6d3d
  if (nr!=0) goto L101;
Packit cb6d3d
Packit cb6d3d
  nf++;
Packit cb6d3d
  ifac[nf+1]=ntry;
Packit cb6d3d
  nl=nq;
Packit cb6d3d
  if(ntry!=2)goto L107;
Packit cb6d3d
  if(nf==1)goto L107;
Packit cb6d3d
Packit cb6d3d
  for (i=1;i
Packit cb6d3d
    ib=nf-i+1;
Packit cb6d3d
    ifac[ib+1]=ifac[ib];
Packit cb6d3d
  }
Packit cb6d3d
  ifac[2] = 2;
Packit cb6d3d
Packit cb6d3d
 L107:
Packit cb6d3d
  if(nl!=1)goto L104;
Packit cb6d3d
  ifac[0]=n;
Packit cb6d3d
  ifac[1]=nf;
Packit cb6d3d
  argh=tpi/n;
Packit cb6d3d
  is=0;
Packit cb6d3d
  nfm1=nf-1;
Packit cb6d3d
  l1=1;
Packit cb6d3d
Packit cb6d3d
  if(nfm1==0)return;
Packit cb6d3d
Packit cb6d3d
  for (k1=0;k1
Packit cb6d3d
    ip=ifac[k1+2];
Packit cb6d3d
    ld=0;
Packit cb6d3d
    l2=l1*ip;
Packit cb6d3d
    ido=n/l2;
Packit cb6d3d
    ipm=ip-1;
Packit cb6d3d
Packit cb6d3d
    for (j=0;j
Packit cb6d3d
      ld+=l1;
Packit cb6d3d
      i=is;
Packit cb6d3d
      argld=(float)ld*argh;
Packit cb6d3d
      fi=0.;
Packit cb6d3d
      for (ii=2;ii
Packit cb6d3d
	fi+=1.;
Packit cb6d3d
	arg=fi*argld;
Packit cb6d3d
	wa[i++]=cos(arg);
Packit cb6d3d
	wa[i++]=sin(arg);
Packit cb6d3d
      }
Packit cb6d3d
      is+=ido;
Packit cb6d3d
    }
Packit cb6d3d
    l1=l2;
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void fdrffti(int n, float *wsave, int *ifac){
Packit cb6d3d
Packit cb6d3d
  if (n == 1) return;
Packit cb6d3d
  drfti1(n, wsave+n, ifac);
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
Packit cb6d3d
  int i,k;
Packit cb6d3d
  float ti2,tr2;
Packit cb6d3d
  int t0,t1,t2,t3,t4,t5,t6;
Packit cb6d3d
Packit cb6d3d
  t1=0;
Packit cb6d3d
  t0=(t2=l1*ido);
Packit cb6d3d
  t3=ido<<1;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    ch[t1<<1]=cc[t1]+cc[t2];
Packit cb6d3d
    ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t2+=ido;
Packit cb6d3d
  }
Packit cb6d3d
    
Packit cb6d3d
  if(ido<2)return;
Packit cb6d3d
  if(ido==2)goto L105;
Packit cb6d3d
Packit cb6d3d
  t1=0;
Packit cb6d3d
  t2=t0;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t3=t2;
Packit cb6d3d
    t4=(t1<<1)+(ido<<1);
Packit cb6d3d
    t5=t1;
Packit cb6d3d
    t6=t1+t1;
Packit cb6d3d
    for(i=2;i
Packit cb6d3d
      t3+=2;
Packit cb6d3d
      t4-=2;
Packit cb6d3d
      t5+=2;
Packit cb6d3d
      t6+=2;
Packit cb6d3d
      tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
Packit cb6d3d
      ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
Packit cb6d3d
      ch[t6]=cc[t5]+ti2;
Packit cb6d3d
      ch[t4]=ti2-cc[t5];
Packit cb6d3d
      ch[t6-1]=cc[t5-1]+tr2;
Packit cb6d3d
      ch[t4-1]=cc[t5-1]-tr2;
Packit cb6d3d
    }
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t2+=ido;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido%2==1)return;
Packit cb6d3d
Packit cb6d3d
 L105:
Packit cb6d3d
  t3=(t2=(t1=ido)-1);
Packit cb6d3d
  t2+=t0;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    ch[t1]=-cc[t2];
Packit cb6d3d
    ch[t1-1]=cc[t3];
Packit cb6d3d
    t1+=ido<<1;
Packit cb6d3d
    t2+=ido;
Packit cb6d3d
    t3+=ido;
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
Packit cb6d3d
	    float *wa2,float *wa3){
Packit cb6d3d
  static float hsqt2 = .70710678118654752440084436210485;
Packit cb6d3d
  int i,k,t0,t1,t2,t3,t4,t5,t6;
Packit cb6d3d
  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
Packit cb6d3d
  t0=l1*ido;
Packit cb6d3d
  
Packit cb6d3d
  t1=t0;
Packit cb6d3d
  t4=t1<<1;
Packit cb6d3d
  t2=t1+(t1<<1);
Packit cb6d3d
  t3=0;
Packit cb6d3d
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    tr1=cc[t1]+cc[t2];
Packit cb6d3d
    tr2=cc[t3]+cc[t4];
Packit cb6d3d
Packit cb6d3d
    ch[t5=t3<<2]=tr1+tr2;
Packit cb6d3d
    ch[(ido<<2)+t5-1]=tr2-tr1;
Packit cb6d3d
    ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
Packit cb6d3d
    ch[t5]=cc[t2]-cc[t1];
Packit cb6d3d
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t2+=ido;
Packit cb6d3d
    t3+=ido;
Packit cb6d3d
    t4+=ido;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido<2)return;
Packit cb6d3d
  if(ido==2)goto L105;
Packit cb6d3d
Packit cb6d3d
Packit cb6d3d
  t1=0;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t2=t1;
Packit cb6d3d
    t4=t1<<2;
Packit cb6d3d
    t5=(t6=ido<<1)+t4;
Packit cb6d3d
    for(i=2;i
Packit cb6d3d
      t3=(t2+=2);
Packit cb6d3d
      t4+=2;
Packit cb6d3d
      t5-=2;
Packit cb6d3d
Packit cb6d3d
      t3+=t0;
Packit cb6d3d
      cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
Packit cb6d3d
      ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
Packit cb6d3d
      t3+=t0;
Packit cb6d3d
      cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
Packit cb6d3d
      ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
Packit cb6d3d
      t3+=t0;
Packit cb6d3d
      cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
Packit cb6d3d
      ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
Packit cb6d3d
Packit cb6d3d
      tr1=cr2+cr4;
Packit cb6d3d
      tr4=cr4-cr2;
Packit cb6d3d
      ti1=ci2+ci4;
Packit cb6d3d
      ti4=ci2-ci4;
Packit cb6d3d
Packit cb6d3d
      ti2=cc[t2]+ci3;
Packit cb6d3d
      ti3=cc[t2]-ci3;
Packit cb6d3d
      tr2=cc[t2-1]+cr3;
Packit cb6d3d
      tr3=cc[t2-1]-cr3;
Packit cb6d3d
Packit cb6d3d
      ch[t4-1]=tr1+tr2;
Packit cb6d3d
      ch[t4]=ti1+ti2;
Packit cb6d3d
Packit cb6d3d
      ch[t5-1]=tr3-ti4;
Packit cb6d3d
      ch[t5]=tr4-ti3;
Packit cb6d3d
Packit cb6d3d
      ch[t4+t6-1]=ti4+tr3;
Packit cb6d3d
      ch[t4+t6]=tr4+ti3;
Packit cb6d3d
Packit cb6d3d
      ch[t5+t6-1]=tr2-tr1;
Packit cb6d3d
      ch[t5+t6]=ti1-ti2;
Packit cb6d3d
    }
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
  }
Packit cb6d3d
  if(ido&1)return;
Packit cb6d3d
Packit cb6d3d
 L105:
Packit cb6d3d
  
Packit cb6d3d
  t2=(t1=t0+ido-1)+(t0<<1);
Packit cb6d3d
  t3=ido<<2;
Packit cb6d3d
  t4=ido;
Packit cb6d3d
  t5=ido<<1;
Packit cb6d3d
  t6=ido;
Packit cb6d3d
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    ti1=-hsqt2*(cc[t1]+cc[t2]);
Packit cb6d3d
    tr1=hsqt2*(cc[t1]-cc[t2]);
Packit cb6d3d
Packit cb6d3d
    ch[t4-1]=tr1+cc[t6-1];
Packit cb6d3d
    ch[t4+t5-1]=cc[t6-1]-tr1;
Packit cb6d3d
Packit cb6d3d
    ch[t4]=ti1-cc[t1+t0];
Packit cb6d3d
    ch[t4+t5]=ti1+cc[t1+t0];
Packit cb6d3d
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t2+=ido;
Packit cb6d3d
    t4+=t3;
Packit cb6d3d
    t6+=ido;
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
Packit cb6d3d
  int i,k1,l1,l2;
Packit cb6d3d
  int na,kh,nf;
Packit cb6d3d
  int ip,iw,ido,ix2,ix3;
Packit cb6d3d
Packit cb6d3d
  nf=ifac[1];
Packit cb6d3d
  na=1;
Packit cb6d3d
  l2=n;
Packit cb6d3d
  iw=n;
Packit cb6d3d
Packit cb6d3d
  for(k1=0;k1
Packit cb6d3d
    kh=nf-k1;
Packit cb6d3d
    ip=ifac[kh+1];
Packit cb6d3d
    l1=l2/ip;
Packit cb6d3d
    ido=n/l2;
Packit cb6d3d
    iw-=(ip-1)*ido;
Packit cb6d3d
    na=1-na;
Packit cb6d3d
Packit cb6d3d
    if(ip!=4)goto L102;
Packit cb6d3d
Packit cb6d3d
    ix2=iw+ido;
Packit cb6d3d
    ix3=ix2+ido;
Packit cb6d3d
    if(na!=0)
Packit cb6d3d
      dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
Packit cb6d3d
    else
Packit cb6d3d
      dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
Packit cb6d3d
    goto L110;
Packit cb6d3d
Packit cb6d3d
 L102:
Packit cb6d3d
    if(ip!=2)goto L104;
Packit cb6d3d
    if(na!=0)goto L103;
Packit cb6d3d
Packit cb6d3d
    dradf2(ido,l1,c,ch,wa+iw-1);
Packit cb6d3d
    goto L110;
Packit cb6d3d
Packit cb6d3d
  L103:
Packit cb6d3d
    dradf2(ido,l1,ch,c,wa+iw-1);
Packit cb6d3d
    goto L110;
Packit cb6d3d
Packit cb6d3d
  L104:
Packit cb6d3d
    return; /* We're restricted to powers of two.  just fail */
Packit cb6d3d
Packit cb6d3d
  L110:
Packit cb6d3d
    l2=l1;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(na==1)return;
Packit cb6d3d
Packit cb6d3d
  for(i=0;i
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void fdrfftf(int n,float *r,float *wsave,int *ifac){
Packit cb6d3d
  if(n==1)return;
Packit cb6d3d
  drftf1(n,r,wsave,wsave+n,ifac);
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
Packit cb6d3d
  int i,k,t0,t1,t2,t3,t4,t5,t6;
Packit cb6d3d
  float ti2,tr2;
Packit cb6d3d
Packit cb6d3d
  t0=l1*ido;
Packit cb6d3d
  
Packit cb6d3d
  t1=0;
Packit cb6d3d
  t2=0;
Packit cb6d3d
  t3=(ido<<1)-1;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    ch[t1]=cc[t2]+cc[t3+t2];
Packit cb6d3d
    ch[t1+t0]=cc[t2]-cc[t3+t2];
Packit cb6d3d
    t2=(t1+=ido)<<1;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido<2)return;
Packit cb6d3d
  if(ido==2)goto L105;
Packit cb6d3d
Packit cb6d3d
  t1=0;
Packit cb6d3d
  t2=0;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t3=t1;
Packit cb6d3d
    t5=(t4=t2)+(ido<<1);
Packit cb6d3d
    t6=t0+t1;
Packit cb6d3d
    for(i=2;i
Packit cb6d3d
      t3+=2;
Packit cb6d3d
      t4+=2;
Packit cb6d3d
      t5-=2;
Packit cb6d3d
      t6+=2;
Packit cb6d3d
      ch[t3-1]=cc[t4-1]+cc[t5-1];
Packit cb6d3d
      tr2=cc[t4-1]-cc[t5-1];
Packit cb6d3d
      ch[t3]=cc[t4]-cc[t5];
Packit cb6d3d
      ti2=cc[t4]+cc[t5];
Packit cb6d3d
      ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
Packit cb6d3d
      ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
Packit cb6d3d
    }
Packit cb6d3d
    t2=(t1+=ido)<<1;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido%2==1)return;
Packit cb6d3d
Packit cb6d3d
L105:
Packit cb6d3d
  t1=ido-1;
Packit cb6d3d
  t2=ido-1;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    ch[t1]=cc[t2]+cc[t2];
Packit cb6d3d
    ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t2+=ido<<1;
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
Packit cb6d3d
			  float *wa2,float *wa3){
Packit cb6d3d
  static float sqrt2=1.4142135623730950488016887242097;
Packit cb6d3d
  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
Packit cb6d3d
  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
Packit cb6d3d
  t0=l1*ido;
Packit cb6d3d
  
Packit cb6d3d
  t1=0;
Packit cb6d3d
  t2=ido<<2;
Packit cb6d3d
  t3=0;
Packit cb6d3d
  t6=ido<<1;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t4=t3+t6;
Packit cb6d3d
    t5=t1;
Packit cb6d3d
    tr3=cc[t4-1]+cc[t4-1];
Packit cb6d3d
    tr4=cc[t4]+cc[t4]; 
Packit cb6d3d
    tr1=cc[t3]-cc[(t4+=t6)-1];
Packit cb6d3d
    tr2=cc[t3]+cc[t4-1];
Packit cb6d3d
    ch[t5]=tr2+tr3;
Packit cb6d3d
    ch[t5+=t0]=tr1-tr4;
Packit cb6d3d
    ch[t5+=t0]=tr2-tr3;
Packit cb6d3d
    ch[t5+=t0]=tr1+tr4;
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
    t3+=t2;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido<2)return;
Packit cb6d3d
  if(ido==2)goto L105;
Packit cb6d3d
Packit cb6d3d
  t1=0;
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
Packit cb6d3d
    t7=t1;
Packit cb6d3d
    for(i=2;i
Packit cb6d3d
      t2+=2;
Packit cb6d3d
      t3+=2;
Packit cb6d3d
      t4-=2;
Packit cb6d3d
      t5-=2;
Packit cb6d3d
      t7+=2;
Packit cb6d3d
      ti1=cc[t2]+cc[t5];
Packit cb6d3d
      ti2=cc[t2]-cc[t5];
Packit cb6d3d
      ti3=cc[t3]-cc[t4];
Packit cb6d3d
      tr4=cc[t3]+cc[t4];
Packit cb6d3d
      tr1=cc[t2-1]-cc[t5-1];
Packit cb6d3d
      tr2=cc[t2-1]+cc[t5-1];
Packit cb6d3d
      ti4=cc[t3-1]-cc[t4-1];
Packit cb6d3d
      tr3=cc[t3-1]+cc[t4-1];
Packit cb6d3d
      ch[t7-1]=tr2+tr3;
Packit cb6d3d
      cr3=tr2-tr3;
Packit cb6d3d
      ch[t7]=ti2+ti3;
Packit cb6d3d
      ci3=ti2-ti3;
Packit cb6d3d
      cr2=tr1-tr4;
Packit cb6d3d
      cr4=tr1+tr4;
Packit cb6d3d
      ci2=ti1+ti4;
Packit cb6d3d
      ci4=ti1-ti4;
Packit cb6d3d
Packit cb6d3d
      ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
Packit cb6d3d
      ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
Packit cb6d3d
      ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
Packit cb6d3d
      ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
Packit cb6d3d
      ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
Packit cb6d3d
      ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
Packit cb6d3d
    }
Packit cb6d3d
    t1+=ido;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(ido%2 == 1)return;
Packit cb6d3d
Packit cb6d3d
 L105:
Packit cb6d3d
Packit cb6d3d
  t1=ido;
Packit cb6d3d
  t2=ido<<2;
Packit cb6d3d
  t3=ido-1;
Packit cb6d3d
  t4=ido+(ido<<1);
Packit cb6d3d
  for(k=0;k
Packit cb6d3d
    t5=t3;
Packit cb6d3d
    ti1=cc[t1]+cc[t4];
Packit cb6d3d
    ti2=cc[t4]-cc[t1];
Packit cb6d3d
    tr1=cc[t1-1]-cc[t4-1];
Packit cb6d3d
    tr2=cc[t1-1]+cc[t4-1];
Packit cb6d3d
    ch[t5]=tr2+tr2;
Packit cb6d3d
    ch[t5+=t0]=sqrt2*(tr1-ti1);
Packit cb6d3d
    ch[t5+=t0]=ti2+ti2;
Packit cb6d3d
    ch[t5+=t0]=-sqrt2*(tr1+ti1);
Packit cb6d3d
Packit cb6d3d
    t3+=ido;
Packit cb6d3d
    t1+=t2;
Packit cb6d3d
    t4+=t2;
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
Packit cb6d3d
  int i,k1,l1,l2;
Packit cb6d3d
  int na;
Packit cb6d3d
  int nf,ip,iw,ix2,ix3,ido;
Packit cb6d3d
Packit cb6d3d
  nf=ifac[1];
Packit cb6d3d
  na=0;
Packit cb6d3d
  l1=1;
Packit cb6d3d
  iw=1;
Packit cb6d3d
Packit cb6d3d
  for(k1=0;k1
Packit cb6d3d
    ip=ifac[k1 + 2];
Packit cb6d3d
    l2=ip*l1;
Packit cb6d3d
    ido=n/l2;
Packit cb6d3d
    if(ip!=4)goto L103;
Packit cb6d3d
    ix2=iw+ido;
Packit cb6d3d
    ix3=ix2+ido;
Packit cb6d3d
Packit cb6d3d
    if(na!=0)
Packit cb6d3d
      dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
Packit cb6d3d
    else
Packit cb6d3d
      dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
Packit cb6d3d
    na=1-na;
Packit cb6d3d
    goto L115;
Packit cb6d3d
Packit cb6d3d
  L103:
Packit cb6d3d
    if(ip!=2)goto L106;
Packit cb6d3d
Packit cb6d3d
    if(na!=0)
Packit cb6d3d
      dradb2(ido,l1,ch,c,wa+iw-1);
Packit cb6d3d
    else
Packit cb6d3d
      dradb2(ido,l1,c,ch,wa+iw-1);
Packit cb6d3d
    na=1-na;
Packit cb6d3d
    goto L115;
Packit cb6d3d
Packit cb6d3d
  L106:
Packit cb6d3d
    return; /* silently fail.  we only do powers of two in this version */
Packit cb6d3d
Packit cb6d3d
  L115:
Packit cb6d3d
    l1=l2;
Packit cb6d3d
    iw+=(ip-1)*ido;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  if(na==0)return;
Packit cb6d3d
Packit cb6d3d
  for(i=0;i
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
static void fdrfftb(int n, float *r, float *wsave, int *ifac){
Packit cb6d3d
  if (n == 1)return;
Packit cb6d3d
  drftb1(n, r, wsave, wsave+n, ifac);
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
void fft_forward(int n, float *buf,float *trigcache,int *splitcache){
Packit cb6d3d
  int flag=0;
Packit cb6d3d
Packit cb6d3d
  if(!trigcache || !splitcache){
Packit cb6d3d
    trigcache=calloc(3*n,sizeof(float));
Packit cb6d3d
    splitcache=calloc(32,sizeof(int));
Packit cb6d3d
    fdrffti(n, trigcache, splitcache);
Packit cb6d3d
    flag=1;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  fdrfftf(n, buf, trigcache, splitcache);
Packit cb6d3d
Packit cb6d3d
  if(flag){
Packit cb6d3d
    free(trigcache);
Packit cb6d3d
    free(splitcache);
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
void fft_backward(int n, float *buf, float *trigcache,int *splitcache){
Packit cb6d3d
  int i;
Packit cb6d3d
  int flag=0;
Packit cb6d3d
Packit cb6d3d
  if(!trigcache || !splitcache){
Packit cb6d3d
    trigcache=calloc(3*n,sizeof(float));
Packit cb6d3d
    splitcache=calloc(32,sizeof(int));
Packit cb6d3d
    fdrffti(n, trigcache, splitcache);
Packit cb6d3d
    flag=1;
Packit cb6d3d
  }
Packit cb6d3d
Packit cb6d3d
  fdrfftb(n, buf, trigcache, splitcache);
Packit cb6d3d
Packit cb6d3d
  for(i=0;i
Packit cb6d3d
Packit cb6d3d
  if(flag){
Packit cb6d3d
    free(trigcache);
Packit cb6d3d
    free(splitcache);
Packit cb6d3d
  }
Packit cb6d3d
}
Packit cb6d3d
Packit cb6d3d
void fft_i(int n, float **trigcache, int **splitcache){
Packit cb6d3d
  *trigcache=calloc(3*n,sizeof(float));
Packit cb6d3d
  *splitcache=calloc(32,sizeof(int));
Packit cb6d3d
  fdrffti(n, *trigcache, *splitcache);
Packit cb6d3d
}