#include "lm.h" s16 cos_tab[COS_TABLE_SIZE]; void dsp_init(void) { int i; for(i=0;i> (COS_BITS-1)) - s0; s0 = s1; s1 = s2; j += k; if (j >= n) j -= n; } y_re = s1 - ((cos_tab[k] * s0) >> COS_BITS); /* cannot use cos_tab because n is even */ y_im = s1 - ((sin_tab[k] * s0) >> COS_BITS); #else y_re = y_im = 0; for(i=0;i= n) j -= n; } y_re = y_re >> COS_BITS; y_im = y_im >> COS_BITS; #endif y_2 = y_re * y_re + y_im * y_im; return y_2; } /* horrible fft code - only needed to debug or fixed table generation */ #define FFT_MAX_SIZE 2048 static float norm; static float wfft[FFT_MAX_SIZE]; static short tinv[FFT_MAX_SIZE]; static int nf = 0, nf2, nf4; int fft_init(int n) { float p,k; int i,j,a,c, nk; nf=n; nf2=nf/2; nf4=nf/4; nk=0; while (n>>=1) nk++; norm=1/sqrt(nf); k=0; p=(2*M_PI)/nf; for(i=0;i<=nf4;i++) { wfft[i]=cos(k); k+=p; } for(i=0;i>=1; } tinv[i]= c<=i ? -1 : c; } return 0; } /* r = TRUE : reverse FFT */ void fft_calc(complex *x,int n, int r) { int i,j,k,l; complex a,b,c; complex *p,*q; /* auto init of coefficients */ if (n != nf) { fft_init(n); } k=nf2; l=1; do { p=x; q=x+k; i=l; do { j=0; do { a=*p; b=*q; p->re=a.re+b.re; p->im=a.im+b.im; b.re=a.re-b.re; b.im=a.im-b.im; if (j==0) { *q=b; } else if (j==nf4) { if (r) { q->re=b.im; q->im=-b.re; } else { q->re=-b.im; q->im=b.re; } q->re=-b.im; q->im=b.re; } else if (jre=b.re*c.re-b.im*c.im; q->im=b.im*c.re+b.re*c.im; } else { c.re=-wfft[nf2-j]; c.im=wfft[j-nf4]; if (r) c.im=-c.im; q->re=b.re*c.re-b.im*c.im; q->im=b.im*c.re+b.re*c.im; } p++; q++; j+=l; } while (j>=1; l<<=1; } while (k); for(i=0,p=x;ire*=norm; p->im*=norm; } for(i=0,p=x;i