mel_freq_spectrum.c
上传用户:bossps2lzz
上传日期:2022-07-07
资源大小:522k
文件大小:4k
源码类别:

DSP编程

开发平台:

C/C++

  1. /****************************************************************************
  2.  *
  3.  *
  4.  *
  5.  * 
  6.  * mel_freq_spectrum.c 
  7.  * 
  8.  * This program will compute the Mel-Frequency Sprectrum in a given signal.
  9.  *
  10.  * The input will be the address of the structure that 
  11.  * has the data after computing the power of the given signal and
  12.  * the address structure to store the Mel-Frequency Spectrum.
  13.  *
  14.  * The Mel-Frequency spectrum is computed by Multiplying the Signal
  15.  * Spectrum with a set of Triangular filters designed using Mel-Scale
  16.  *
  17.  * 
  18.  * If 'f' is the frequency, then the mel of the frequency is given by
  19.  * B(f) = 1125 log(1 + f/700 ) in mels
  20.  *
  21.  * If 'm' is the mel, then the corresponding frequency is given by
  22.  * B^-1(m) = 700 exp(m/1125) - 700 in Hz
  23.  *
  24.  * Mel for 4000Hz is computed and is divided by 20. The Frequency 
  25.  * Edge of each filter is computed by substituting the correspoding mel.
  26.  * Having Found the edge frequences and center frequencies of the filter,
  27.  * boundry points are computed to determine the transfer function of the filter
  28.  * 
  29.  * Boundry points are given by
  30.  *
  31.  *         N B^-1(B(fl) + m (1/21 B(fh) - 1/21 B(fl)))
  32.  * f(m) = ---------------------------------------------
  33.  *                 fs
  34.  *
  35.  *
  36.  * Here 'fs' is the sampling frequency, 'fh' is upper cut-off frequency
  37.  * 'fl' lower cut-off frequency, 'N' is the total number of samples = 256
  38.  * 'm' is the number denoting the filter number. (m=1 denotes first filter,
  39.  * m=2 denotes second filter and so on )
  40.  * 21 is the total number of filters + 1 = 20+1 = 21
  41.  *
  42.  *
  43.  * After computing boundry points, Transfer function of the Filters are 
  44.  * computed using the following formula
  45.  *
  46.  * H_m(k) = 0 ; if k < f(m-1)
  47.  *       = (k-f(m-1))/(f(m)-f(m-1))  ;  if f(m-1) <= k <= f(m)
  48.  *        = (f(m+1) -k) / (f(m+1)-f(m)) ;  if f(m) <= k <= f(m+1)
  49.  *   = 0 ;  if k > f(m+1)
  50.  *
  51.  *
  52.  * here 'm' denotes the filter number and 'f(m)' denotes the boundry points
  53.  * and 'k' denotes the sample number 
  54.  *
  55.  *
  56.  *
  57.  *
  58.  * The above transfer function will result in a triangular function.
  59.  *
  60.  *
  61.  *
  62.  *
  63.  * Written by Vasanthan Rangan and Sowmya Narayanan
  64.  *
  65.  *
  66.  *
  67.  *
  68.  *****************************************************************************/
  69.  
  70.  
  71. #include "filter_edge.h" /* Include the Filter Edges f(m) (Precomputed)*/
  72. #define column_length 256 /* total Number of samples per frame */
  73. #define row_length 100 /* Total number of Frames */
  74. struct complex {
  75. float real;
  76. float imag;
  77. }; /* Structure to store real and imaginary part of a signal */
  78. struct buffer {
  79. struct complex data[row_length][column_length];
  80. }; /* Structure to store input signal */
  81. struct mfcc {
  82. float data[row_length][Number_Of_Filters];
  83. };/* Structure to store the Mel Frequency Spectrum */
  84. /* Function to Compute Mel Frequency */
  85. void mel_freq_spectrum(struct buffer *input_data, struct mfcc *mfcc_coeff) {
  86. int i,j,k; /* Variables used as counters*/
  87. for ( j=0; j<row_length; j++ ) { /* For every Frame */
  88. for ( i=0; i<Number_Of_Filters; i++ ) { /*For each Filters */
  89. for ( k=0; k<((column_length/2) + 1) ; k++) { /*For each Sample in a Frame*/
  90. if ( k < H[i] ) { /* Apply Triangular Filters */
  91. mfcc_coeff->data[j][i] = mfcc_coeff->data[j][i] + (input_data->data[j][k].real*0.0);
  92. } else if ( k > H[i] && k < H[i+1] ) {
  93. mfcc_coeff->data[j][i] = mfcc_coeff->data[j][i] + (input_data->data[j][k].real*((k-H[i])/(H[i+1] - H[i])));
  94. } else if ( k > H[i+1] && k < H[i+2] ) {
  95. mfcc_coeff->data[j][i] = mfcc_coeff->data[j][i] + (input_data->data[j][k].real*((H[i+2]-k)/(H[i+2] - H[i+1])));
  96. }
  97. }
  98. }
  99. }
  100. return; /*Return back to Main Function */
  101. }