nuclear@1: /******************************************************************** nuclear@1: * * nuclear@1: * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * nuclear@1: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * nuclear@1: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * nuclear@1: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * nuclear@1: * * nuclear@1: * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * nuclear@1: * by the Xiph.Org Foundation http://www.xiph.org/ * nuclear@1: * * nuclear@1: ******************************************************************** nuclear@1: nuclear@1: function: *unnormalized* fft transform nuclear@1: last mod: $Id: smallft.c 16227 2009-07-08 06:58:46Z xiphmont $ nuclear@1: nuclear@1: ********************************************************************/ nuclear@1: nuclear@1: /* FFT implementation from OggSquish, minus cosine transforms, nuclear@1: * minus all but radix 2/4 case. In Vorbis we only need this nuclear@1: * cut-down version. nuclear@1: * nuclear@1: * To do more than just power-of-two sized vectors, see the full nuclear@1: * version I wrote for NetLib. nuclear@1: * nuclear@1: * Note that the packing is a little strange; rather than the FFT r/i nuclear@1: * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, nuclear@1: * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the nuclear@1: * FORTRAN version nuclear@1: */ nuclear@1: nuclear@1: #include nuclear@1: #include nuclear@1: #include nuclear@1: #include "smallft.h" nuclear@1: #include "os.h" nuclear@1: #include "misc.h" nuclear@1: nuclear@1: static void drfti1(int n, float *wa, int *ifac){ nuclear@1: static int ntryh[4] = { 4,2,3,5 }; nuclear@1: static float tpi = 6.28318530717958648f; nuclear@1: float arg,argh,argld,fi; nuclear@1: int ntry=0,i,j=-1; nuclear@1: int k1, l1, l2, ib; nuclear@1: int ld, ii, ip, is, nq, nr; nuclear@1: int ido, ipm, nfm1; nuclear@1: int nl=n; nuclear@1: int nf=0; nuclear@1: nuclear@1: L101: nuclear@1: j++; nuclear@1: if (j < 4) nuclear@1: ntry=ntryh[j]; nuclear@1: else nuclear@1: ntry+=2; nuclear@1: nuclear@1: L104: nuclear@1: nq=nl/ntry; nuclear@1: nr=nl-ntry*nq; nuclear@1: if (nr!=0) goto L101; nuclear@1: nuclear@1: nf++; nuclear@1: ifac[nf+1]=ntry; nuclear@1: nl=nq; nuclear@1: if(ntry!=2)goto L107; nuclear@1: if(nf==1)goto L107; nuclear@1: nuclear@1: for (i=1;i>1; nuclear@1: ipp2=ip; nuclear@1: idp2=ido; nuclear@1: nbd=(ido-1)>>1; nuclear@1: t0=l1*ido; nuclear@1: t10=ip*ido; nuclear@1: nuclear@1: if(ido==1)goto L119; nuclear@1: for(ik=0;ikl1){ nuclear@1: for(j=1;j>1; nuclear@1: ipp2=ip; nuclear@1: ipph=(ip+1)>>1; nuclear@1: if(idol1)goto L139; nuclear@1: nuclear@1: is= -ido-1; nuclear@1: t1=0; nuclear@1: for(j=1;jn==1)return; nuclear@1: drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); nuclear@1: } nuclear@1: nuclear@1: void drft_backward(drft_lookup *l,float *data){ nuclear@1: if (l->n==1)return; nuclear@1: drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache); nuclear@1: } nuclear@1: nuclear@1: void drft_init(drft_lookup *l,int n){ nuclear@1: l->n=n; nuclear@1: l->trigcache=_ogg_calloc(3*n,sizeof(*l->trigcache)); nuclear@1: l->splitcache=_ogg_calloc(32,sizeof(*l->splitcache)); nuclear@1: fdrffti(n, l->trigcache, l->splitcache); nuclear@1: } nuclear@1: nuclear@1: void drft_clear(drft_lookup *l){ nuclear@1: if(l){ nuclear@1: if(l->trigcache)_ogg_free(l->trigcache); nuclear@1: if(l->splitcache)_ogg_free(l->splitcache); nuclear@1: memset(l,0,sizeof(*l)); nuclear@1: } nuclear@1: }