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