fft.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:10k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. ** FFT and FHT routines
  3. **  Copyright 1988, 1993; Ron Mayer
  4. **  
  5. **  fht(fz,n);
  6. **      Does a hartley transform of "n" points in the array "fz".
  7. **      
  8. ** NOTE: This routine uses at least 2 patented algorithms, and may be
  9. **       under the restrictions of a bunch of different organizations.
  10. **       Although I wrote it completely myself; it is kind of a derivative
  11. **       of a routine I once authored and released under the GPL, so it
  12. **       may fall under the free software foundation's restrictions;
  13. **       it was worked on as a Stanford Univ project, so they claim
  14. **       some rights to it; it was further optimized at work here, so
  15. **       I think this company claims parts of it.  The patents are
  16. **       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
  17. **       trig generator), both at Stanford Univ.
  18. **       If it were up to me, I'd say go do whatever you want with it;
  19. **       but it would be polite to give credit to the following people
  20. **       if you use this anywhere:
  21. **           Euler     - probable inventor of the fourier transform.
  22. **           Gauss     - probable inventor of the FFT.
  23. **           Hartley   - probable inventor of the hartley transform.
  24. **           Buneman   - for a really cool trig generator
  25. **           Mayer(me) - for authoring this particular version and
  26. **                       including all the optimizations in one package.
  27. **       Thanks,
  28. **       Ron Mayer; mayer@acuson.com
  29. ** and added some optimization by
  30. **           Mather    - idea of using lookup table
  31. **           Takehiro  - some dirty hack for speed up
  32. */
  33. #include <math.h>
  34. #include "util.h"
  35. #include "psymodel.h"
  36. #include "lame.h"
  37. #define TRI_SIZE (5-1) /* 1024 =  4**5 */
  38. static FLOAT costab[TRI_SIZE*2];
  39. static FLOAT window[BLKSIZE / 2], window_s[BLKSIZE_s / 2];
  40. static INLINE void fht(FLOAT *fz, short n)
  41. {
  42.     short k4;
  43.     FLOAT *fi, *fn, *gi;
  44.     FLOAT *tri;
  45.     fn = fz + n;
  46.     tri = &costab[0];
  47.     k4 = 4;
  48.     do {
  49. FLOAT s1, c1;
  50. short i, k1, k2, k3, kx;
  51. kx  = k4 >> 1;
  52. k1  = k4;
  53. k2  = k4 << 1;
  54. k3  = k2 + k1;
  55. k4  = k2 << 1;
  56. fi  = fz;
  57. gi  = fi + kx;
  58. do {
  59.     FLOAT f0,f1,f2,f3;
  60.     f1      = fi[0]  - fi[k1];
  61.     f0      = fi[0]  + fi[k1];
  62.     f3      = fi[k2] - fi[k3];
  63.     f2      = fi[k2] + fi[k3];
  64.     fi[k2]  = f0     - f2;
  65.     fi[0 ]  = f0     + f2;
  66.     fi[k3]  = f1     - f3;
  67.     fi[k1]  = f1     + f3;
  68.     f1      = gi[0]  - gi[k1];
  69.     f0      = gi[0]  + gi[k1];
  70.     f3      = SQRT2  * gi[k3];
  71.     f2      = SQRT2  * gi[k2];
  72.     gi[k2]  = f0     - f2;
  73.     gi[0 ]  = f0     + f2;
  74.     gi[k3]  = f1     - f3;
  75.     gi[k1]  = f1     + f3;
  76.     gi     += k4;
  77.     fi     += k4;
  78. } while (fi<fn);
  79. c1 = tri[0];
  80. s1 = tri[1];
  81. for (i = 1; i < kx; i++) {
  82.     FLOAT c2,s2;
  83.     c2 = 1 - (2*s1)*s1;
  84.     s2 = (2*s1)*c1;
  85.     fi = fz + i;
  86.     gi = fz + k1 - i;
  87.     do {
  88. FLOAT a,b,g0,f0,f1,g1,f2,g2,f3,g3;
  89. b       = s2*fi[k1] - c2*gi[k1];
  90. a       = c2*fi[k1] + s2*gi[k1];
  91. f1      = fi[0 ]    - a;
  92. f0      = fi[0 ]    + a;
  93. g1      = gi[0 ]    - b;
  94. g0      = gi[0 ]    + b;
  95. b       = s2*fi[k3] - c2*gi[k3];
  96. a       = c2*fi[k3] + s2*gi[k3];
  97. f3      = fi[k2]    - a;
  98. f2      = fi[k2]    + a;
  99. g3      = gi[k2]    - b;
  100. g2      = gi[k2]    + b;
  101. b       = s1*f2     - c1*g3;
  102. a       = c1*f2     + s1*g3;
  103. fi[k2]  = f0        - a;
  104. fi[0 ]  = f0        + a;
  105. gi[k3]  = g1        - b;
  106. gi[k1]  = g1        + b;
  107. b       = c1*g2     - s1*f3;
  108. a       = s1*g2     + c1*f3;
  109. gi[k2]  = g0        - a;
  110. gi[0 ]  = g0        + a;
  111. fi[k3]  = f1        - b;
  112. fi[k1]  = f1        + b;
  113. gi     += k4;
  114. fi     += k4;
  115.     } while (fi<fn);
  116.     c2 = c1;
  117.     c1 = c2 * tri[0] - s1 * tri[1];
  118.     s1 = c2 * tri[1] + s1 * tri[0];
  119.         }
  120. tri += 2;
  121.     } while (k4<n);
  122. }
  123. static const short rv_tbl[] = {
  124.     0x00,    0x80,    0x40,    0xc0,    0x20,    0xa0,    0x60,    0xe0,
  125.     0x10,    0x90,    0x50,    0xd0,    0x30,    0xb0,    0x70,    0xf0,
  126.     0x08,    0x88,    0x48,    0xc8,    0x28,    0xa8,    0x68,    0xe8,
  127.     0x18,    0x98,    0x58,    0xd8,    0x38,    0xb8,    0x78,    0xf8,
  128.     0x04,    0x84,    0x44,    0xc4,    0x24,    0xa4,    0x64,    0xe4,
  129.     0x14,    0x94,    0x54,    0xd4,    0x34,    0xb4,    0x74,    0xf4,
  130.     0x0c,    0x8c,    0x4c,    0xcc,    0x2c,    0xac,    0x6c,    0xec,
  131.     0x1c,    0x9c,    0x5c,    0xdc,    0x3c,    0xbc,    0x7c,    0xfc,
  132.     0x02,    0x82,    0x42,    0xc2,    0x22,    0xa2,    0x62,    0xe2,
  133.     0x12,    0x92,    0x52,    0xd2,    0x32,    0xb2,    0x72,    0xf2,
  134.     0x0a,    0x8a,    0x4a,    0xca,    0x2a,    0xaa,    0x6a,    0xea,
  135.     0x1a,    0x9a,    0x5a,    0xda,    0x3a,    0xba,    0x7a,    0xfa,
  136.     0x06,    0x86,    0x46,    0xc6,    0x26,    0xa6,    0x66,    0xe6,
  137.     0x16,    0x96,    0x56,    0xd6,    0x36,    0xb6,    0x76,    0xf6,
  138.     0x0e,    0x8e,    0x4e,    0xce,    0x2e,    0xae,    0x6e,    0xee,
  139.     0x1e,    0x9e,    0x5e,    0xde,    0x3e,    0xbe,    0x7e,    0xfe
  140. };
  141. #define ch01(index)  (buffer[chn][index])
  142. #define ch2(index)  (((FLOAT)(0.5*SQRT2))*(buffer[0][index] + buffer[1][index]))
  143. #define ch3(index)  (((FLOAT)(0.5*SQRT2))*(buffer[0][index] - buffer[1][index]))
  144. #define ml00(f) (window[i        ] * f(i))
  145. #define ml10(f) (window[0x1ff - i] * f(i + 0x200))
  146. #define ml20(f) (window[i + 0x100] * f(i + 0x100))
  147. #define ml30(f) (window[0x0ff - i] * f(i + 0x300))
  148. #define ml01(f) (window[i + 0x001] * f(i + 0x001))
  149. #define ml11(f) (window[0x1fe - i] * f(i + 0x201))
  150. #define ml21(f) (window[i + 0x101] * f(i + 0x101))
  151. #define ml31(f) (window[0x0fe - i] * f(i + 0x301))
  152. #define ms00(f) (window_s[i       ] * f(i + k))
  153. #define ms10(f) (window_s[0x7f - i] * f(i + k + 0x80))
  154. #define ms20(f) (window_s[i + 0x40] * f(i + k + 0x40))
  155. #define ms30(f) (window_s[0x3f - i] * f(i + k + 0xc0))
  156. #define ms01(f) (window_s[i + 0x01] * f(i + k + 0x01))
  157. #define ms11(f) (window_s[0x7e - i] * f(i + k + 0x81))
  158. #define ms21(f) (window_s[i + 0x41] * f(i + k + 0x41))
  159. #define ms31(f) (window_s[0x3e - i] * f(i + k + 0xc1))
  160. void fft_short(
  161.     FLOAT x_real[3][BLKSIZE_s], int chn, short *buffer[2])
  162. {
  163.     short i, j, b;
  164.     for (b = 0; b < 3; b++) {
  165. FLOAT *x = &x_real[b][BLKSIZE_s / 2];
  166. short k = (576 / 3) * (b + 1);
  167. j = BLKSIZE_s / 8 - 1;
  168. if (chn < 2) {
  169.     do {
  170. FLOAT f0,f1,f2,f3, w;
  171. i = rv_tbl[j << 2];
  172. f0 = ms00(ch01); w = ms10(ch01); f1 = f0 - w; f0 = f0 + w;
  173. f2 = ms20(ch01); w = ms30(ch01); f3 = f2 - w; f2 = f2 + w;
  174. x -= 4;
  175. x[0] = f0 + f2;
  176. x[2] = f0 - f2;
  177. x[1] = f1 + f3;
  178. x[3] = f1 - f3;
  179. f0 = ms01(ch01); w = ms11(ch01); f1 = f0 - w; f0 = f0 + w;
  180. f2 = ms21(ch01); w = ms31(ch01); f3 = f2 - w; f2 = f2 + w;
  181. x[BLKSIZE_s / 2 + 0] = f0 + f2;
  182. x[BLKSIZE_s / 2 + 2] = f0 - f2;
  183. x[BLKSIZE_s / 2 + 1] = f1 + f3;
  184. x[BLKSIZE_s / 2 + 3] = f1 - f3;
  185.     } while (--j >= 0);
  186. } else if (chn == 2) {
  187.     do {
  188. FLOAT f0,f1,f2,f3, w;
  189. i = rv_tbl[j << 2];
  190. f0 = ms00(ch2); w = ms10(ch2); f1 = f0 - w; f0 = f0 + w;
  191. f2 = ms20(ch2); w = ms30(ch2); f3 = f2 - w; f2 = f2 + w;
  192. x -= 4;
  193. x[0] = f0 + f2;
  194. x[2] = f0 - f2;
  195. x[1] = f1 + f3;
  196. x[3] = f1 - f3;
  197. f0 = ms01(ch2); w = ms11(ch2); f1 = f0 - w; f0 = f0 + w;
  198. f2 = ms21(ch2); w = ms31(ch2); f3 = f2 - w; f2 = f2 + w;
  199. x[BLKSIZE_s / 2 + 0] = f0 + f2;
  200. x[BLKSIZE_s / 2 + 2] = f0 - f2;
  201. x[BLKSIZE_s / 2 + 1] = f1 + f3;
  202. x[BLKSIZE_s / 2 + 3] = f1 - f3;
  203.     } while (--j >= 0);
  204. } else {
  205.     do {
  206. FLOAT f0,f1,f2,f3, w;
  207. i = rv_tbl[j << 2];
  208. f0 = ms00(ch3); w = ms10(ch3); f1 = f0 - w; f0 = f0 + w;
  209. f2 = ms20(ch3); w = ms30(ch3); f3 = f2 - w; f2 = f2 + w;
  210. x -= 4;
  211. x[0] = f0 + f2;
  212. x[2] = f0 - f2;
  213. x[1] = f1 + f3;
  214. x[3] = f1 - f3;
  215. f0 = ms01(ch3); w = ms11(ch3); f1 = f0 - w; f0 = f0 + w;
  216. f2 = ms21(ch3); w = ms31(ch3); f3 = f2 - w; f2 = f2 + w;
  217. x[BLKSIZE_s / 2 + 0] = f0 + f2;
  218. x[BLKSIZE_s / 2 + 2] = f0 - f2;
  219. x[BLKSIZE_s / 2 + 1] = f1 + f3;
  220. x[BLKSIZE_s / 2 + 3] = f1 - f3;
  221.     } while (--j >= 0);
  222. }
  223. fht(x, BLKSIZE_s);
  224.     }
  225. }
  226. void fft_long(
  227.     FLOAT x[BLKSIZE], int chn, short *buffer[2])
  228. {
  229.     short i,jj = BLKSIZE / 8 - 1;
  230.     x += BLKSIZE / 2;
  231.     if (chn < 2) {
  232. do {
  233.     FLOAT f0,f1,f2,f3, w;
  234.     i = rv_tbl[jj];
  235.     f0 = ml00(ch01); w = ml10(ch01); f1 = f0 - w; f0 = f0 + w;
  236.     f2 = ml20(ch01); w = ml30(ch01); f3 = f2 - w; f2 = f2 + w;
  237.     x -= 4;
  238.     x[0] = f0 + f2;
  239.     x[2] = f0 - f2;
  240.     x[1] = f1 + f3;
  241.     x[3] = f1 - f3;
  242.     f0 = ml01(ch01); w = ml11(ch01); f1 = f0 - w; f0 = f0 + w;
  243.     f2 = ml21(ch01); w = ml31(ch01); f3 = f2 - w; f2 = f2 + w;
  244.     x[BLKSIZE / 2 + 0] = f0 + f2;
  245.     x[BLKSIZE / 2 + 2] = f0 - f2;
  246.     x[BLKSIZE / 2 + 1] = f1 + f3;
  247.     x[BLKSIZE / 2 + 3] = f1 - f3;
  248. } while (--jj >= 0);
  249.     } else if (chn == 2) {
  250. do {
  251.     FLOAT f0,f1,f2,f3, w;
  252.     i = rv_tbl[jj];
  253.     f0 = ml00(ch2); w = ml10(ch2); f1 = f0 - w; f0 = f0 + w;
  254.     f2 = ml20(ch2); w = ml30(ch2); f3 = f2 - w; f2 = f2 + w;
  255.     x -= 4;
  256.     x[0] = f0 + f2;
  257.     x[2] = f0 - f2;
  258.     x[1] = f1 + f3;
  259.     x[3] = f1 - f3;
  260.     f0 = ml01(ch2); w = ml11(ch2); f1 = f0 - w; f0 = f0 + w;
  261.     f2 = ml21(ch2); w = ml31(ch2); f3 = f2 - w; f2 = f2 + w;
  262.     x[BLKSIZE / 2 + 0] = f0 + f2;
  263.     x[BLKSIZE / 2 + 2] = f0 - f2;
  264.     x[BLKSIZE / 2 + 1] = f1 + f3;
  265.     x[BLKSIZE / 2 + 3] = f1 - f3;
  266. } while (--jj >= 0);
  267.     } else {
  268. do {
  269.     FLOAT f0,f1,f2,f3, w;
  270.     i = rv_tbl[jj];
  271.     f0 = ml00(ch3); w = ml10(ch3); f1 = f0 - w; f0 = f0 + w;
  272.     f2 = ml20(ch3); w = ml30(ch3); f3 = f2 - w; f2 = f2 + w;
  273.     x -= 4;
  274.     x[0] = f0 + f2;
  275.     x[2] = f0 - f2;
  276.     x[1] = f1 + f3;
  277.     x[3] = f1 - f3;
  278.     f0 = ml01(ch3); w = ml11(ch3); f1 = f0 - w; f0 = f0 + w;
  279.     f2 = ml21(ch3); w = ml31(ch3); f3 = f2 - w; f2 = f2 + w;
  280.     x[BLKSIZE / 2 + 0] = f0 + f2;
  281.     x[BLKSIZE / 2 + 2] = f0 - f2;
  282.     x[BLKSIZE / 2 + 1] = f1 + f3;
  283.     x[BLKSIZE / 2 + 3] = f1 - f3;
  284. } while (--jj >= 0);
  285.     }
  286.     fht(x, BLKSIZE);
  287. }
  288. void init_fft(void)
  289. {
  290.     int i;
  291.     FLOAT r = PI*0.125;
  292.     for (i = 0; i < TRI_SIZE; i++) {
  293. costab[i*2  ] = cos(r);
  294. costab[i*2+1] = sin(r);
  295. r *= 0.25;
  296.     }
  297.     /*
  298.      * calculate HANN window coefficients 
  299.      */
  300.     for (i = 0; i < BLKSIZE / 2; i++)
  301. window[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE));
  302.     for (i = 0; i < BLKSIZE_s / 2; i++)
  303. window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s));
  304. }