mfcc.c
上传用户:qingan1008
上传日期:2022-06-04
资源大小:3k
文件大小:8k
源码类别:

语音合成与识别

开发平台:

C/C++

  1. #include "mfcc.h"
  2. #include <math.h>
  3. #include <stdio.h>
  4. int temp=1;
  5. int m_cepOrder = 12;
  6. int m_fbOrder = 23;
  7. float m_dctMatrix[(12+1)*23];
  8. int m_sampleRate=32000;
  9. WfMelFB m_MelFB[23];
  10. float  m_MelWeight[512/2+1];
  11. float m_logEnergyFloor;
  12. float m_energyFloor;
  13. //预加重
  14. int preemphasize(float *sample, int sampleN)
  15. {
  16. /* Setting emphFac=0 turns off preemphasis. */
  17. int i;
  18. float emphFac = (float)0.97;
  19. for (i = sampleN-1; i > 0; i--) {
  20. sample[i] = sample[i] - emphFac * sample[i-1];
  21. }
  22. sample[0] = (float)(1.0 - emphFac) * sample[0];
  23. return(1);
  24. }
  25. int preprocessing(short *sample, int sampleN, float *out)
  26. {
  27. int i;
  28. for(i=0;i<sampleN;i++)
  29. out[i]=sample[i];
  30. //if (m_dither) Dither(out, sampleN);
  31. preemphasize(out, sampleN);
  32. return 1;
  33. }
  34. //加窗
  35. int Do_hamm_window(float *inputA, int inputN)
  36. {
  37. int i;
  38. float* hamm_window ;
  39. float temp = (float)(2 * M_PI / (float)(inputN-1));
  40. hamm_window = (float*)malloc(inputN*4);
  41.     for (i=0 ; i<inputN ; i++ ) hamm_window[i] = (float)(0.54 - 0.46*cos(temp*i));
  42. for (i=0 ; i<inputN ;i++ ) inputA[i] = hamm_window[i]*inputA[i];
  43. free(hamm_window);
  44. return(1);
  45. }
  46. int mel_cepstrum_basic(short *sample, int frameSize, float *mel_cep, int ceporder, int fft_size)
  47. {
  48. float* frameA = (float*)malloc(frameSize*4);
  49. preprocessing(sample, frameSize, &frameA[0]);
  50. Do_hamm_window(&frameA[0], frameSize);
  51. _mel_cepstrum_basic(&frameA[0], frameSize, mel_cep, m_fbOrder, ceporder, fft_size);
  52. free(frameA);
  53. return 1;
  54. }
  55. int MfccInitDCTMatrix (float *dctMatrix, int ceporder, int numChannels)
  56. {
  57.     int i, j;
  58.     for (i = 0; i <= ceporder; i++){//12+1
  59.         for (j = 0; j < numChannels; j++){//23
  60.             dctMatrix[i * numChannels + j] = (float) cos (M_PI * (float) i / (float) numChannels * ((float) j + 0.5));
  61. if(i==0) dctMatrix[i * numChannels + j]*=(float)sqrt(1/(float)numChannels);
  62. else     dctMatrix[i * numChannels + j]*=(float)sqrt(2/(float)numChannels);
  63. }
  64. }
  65. return 1;
  66. }
  67. int _mel_cepstrum_basic(float *sample, int frameSize, float *mel_cep, int fborder, int ceporder, int fft_size)
  68. {
  69. int i;
  70. float* filter_bank = (float*)malloc(m_fbOrder*4);
  71. float f;
  72. MfccInitDCTMatrix (&m_dctMatrix[0], ceporder, fborder);
  73. _filterbank_basic(sample, frameSize, &filter_bank[0], fborder, fft_size, 0, 0);
  74. MfccDCT (filter_bank, &m_dctMatrix[0], ceporder, fborder, mel_cep);
  75. free(filter_bank);
  76. // /* scale down to be consistent with other kinds of cepstrum coefficients */
  77. f=fborder/(float)fft_size;
  78. for(i=0;i<=ceporder;i++)
  79. mel_cep[i]*=f;
  80. printf("gogogo%dn",temp);
  81.         temp++;
  82.     for(i=0;i<13;i++)
  83. {
  84.    printf("%ft",mel_cep[i]);
  85. }
  86.     return 1;
  87. }
  88. /* Supporting routine for MFCC */
  89. #define MfccRound(x) ((int)((x)+0.5))
  90. void MfccInitMelFilterBanks (float startingFrequency, float samplingRate, int fftLength, int numChannels)
  91. {
  92.     int i, k;
  93.     float* freq=(float*)malloc(numChannels*4+8);
  94. int * bin=(int *)malloc(numChannels*4+8);
  95. float start_mel, fs_per_2_mel;
  96. //m_MelWeight = (float*)malloc(fftLength*2+4);
  97.     /* Constants for calculation */
  98. freq[0] = startingFrequency;
  99.     start_mel = (float)(2595.0 * log10 (1.0 + startingFrequency / 700.0));
  100. bin[0] = MfccRound(fftLength * freq[0] / samplingRate);
  101. freq[numChannels+1] = (float)(samplingRate / 2.0);
  102.     fs_per_2_mel = (float)(2595.0 * log10 (1.0 + (samplingRate / 2.0) / 700.0));
  103. bin[numChannels+1] = MfccRound(fftLength * freq[numChannels+1] / samplingRate);
  104. /* Calculating mel-scaled frequency and the corresponding FFT-bin */
  105.     /* number for the lower edge of the band                          */
  106. for (k = 1; k <= numChannels; k++) {
  107.         freq[k] = (float)(700 * (pow (10, (start_mel + (float) k / (numChannels + 1) * (fs_per_2_mel - start_mel)) / 2595.0) - 1.0));
  108. bin[k] = MfccRound(fftLength * freq[k] / samplingRate);
  109. }
  110. /* This part is never used to compute MFCC coefficients */
  111. /* but initialized for completeness                     */
  112. for(i = 0; i<bin[0]; i++){
  113. m_MelWeight[i]=0;
  114. }
  115. m_MelWeight[fftLength/2]=1;
  116. /* Initialize low, center, high indices to FFT-bin */
  117. for (k = 0; k <= numChannels; k++) {
  118. if(k<numChannels){
  119. m_MelFB[k].m_lowX=bin[k];
  120. m_MelFB[k].m_centerX=bin[k+1];
  121. m_MelFB[k].m_highX=bin[k+2];
  122. }
  123. for(i = bin[k]; i<bin[k+1]; i++){
  124. m_MelWeight[i]=(i-bin[k]+1)/(float)(bin[k+1]-bin[k]+1);
  125. }
  126.     }
  127. free(freq);
  128. free(bin);
  129.     return;
  130. }
  131. float LogE(float x)
  132. {
  133. if(x>m_energyFloor) return log(x);
  134. else return m_logEnergyFloor;
  135. }
  136. void PRFFT_NEW(float *a, float *b, int m, int n_pts, int iff)
  137. {
  138. int l,lmx,lix,lm,li,j1,j2,ii,jj,nv2,nm1,k,lmxy,n;
  139. float scl,s,c,arg,T_a,T_b;
  140. n = 1 << m;
  141. for( l=1 ; l<=m ; l++ ) {
  142. lmx = 1 << (m - l) ;
  143. lix = 2 * lmx ;
  144. scl = 2 * (float)M_PI/(float)lix ;
  145. if(lmx < n_pts) lmxy = lmx ;
  146. else lmxy = n_pts ;
  147. for( lm = 1 ; lm <= lmxy ; lm++ ) {
  148. arg=((float)(lm-1)*scl) ;
  149. c = (float)cos(arg) ;
  150. s = iff * (float)sin(arg) ;
  151. for( li = lix ; li <= n ; li += lix ) {
  152. j1 = li - lix + lm ;
  153. j2 = j1 + lmx ;
  154. if(lmxy != n_pts ) {
  155. T_a=a[j1-1] - a[j2-1] ;
  156. /* T_a : real part */
  157. T_b=b[j1-1] - b[j2-1] ;
  158. /* T_b : imaginary part */
  159. a[j1-1] = a[j1-1] + a[j2-1] ;
  160. b[j1-1] = b[j1-1] + b[j2-1] ;
  161. a[j2-1] = T_a*c + T_b*s ;
  162. b[j2-1] = T_b*c - T_a*s ;
  163. } else{
  164. a[j2-1] = a[j1-1]*c + b[j1-1]*s ;
  165. b[j2-1] = b[j1-1]*c - a[j1-1]*s ;
  166. }
  167. }
  168. }
  169. }
  170. nv2 = n/2 ;
  171. nm1 = n - 1 ;
  172. jj = 1 ;
  173. for( ii = 1 ; ii <= nm1 ;) {
  174. if( ii < jj ) {
  175. T_a = a[jj-1] ;
  176. T_b = b[jj-1] ;
  177. a[jj-1] = a[ii-1] ;
  178. b[jj-1] = b[ii-1] ;
  179. a[ii-1] = T_a ;
  180. b[ii-1] = T_b ;
  181. }
  182. k = nv2 ;
  183. while( k < jj ) {
  184. jj = jj - k ;
  185. k = k/2 ;
  186. }
  187. jj = jj + k ;
  188. ii = ii + 1 ;
  189. }
  190. if(iff == (-1)){
  191. for( l=0 ; l<n ; l++ ) {
  192. a[l]/=(float)n;
  193. b[l]/=(float)n;
  194. }
  195. }
  196. }
  197. void MfccMelFilterBank (float *sigFFT, int numChannels, float* output, int normalize)
  198. {
  199.     float sum, wsum;
  200.     int i, k;
  201. MfccMelFB *melFB;
  202.     for (k=0;k<numChannels;k++){
  203. melFB=&m_MelFB[k];
  204.         sum = sigFFT[melFB->m_centerX];
  205. wsum=1;
  206.         for (i = melFB->m_lowX; i < melFB->m_centerX; i++){
  207.             sum += m_MelWeight[i] * sigFFT[i];
  208. wsum += m_MelWeight[i];
  209. }
  210. for (i = melFB->m_centerX+1; i <= melFB->m_highX; i++){
  211.             sum += (1 - m_MelWeight[i-1]) * sigFFT[i];
  212. wsum += (1 - m_MelWeight[i-1]);
  213. }
  214.         output[k] = sum;
  215. if(normalize) {
  216. // assert(wsum>0);
  217. output[k] /= wsum;
  218. }
  219.     }
  220.     return;
  221. }
  222. int _filterbank_basic(float *sample, int frameSize, float *filter_bank, int fborder, int fftSize, int cep_smooth, int cepFilterLen)
  223. {
  224. int i;
  225. float* a=(float*)malloc(fftSize*4);
  226. float* b=(float*)malloc(fftSize*4);
  227. int uiLogFFTSize = (int)(log((double)fftSize)/log((double)2)+0.5);
  228. MfccInitMelFilterBanks ((float)64.0, (float)m_sampleRate, fftSize, fborder);
  229. for(i=0;i<frameSize;i++){ a[i] = sample[i]; b[i]=0; }
  230. for(i=frameSize;i<fftSize;i++) a[i] = b[i] = 0;
  231. PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, frameSize, 1);
  232. for(i=0;i<fftSize;i++){
  233. a[i] = a[i]*a[i] + b[i]*b[i];
  234. b[i] = 0.0;
  235. }
  236. MfccMelFilterBank (&a[0], fborder, &filter_bank[0], 1);
  237. for (i = 0; i < fborder; i++)
  238. filter_bank[i] = 0.5*LogE(filter_bank[i]);
  239. free(a);
  240. free(b);
  241. return(1);
  242. }
  243. void MfccDCT (float *x, float *dctMatrix, int ceporder, int numChannels, float *mel_cep)
  244. {
  245.     int i, j;
  246.     for (i = 0; i <= ceporder; i++) {
  247.         mel_cep[i] = 0.0;
  248.         for (j = 0; j < numChannels; j++){
  249.             mel_cep[i] += x[j] * dctMatrix[i * numChannels + j];
  250. }
  251.     }
  252.     return;
  253. }
  254. int main(int argc, char* argv[])
  255. {
  256. float mel_cep[12+1];
  257. short sample[512];
  258.     FILE*  fp;
  259. int templen;
  260. int i;
  261. //sample rate=32k 每个样点16BIT frame_size=512  fft_size=512  相邻两帧间重叠128个样点
  262. //滤波器个数=23  MFCC个数=12+1
  263. m_logEnergyFloor=FE_MIN_LOG_ENERGY;
  264. m_energyFloor=(float)exp(m_logEnergyFloor);
  265. if ((fp=fopen(argv[1],"rb"))==NULL)
  266. {
  267. printf("Open Errorn");
  268. }
  269. while ((templen=fread(sample,2,512,fp))==512)
  270. {
  271. mel_cepstrum_basic(sample, 512, mel_cep, 12,512);
  272. fseek(fp,-512,SEEK_CUR);
  273. }
  274. fclose(fp);
  275. printf("lastn");
  276.     for(i=0;i<13;i++)
  277. {
  278.    printf("%ft",mel_cep[i]);
  279. }
  280.     return 0;
  281. }