FE_mfcc.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:6k
源码类别:

语音合成与识别

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // This is a part of the Feature program.
  3. // Version: 1.0
  4. // Date: February 22, 2003
  5. // Programmer: Oh-Wook Kwon
  6. // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #include "StdAfx.h"
  9. #include "FE_feature.h"
  10. int Fe::mel_cepstrum_basic(short *sample, int frameSize, float *mel_cep, int ceporder, int fft_size)
  11. {
  12. vector<float> frameA(frameSize);
  13. preprocessing(sample, frameSize, &frameA[0]);
  14. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  15. _mel_cepstrum_basic(&frameA[0], frameSize, mel_cep, m_fbOrder, ceporder, fft_size);
  16. return 1;
  17. }
  18. int Fe::_mel_cepstrum_basic(float *sample, int frameSize, float *mel_cep, int fborder, int ceporder, int fft_size)
  19. {
  20. int i;
  21. if(m_dctMatrix.size() != ceporder*fborder || ceporder != m_cepOrder){
  22. m_dctMatrix.resize((ceporder+1)*fborder);
  23. MfccInitDCTMatrix (&m_dctMatrix[0], ceporder, fborder);
  24. m_idctMatrix.resize((ceporder+1)*fborder);
  25. MfccInitIDCTMatrix (&m_idctMatrix[0], ceporder, fborder);
  26. }
  27. vector<float> filter_bank(m_fbOrder);
  28. _filterbank_basic(sample, frameSize, &filter_bank[0], fborder, fft_size, 0, 0);
  29. MfccDCT (&filter_bank[0], &m_dctMatrix[0], ceporder, fborder, mel_cep);
  30. /* scale down to be consistent with other kinds of cepstrum coefficients */
  31. float f=fborder/(float)fft_size;
  32. for(i=0;i<=ceporder;i++) mel_cep[i]*=f;
  33. return 1;
  34. }
  35. /* Supporting routine for MFCC */
  36. #define MfccRound(x) ((int)((x)+0.5))
  37. void Fe::MfccInitMelFilterBanks (float startingFrequency, float samplingRate, int fftLength, int numChannels)
  38. {
  39.     int i, k;
  40.     vector<float> freq(numChannels+2);
  41. vector<int> bin(numChannels+2);
  42. float start_mel, fs_per_2_mel;
  43.     /* Constants for calculation */
  44. freq[0] = startingFrequency;
  45.     start_mel = (float)(2595.0 * log10 (1.0 + startingFrequency / 700.0));
  46. bin[0] = MfccRound(fftLength * freq[0] / samplingRate);
  47. freq[numChannels+1] = (float)(samplingRate / 2.0);
  48.     fs_per_2_mel = (float)(2595.0 * log10 (1.0 + (samplingRate / 2.0) / 700.0));
  49. bin[numChannels+1] = MfccRound(fftLength * freq[numChannels+1] / samplingRate);
  50. /* Calculating mel-scaled frequency and the corresponding FFT-bin */
  51.     /* number for the lower edge of the band                          */
  52. for (k = 1; k <= numChannels; k++) {
  53.         freq[k] = (float)(700 * (pow (10, (start_mel + (float) k / (numChannels + 1) * (fs_per_2_mel - start_mel)) / 2595.0) - 1.0));
  54. bin[k] = MfccRound(fftLength * freq[k] / samplingRate);
  55. }
  56. /* This part is never used to compute MFCC coefficients */
  57. /* but initialized for completeness                     */
  58. m_MelWeight.resize(fftLength/2+1);
  59. for(i = 0; i<bin[0]; i++){
  60. m_MelWeight[i]=0;
  61. }
  62. m_MelWeight[fftLength/2]=1;
  63. /* Initialize low, center, high indices to FFT-bin */
  64. m_MelFB.resize(numChannels);
  65. for (k = 0; k <= numChannels; k++) {
  66. if(k<numChannels){
  67. m_MelFB[k].m_lowX=bin[k];
  68. m_MelFB[k].m_centerX=bin[k+1];
  69. m_MelFB[k].m_highX=bin[k+2];
  70. }
  71. for(i = bin[k]; i<bin[k+1]; i++){
  72. m_MelWeight[i]=(i-bin[k]+1)/(float)(bin[k+1]-bin[k]+1);
  73. }
  74.     }
  75. m_MelCenterFreq.resize(numChannels+2);
  76. m_MelCenterIdx.resize(numChannels+2);
  77. for(k=0;k<=numChannels+1;k++){
  78. m_MelCenterFreq[k]=freq[k];
  79. m_MelCenterIdx[k]=bin[k];
  80. }
  81.     return;
  82. }
  83. /* Be careful that the assumed ordering is [c0 c1 c2 ... c12] */
  84. int Fe::MfccInitDCTMatrix (float *dctMatrix, int ceporder, int numChannels)
  85. {
  86.     int i, j;
  87.     for (i = 0; i <= ceporder; i++){
  88.         for (j = 0; j < numChannels; j++){
  89.             dctMatrix[i * numChannels + j] = (float) cos (M_PI * (float) i / (float) numChannels * ((float) j + 0.5));
  90. if(i==0) dctMatrix[i * numChannels + j]*=(float)sqrt(1/(float)numChannels);
  91. else     dctMatrix[i * numChannels + j]*=(float)sqrt(2/(float)numChannels);
  92. }
  93. }
  94. return 1;
  95. }
  96. /* Be careful that the assumed ordering is [c0 c1 c2 ... c12] */
  97. int Fe::MfccInitIDCTMatrix (float *idctMatrix, int ceporder, int numChannels)
  98. {
  99.     int i, j;
  100. for (j = 0; j < numChannels; j++){
  101. for (i = 0; i <= ceporder; i++){
  102.             idctMatrix[j * (ceporder+1) + i] = (float) cos (M_PI * (float) i / (float) numChannels * ((float) j + 0.5));
  103. if(i==0) idctMatrix[j * (ceporder+1) + i]*=(float)sqrt(1/(float)numChannels);
  104. else     idctMatrix[j * (ceporder+1) + i]*=(float)sqrt(2/(float)numChannels);
  105. }
  106. }
  107. return 1;
  108. }
  109. void Fe::MfccDCT (float *x, float *dctMatrix, int ceporder, int numChannels, float *mel_cep)
  110. {
  111.     int i, j;
  112.     for (i = 0; i <= ceporder; i++) {
  113.         mel_cep[i] = 0.0;
  114.         for (j = 0; j < numChannels; j++){
  115.             mel_cep[i] += x[j] * dctMatrix[i * numChannels + j];
  116. }
  117.     }
  118.     return;
  119. }
  120. void Fe::MfccIDCT (float *mel_cep, float *idctMatrix, int ceporder, int numChannels, float *x)
  121. {
  122.     int i, j;
  123. for (j = 0; j < numChannels; j++) {
  124. x[j] = 0;
  125. for (i = 0; i <= ceporder; i++) {
  126.             x[j] += mel_cep[i] * idctMatrix[j * (ceporder+1) + i];
  127. }
  128.     }
  129.     return;
  130. }
  131. void Fe::MfccMelFilterBank (float *sigFFT, int numChannels, float* output, int normalize)
  132. {
  133.     float sum, wsum;
  134.     int i, k;
  135.     for (k=0;k<numChannels;k++){
  136. MfccMelFB *melFB=&m_MelFB[k];
  137.         sum = sigFFT[melFB->m_centerX];
  138. wsum=1;
  139.         for (i = melFB->m_lowX; i < melFB->m_centerX; i++){
  140.             sum += m_MelWeight[i] * sigFFT[i];
  141. wsum += m_MelWeight[i];
  142. }
  143. for (i = melFB->m_centerX+1; i <= melFB->m_highX; i++){
  144.             sum += (1 - m_MelWeight[i-1]) * sigFFT[i];
  145. wsum += (1 - m_MelWeight[i-1]);
  146. }
  147.         output[k] = sum;
  148. if(normalize) {
  149. assert(wsum>0);
  150. output[k] /= wsum;
  151. }
  152.     }
  153.     return;
  154. }