fft.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * FFT/IFFT transforms
  3.  * Copyright (c) 2002 Fabrice Bellard.
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. /**
  20.  * @file fft.c
  21.  * FFT/IFFT transforms.
  22.  */
  23. #include "dsputil.h"
  24. /**
  25.  * The size of the FFT is 2^nbits. If inverse is TRUE, inverse FFT is
  26.  * done 
  27.  */
  28. int ff_fft_init(FFTContext *s, int nbits, int inverse)
  29. {
  30.     int i, j, m, n;
  31.     float alpha, c1, s1, s2;
  32.     
  33.     s->nbits = nbits;
  34.     n = 1 << nbits;
  35.     s->exptab = av_malloc((n / 2) * sizeof(FFTComplex));
  36.     if (!s->exptab)
  37.         goto fail;
  38.     s->revtab = av_malloc(n * sizeof(uint16_t));
  39.     if (!s->revtab)
  40.         goto fail;
  41.     s->inverse = inverse;
  42.     s2 = inverse ? 1.0 : -1.0;
  43.         
  44.     for(i=0;i<(n/2);i++) {
  45.         alpha = 2 * M_PI * (float)i / (float)n;
  46.         c1 = cos(alpha);
  47.         s1 = sin(alpha) * s2;
  48.         s->exptab[i].re = c1;
  49.         s->exptab[i].im = s1;
  50.     }
  51.     s->fft_calc = ff_fft_calc_c;
  52.     s->exptab1 = NULL;
  53.     /* compute constant table for HAVE_SSE version */
  54. #if (defined(HAVE_MMX) && defined(HAVE_BUILTIN_VECTOR)) || defined(HAVE_ALTIVEC)
  55.     {
  56.         int has_vectors = 0;
  57. #if defined(HAVE_MMX)
  58.         has_vectors = mm_support() & MM_SSE;
  59. #endif
  60. #if defined(HAVE_ALTIVEC) && !defined(ALTIVEC_USE_REFERENCE_C_CODE)
  61.         has_vectors = mm_support() & MM_ALTIVEC;
  62. #endif
  63.         if (has_vectors) {
  64.             int np, nblocks, np2, l;
  65.             FFTComplex *q;
  66.             
  67.             np = 1 << nbits;
  68.             nblocks = np >> 3;
  69.             np2 = np >> 1;
  70.             s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex));
  71.             if (!s->exptab1)
  72.                 goto fail;
  73.             q = s->exptab1;
  74.             do {
  75.                 for(l = 0; l < np2; l += 2 * nblocks) {
  76.                     *q++ = s->exptab[l];
  77.                     *q++ = s->exptab[l + nblocks];
  78.                     q->re = -s->exptab[l].im;
  79.                     q->im = s->exptab[l].re;
  80.                     q++;
  81.                     q->re = -s->exptab[l + nblocks].im;
  82.                     q->im = s->exptab[l + nblocks].re;
  83.                     q++;
  84.                 }
  85.                 nblocks = nblocks >> 1;
  86.             } while (nblocks != 0);
  87.             av_freep(&s->exptab);
  88. #if defined(HAVE_MMX)
  89.             s->fft_calc = ff_fft_calc_sse;
  90. #else
  91.             s->fft_calc = ff_fft_calc_altivec;
  92. #endif
  93.         }
  94.     }
  95. #endif
  96.     /* compute bit reverse table */
  97.     for(i=0;i<n;i++) {
  98.         m=0;
  99.         for(j=0;j<nbits;j++) {
  100.             m |= ((i >> j) & 1) << (nbits-j-1);
  101.         }
  102.         s->revtab[i]=m;
  103.     }
  104.     return 0;
  105.  fail:
  106.     av_freep(&s->revtab);
  107.     av_freep(&s->exptab);
  108.     av_freep(&s->exptab1);
  109.     return -1;
  110. }
  111. /* butter fly op */
  112. #define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) 
  113. {
  114.   FFTSample ax, ay, bx, by;
  115.   bx=pre1;
  116.   by=pim1;
  117.   ax=qre1;
  118.   ay=qim1;
  119.   pre = (bx + ax);
  120.   pim = (by + ay);
  121.   qre = (bx - ax);
  122.   qim = (by - ay);
  123. }
  124. #define MUL16(a,b) ((a) * (b))
  125. #define CMUL(pre, pim, are, aim, bre, bim) 
  126. {
  127.    pre = (MUL16(are, bre) - MUL16(aim, bim));
  128.    pim = (MUL16(are, bim) + MUL16(bre, aim));
  129. }
  130. /**
  131.  * Do a complex FFT with the parameters defined in ff_fft_init(). The
  132.  * input data must be permuted before with s->revtab table. No
  133.  * 1.0/sqrt(n) normalization is done.  
  134.  */
  135. void ff_fft_calc_c(FFTContext *s, FFTComplex *z)
  136. {
  137.     int ln = s->nbits;
  138.     int j, np, np2;
  139.     int nblocks, nloops;
  140.     register FFTComplex *p, *q;
  141.     FFTComplex *exptab = s->exptab;
  142.     int l;
  143.     FFTSample tmp_re, tmp_im;
  144.     np = 1 << ln;
  145.     /* pass 0 */
  146.     p=&z[0];
  147.     j=(np >> 1);
  148.     do {
  149.         BF(p[0].re, p[0].im, p[1].re, p[1].im, 
  150.            p[0].re, p[0].im, p[1].re, p[1].im);
  151.         p+=2;
  152.     } while (--j != 0);
  153.     /* pass 1 */
  154.     
  155.     p=&z[0];
  156.     j=np >> 2;
  157.     if (s->inverse) {
  158.         do {
  159.             BF(p[0].re, p[0].im, p[2].re, p[2].im, 
  160.                p[0].re, p[0].im, p[2].re, p[2].im);
  161.             BF(p[1].re, p[1].im, p[3].re, p[3].im, 
  162.                p[1].re, p[1].im, -p[3].im, p[3].re);
  163.             p+=4;
  164.         } while (--j != 0);
  165.     } else {
  166.         do {
  167.             BF(p[0].re, p[0].im, p[2].re, p[2].im, 
  168.                p[0].re, p[0].im, p[2].re, p[2].im);
  169.             BF(p[1].re, p[1].im, p[3].re, p[3].im, 
  170.                p[1].re, p[1].im, p[3].im, -p[3].re);
  171.             p+=4;
  172.         } while (--j != 0);
  173.     }
  174.     /* pass 2 .. ln-1 */
  175.     nblocks = np >> 3;
  176.     nloops = 1 << 2;
  177.     np2 = np >> 1;
  178.     do {
  179.         p = z;
  180.         q = z + nloops;
  181.         for (j = 0; j < nblocks; ++j) {
  182.             BF(p->re, p->im, q->re, q->im,
  183.                p->re, p->im, q->re, q->im);
  184.             
  185.             p++;
  186.             q++;
  187.             for(l = nblocks; l < np2; l += nblocks) {
  188.                 CMUL(tmp_re, tmp_im, exptab[l].re, exptab[l].im, q->re, q->im);
  189.                 BF(p->re, p->im, q->re, q->im,
  190.                    p->re, p->im, tmp_re, tmp_im);
  191.                 p++;
  192.                 q++;
  193.             }
  194.             p += nloops;
  195.             q += nloops;
  196.         }
  197.         nblocks = nblocks >> 1;
  198.         nloops = nloops << 1;
  199.     } while (nblocks != 0);
  200. }
  201. /**
  202.  * Do the permutation needed BEFORE calling ff_fft_calc()
  203.  */
  204. void ff_fft_permute(FFTContext *s, FFTComplex *z)
  205. {
  206.     int j, k, np;
  207.     FFTComplex tmp;
  208.     const uint16_t *revtab = s->revtab;
  209.     
  210.     /* reverse */
  211.     np = 1 << s->nbits;
  212.     for(j=0;j<np;j++) {
  213.         k = revtab[j];
  214.         if (k < j) {
  215.             tmp = z[k];
  216.             z[k] = z[j];
  217.             z[j] = tmp;
  218.         }
  219.     }
  220. }
  221. void ff_fft_end(FFTContext *s)
  222. {
  223.     av_freep(&s->revtab);
  224.     av_freep(&s->exptab);
  225.     av_freep(&s->exptab1);
  226. }