SUBS.C
上传用户:dshsh2009
上传日期:2007-01-07
资源大小:155k
文件大小:6k
源码类别:

mpeg/mp3

开发平台:

Unix_Linux

  1. /**********************************************************************
  2. Copyright (c) 1991 ISO/IEC JTC1 SC29 WG1, All Rights Reserved
  3. subs.c
  4. **********************************************************************/
  5. /**********************************************************************
  6.  * MPEG/audio coding/decoding software, work in progress              *
  7.  *   NOT for public distribution until verified and approved by the   *
  8.  *   MPEG/audio committee.  For further information, please contact   *
  9.  *   Davis Pan, 708-538-5671, e-mail: pan@ukraine.corp.mot.com        *
  10.  *                                                                    *
  11.  * VERSION 4.3                                                        *
  12.  *   changes made since last update:                                  *
  13.  *   date   programmers         comment                               *
  14.  * 2/25/91  Davis Pan           start of version 1.0 records          *
  15.  * 5/10/91  W. Joseph Carter    Ported to Macintosh and Unix.         *
  16.  * 7/10/91  Earle Jennings      Ported to MsDos from Macintosh        *
  17.  *                              Replacement of one float with FLOAT   *
  18.  * 2/11/92  W. Joseph Carter    Added type casting to memset() args.  *
  19.  * 4/27/92  Masahiro Iwadare    Added 256 point version for Layer III *
  20.  **********************************************************************/
  21. #include "common.h"
  22. #include "encoder.h"
  23. /*****************************************************************************
  24.  ************************** Start of Subroutines *****************************
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * FFT computes fast fourier transform of BLKSIZE samples of data            *
  28.  *   uses decimation-in-frequency algorithm described in "Digital            *
  29.  *   Signal Processing" by Oppenheim and Schafer, refer to pages 304         *
  30.  *   (flow graph) and 330-332 (Fortran program in problem 5)                 *
  31.  *   to get the inverse fft, change line 20 from                             *
  32.  *                 w_imag[L] = -sin(PI/le1);                                 *
  33.  *                          to                                               *
  34.  *                 w_imag[L] = sin(PI/le1);                                  *
  35.  *                                                                           *
  36.  *   required constants:                                                     *
  37.  *         #define      PI          3.14159265358979                         *
  38.  *         #define      BLKSIZE     1024                                     *
  39.  *         #define      LOGBLKSIZE  10                                       *
  40.  *         #define      BLKSIZE_S   256                                      *
  41.  *         #define      LOGBLKSIZE_S 8                                       *
  42.  *                                                                           *
  43.  *****************************************************************************/
  44. #define      BLKSIZE_S   256
  45. #define      LOGBLKSIZE_S 8
  46. void fft(x_real,x_imag, energy, phi, N)
  47. FLOAT x_real[BLKSIZE], x_imag[BLKSIZE], energy[BLKSIZE], phi[BLKSIZE];
  48. int N;
  49. {
  50.  int     M,MM1;
  51.  static int     init=0;
  52.  int     NV2, NM1, MP;
  53.  static double  w_real[2][LOGBLKSIZE], w_imag[2][LOGBLKSIZE];
  54.  int            i,j,k,L;
  55.  int            ip, le,le1;
  56.  double         t_real, t_imag, u_real, u_imag;
  57.  if(init==0) {
  58.     memset((char *) w_real, 0, sizeof(w_real));  /* preset statics to 0 */
  59.     memset((char *) w_imag, 0, sizeof(w_imag));  /* preset statics to 0 */
  60.     M = LOGBLKSIZE;
  61.     for(L=0; L<M; L++){
  62.        le = 1 << (M-L);
  63.        le1 = le >> 1;
  64.        w_real[0][L] = cos(PI/le1);
  65.        w_imag[0][L] = -sin(PI/le1);
  66.     }          
  67.     M = LOGBLKSIZE_S;
  68.     for(L=0; L<M; L++){
  69.        le = 1 << (M-L);
  70.        le1 = le >> 1;
  71.        w_real[1][L] = cos(PI/le1);
  72.        w_imag[1][L] = -sin(PI/le1);
  73.     }          
  74.     init++;
  75.  }
  76.  switch(N) {
  77. case BLKSIZE:
  78. M = LOGBLKSIZE;
  79. MP = 0;
  80. break;
  81. case BLKSIZE_S:
  82. M = LOGBLKSIZE_S;
  83. MP = 1;
  84. break;
  85. default: printf("Error: Bad FFT Size in subs.cn");
  86. exit(-1);
  87.  }
  88.  MM1 = M-1;
  89.  NV2 = N >> 1;
  90.  NM1 = N - 1;
  91.  for(L=0; L<MM1; L++){
  92.     le = 1 << (M-L);
  93.     le1 = le >> 1;
  94.     u_real = 1;
  95.     u_imag = 0;
  96.     for(j=0; j<le1; j++){
  97.        for(i=j; i<N; i+=le){
  98.           ip = i + le1;
  99.           t_real = x_real[i] + x_real[ip];
  100.           t_imag = x_imag[i] + x_imag[ip];
  101.           x_real[ip] = x_real[i] - x_real[ip];
  102.           x_imag[ip] = x_imag[i] - x_imag[ip];
  103.           x_real[i] = t_real;
  104.           x_imag[i] = t_imag;
  105.           t_real = x_real[ip];
  106.           x_real[ip] = x_real[ip]*u_real - x_imag[ip]*u_imag;
  107.           x_imag[ip] = x_imag[ip]*u_real + t_real*u_imag;
  108.        }
  109.        t_real = u_real;
  110.        u_real = u_real*w_real[MP][L] - u_imag*w_imag[MP][L];
  111.        u_imag = u_imag*w_real[MP][L] + t_real*w_imag[MP][L];
  112.     }
  113.  }
  114.  /* special case: L = M-1; all Wn = 1 */
  115.  for(i=0; i<N; i+=2){
  116.     ip = i + 1;
  117.     t_real = x_real[i] + x_real[ip];
  118.     t_imag = x_imag[i] + x_imag[ip];
  119.     x_real[ip] = x_real[i] - x_real[ip];
  120.     x_imag[ip] = x_imag[i] - x_imag[ip];
  121.     x_real[i] = t_real;
  122.     x_imag[i] = t_imag;
  123.     energy[i] = x_real[i]*x_real[i] + x_imag[i]*x_imag[i];
  124.     if(energy[i] <= 0.0005){phi[i] = 0;energy[i] = 0.0005;}
  125.     else phi[i] = atan2((double) x_imag[i],(double) x_real[i]);
  126.     energy[ip] = x_real[ip]*x_real[ip] + x_imag[ip]*x_imag[ip];
  127.     if(energy[ip] == 0)phi[ip] = 0;
  128.     else phi[ip] = atan2((double) x_imag[ip],(double) x_real[ip]);
  129.  }
  130.  /* this section reorders the data to the correct ordering */
  131.  j = 0;
  132.  for(i=0; i<NM1; i++){
  133.     if(i<j){
  134. /* use this section only if you need the FFT in complex number form *
  135.  * (and in the correct ordering)                                    */
  136.        t_real = x_real[j];
  137.        t_imag = x_imag[j];
  138.        x_real[j] = x_real[i];
  139.        x_imag[j] = x_imag[i];
  140.        x_real[i] = t_real;
  141.        x_imag[i] = t_imag;
  142. /* reorder the energy and phase, phi                                        */
  143.        t_real = energy[j];
  144.        energy[j] = energy[i];
  145.        energy[i] = t_real;
  146.        t_real = phi[j];
  147.        phi[j] = phi[i];
  148.        phi[i] = t_real;
  149.     }
  150.     k=NV2;
  151.     while(k<=j){
  152.        j = j-k;
  153.        k = k >> 1;
  154.     }
  155.     j = j+k;
  156.  }
  157. }