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

mpeg/mp3

开发平台:

C/C++

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