/* ** FFT and FHT routines ** Copyright 1988, 1993; Ron Mayer ** ** fht(fz,n); ** Does a hartley transform of "n" points in the array "fz". ** fft(n,real,imag) ** Does a fourier transform of "n" points of the "real" and ** "imag" arrays. ** ifft(n,real,imag) ** Does an inverse fourier transform of "n" points of the "real" ** and "imag" arrays. ** realfft(n,real) ** Does a real-valued fourier transform of "n" points of the ** "real" array. The real part of the transform ends ** up in the first half of the array and the imaginary part of the ** transform ends up in the second half of the array. ** realifft(n,real) ** The inverse of the realfft() routine above. ** ** ** NOTE: This routine uses at least 2 patented algorithms, and may be ** under the restrictions of a bunch of different organizations. ** Although I wrote it completely myself; it is kind of a derivative ** of a routine I once authored and released under the GPL, so it ** may fall under the free software foundation's restrictions; ** it was worked on as a Stanford Univ project, so they claim ** some rights to it; it was further optimized at work here, so ** I think this company claims parts of it. The patents are ** held by R. Bracewell (the FHT algorithm) and O. Buneman (the ** trig generator), both at Stanford Univ. ** If it were up to me, I'd say go do whatever you want with it; ** but it would be polite to give credit to the following people ** if you use this anywhere: ** Euler - probable inventor of the fourier transform. ** Gauss - probable inventor of the FFT. ** Hartley - probable inventor of the hartley transform. ** Buneman - for a really cool trig generator ** Mayer(me) - for authoring this particular version and ** including all the optimizations in one package. ** Thanks, ** Ron Mayer; mayer@acuson.com ** */ #include "fftmayer.h" #define GOOD_TRIG #define REAL r_4 #include "trigtbl.h" char fht_r4_version[] = "Brcwl-Hrtly-Ron-dbld"; #define SQRT2_2 0.70710678118654752440084436210484 #define SQRT2 2*0.70710678118654752440084436210484 void fht_r4(r_4 *fz,int n) { r_4 a,b; r_4 c1,s1,s2,c2,s3,c3,s4,c4; r_4 f0,g0,f1,g1,f2,g2,f3,g3; int i,k,k1,k2,k3,k4,kx; r_4 *fi,*fn,*gi; TRIG_VARS; for (k1=1,k2=0;k1>1; (!((k2^=k)&k)); k>>=1); if (k1>k2) { a=fz[k1];fz[k1]=fz[k2];fz[k2]=a; } } for ( k=0 ; (1<> 1; fi = fz; gi = fi + kx; fn = fz + n; do { r_4 g0,f0,f1,g1,f2,g2,f3,g3; f1 = fi[0 ] - fi[k1]; f0 = fi[0 ] + fi[k1]; f3 = fi[k2] - fi[k3]; f2 = fi[k2] + fi[k3]; fi[k2] = f0 - f2; fi[0 ] = f0 + f2; fi[k3] = f1 - f3; fi[k1] = f1 + f3; g1 = gi[0 ] - gi[k1]; g0 = gi[0 ] + gi[k1]; g3 = SQRT2 * gi[k3]; g2 = SQRT2 * gi[k2]; gi[k2] = g0 - g2; gi[0 ] = g0 + g2; gi[k3] = g1 - g3; gi[k1] = g1 + g3; gi += k4; fi += k4; } while (fi