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

语音合成与识别

开发平台:

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" #include "FE_feature.h"
  9. int Fe::fft_spectrum_basic(short *sample, int frameSize, float *spectrum, int fftSize)
  10. {
  11. _fft_spectrum_basic(sample, frameSize, spectrum, fftSize, 0, 0);
  12. return 1;
  13. }
  14. int Fe::_fft_spectrum_basic(short *sample, int frameSize, float *spectrum, int fftSize, int cep_smooth, int cepFilterLen)
  15. {
  16. int i;
  17. vector<float> frameA(frameSize);
  18. vector<float> power(fftSize);
  19. for(i=0;i<frameSize;i++) frameA[i]=sample[i];
  20. preemphasize(&frameA[0], frameSize, m_emphFac);
  21. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  22. int uiLogFFTSize = (int)(log((double)fftSize)/log((double)2)+0.5);
  23. compute_spectrum(&frameA[0], &power[0], frameSize, uiLogFFTSize);
  24. float log10db=(float)10/log(10);
  25. for(i=0;i<(int)fftSize;i++)
  26. spectrum[i] = log10db*LogE(power[i]);
  27. if(cep_smooth) {
  28. vector<float> a(fftSize);
  29. vector<float> b(fftSize);
  30. for(i=0;i<fftSize;i++){
  31. a[i] = spectrum[i];
  32. b[i] = 0;
  33. }
  34. PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, fftSize, -1);
  35. if(cepFilterLen <= 0) cepFilterLen = 1;
  36. for (i=cepFilterLen ; i < fftSize-(cepFilterLen-1); i++){
  37. a[i] = b[i] = 0;
  38. }
  39. for(i=fftSize-1;i>fftSize/2;i--){
  40. a[i] = a[fftSize-i];
  41. b[i] = b[fftSize-i];
  42. }
  43.      PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, fftSize, 1) ;
  44. for (i=0 ; i < m_fftSize; i++) 
  45. spectrum[i] = a[i];
  46. }
  47. return 1;
  48. }
  49. int Fe::fft_cepstrum_basic(short *sample, int frameSize, float *fft_cep, int ceporder, int fftSize)
  50. {
  51. vector<float> frameA(frameSize);
  52. preprocessing(sample, frameSize, &frameA[0]);
  53. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  54. _fft_cepstrum_basic(&frameA[0],frameSize,fft_cep,ceporder,fftSize);
  55. cepstral_window(fft_cep, ceporder, m_lifter);
  56. /* owkwon: To make dynamic range consistent with other kinds of cepstral coefficients */
  57. /* Needs further study */
  58. for (int i=0;i<=ceporder;i++) fft_cep[i] /= 8;
  59. return 1;
  60. }
  61. int Fe::_fft_cepstrum_basic(float *sample, int frameSize, float *fft_cep, int ceporder, int fftSize)
  62. {
  63. int i;
  64. int uiLogFFTSize = (int)(log((double)fftSize)/log((double)2)+0.5);
  65. vector<float> a(fftSize);
  66. vector<float> b(fftSize);
  67. for(i=0;i<frameSize;i++){ a[i] = sample[i]; b[i]=0; }
  68. for(i=frameSize;i<fftSize;i++) a[i] = b[i] = 0;
  69. PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, frameSize, 1);
  70. for(i=0;i<fftSize;i++){
  71. a[i] = (float)(0.5*LogE(a[i]*a[i]+b[i]*b[i]));
  72. b[i] = 0;
  73. }
  74. PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, fftSize, -1);
  75. for(i=0;i<=ceporder;i++) fft_cep[i] = a[i];
  76. return 1;
  77. }
  78. int Fe::filterbank_basic(short *sample, int frameSize, float *filter_bank, int fborder, int fftSize)
  79. {
  80. vector<float> frameA(frameSize);
  81. preprocessing(sample, frameSize, &frameA[0]);
  82. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  83. _filterbank_basic(&frameA[0], frameSize, filter_bank, fborder, fftSize, m_cepSmooth, (int)(m_sampleRate/MAX_PITCH_FREQ));
  84. /* Convert to dB scale */
  85. float log10db=(float)(10/log(10));
  86. for(int i=0;i<fborder;i++) filter_bank[i]*=log10db;
  87. return 1;
  88. }
  89. int Fe::_filterbank_basic(float *sample, int frameSize, float *filter_bank, int fborder, int fftSize, int cep_smooth, int cepFilterLen)
  90. {
  91. if(m_MelFB.size() != fborder || fftSize != m_MelFBfftSize){
  92. m_MelFBfftSize=fftSize;
  93. MfccInitMelFilterBanks ((float)64.0, (float)m_sampleRate, fftSize, fborder);
  94. }
  95. int i;
  96. int uiLogFFTSize = (int)(log((double)fftSize)/log((double)2)+0.5);
  97. vector<float> a(fftSize);
  98. vector<float> b(fftSize);
  99. for(i=0;i<frameSize;i++){ a[i] = sample[i]; b[i]=0; }
  100. for(i=frameSize;i<fftSize;i++) a[i] = b[i] = 0;
  101. PRFFT_NEW( &a[0], &b[0], uiLogFFTSize, frameSize, 1);
  102. for(i=0;i<fftSize;i++){
  103. a[i] = a[i]*a[i] + b[i]*b[i];
  104. b[i] = 0.0;
  105. }
  106. MfccMelFilterBank (&a[0], fborder, &filter_bank[0], 1);
  107. for (i = 0; i < fborder; i++) filter_bank[i] = 0.5*LogE(filter_bank[i]);
  108. return(1);
  109. }
  110. int Fe::compute_spectrum(float *input, float *spectrum, int winlength, int log2length) 
  111. {
  112.   int i, log2length_i;
  113.   int npoints, npoints2;
  114.   npoints  = (int) (pow(2.0,(float) log2length) + 0.5);
  115.   npoints2 = npoints / 2;
  116.   vector<FeComplex> complex_in(npoints);
  117.   for(i=0;i<winlength;i++){
  118.     complex_in[i].m_re = input[i];
  119.     complex_in[i].m_im = (float)0.0;
  120.   }
  121.   for(i = winlength; i < npoints; i++){
  122.     complex_in[i].m_re = (float)0.0;
  123.     complex_in[i].m_im = (float)0.0;
  124.   }
  125.   log2length_i = (int)log2length;
  126.   FAST_new(&complex_in[0],log2length_i);
  127.   
  128.   spectrum[0] = complex_in[0].m_re * complex_in[0].m_re;
  129.   spectrum[npoints2] = complex_in[npoints2].m_re * complex_in[npoints2].m_re;
  130.   /*
  131.     Only the first half of the spectrum[] array is filled with data.
  132.     The second half is just a reflection of the first half.
  133.   */
  134.   for(i=1;i<npoints2;i++){
  135.     spectrum[i] = complex_in[i].m_re * complex_in[i].m_re + complex_in[i].m_im * complex_in[i].m_im;
  136.   }
  137.   for(i=npoints-1;i>npoints2;i--){
  138.   spectrum[i] = spectrum[npoints-i];
  139.   }
  140.   return(0);
  141. }
  142. int Fe::smooth_spectrum(float *spectrum, int pointsN)
  143. {
  144. vector<float> tmp(pointsN);
  145. tmp[0]=spectrum[0];
  146. tmp[1]=(2*spectrum[1]+spectrum[0]+spectrum[2])/(float)4;
  147. for(int i=2;i<pointsN-2;i++){
  148. tmp[i]=(float)(4*spectrum[i]+2*spectrum[i-1]+2*spectrum[i+1]+spectrum[i-2]+spectrum[i+2])/(float)10;
  149. }
  150. tmp[pointsN-2]=(2*spectrum[pointsN-2]+spectrum[pointsN-3]+spectrum[pointsN-1])/(float)4;
  151. tmp[pointsN-1]=spectrum[pointsN-1];
  152. memmove(spectrum, &tmp[0], sizeof(float)*pointsN);
  153. return(1);
  154. }
  155. /*========================================================================
  156. ** Discrete Fourier analysis routine
  157. ** from IEEE Programs for Digital Signal Processing
  158. ** G. D. Bergland and M. T. Dolan, original authors
  159. ** Translated from the FORTRAN with some changes by Paul Kube
  160. ** Modified to return the power spectrum by Chuck Wooters
  161. ========================================================================*/
  162. /**************************************************************************
  163. FAST_new - In-place radix 2 decimation in time FFT
  164. Requires pointer to complex array, x and power of 2 size of FFT, m
  165. (size of FFT = 2**m).  Places FFT output on top of input FeComplex array.
  166. void FAST_new(FeComplex *x, int m)
  167. *************************************************************************/
  168. void Fe::FAST_new(FeComplex *x, int m)
  169. {
  170.     FeComplex u,temp,tm;
  171.     FeComplex *xi,*xip,*xj,*wptr;
  172.     int i,j,k,l,le,windex;
  173.     double arg,w_real,w_imag,wrecur_real,wrecur_imag,wtemp_real;
  174. if(m == 0) return;       /* if m=0 then done */
  175. int n = 1 << m; /* length of fft */
  176.     if(n != m_fftW.size()) {
  177. m_fftW.resize(n); 
  178.         le = n/2;
  179. for(int nn=0;nn < le-1; nn++)
  180. m_fftW[nn].m_re = m_fftW[nn].m_im = (float)0.0;
  181.         arg = 4.0*atan(1.0)/le;
  182.         wrecur_real = w_real = cos(arg);
  183.         wrecur_imag = w_imag = -sin(arg);
  184.         xj = &m_fftW[0];
  185.         for (j = 1 ; j < le ; j++) {
  186.             xj->m_re = (float)wrecur_real;
  187.             xj->m_im = (float)wrecur_imag;
  188.             xj++;
  189.             wtemp_real = wrecur_real*w_real - wrecur_imag*w_imag;
  190.             wrecur_imag = wrecur_real*w_imag + wrecur_imag*w_real;
  191.             wrecur_real = wtemp_real;
  192.         }
  193.     }
  194.     le = n;
  195.     windex = 1;
  196.     for (l = 0 ; l < m ; l++) {
  197.         le = le/2;
  198.         for(i = 0 ; i < n ; i = i + 2*le) {
  199.             xi = x + i;
  200.             xip = xi + le;
  201.             temp.m_re = xi->m_re + xip->m_re;
  202.             temp.m_im = xi->m_im + xip->m_im;
  203.             xip->m_re = xi->m_re - xip->m_re;
  204.             xip->m_im = xi->m_im - xip->m_im;
  205.             *xi = temp;
  206.         }
  207.         wptr = &m_fftW[0] + windex - 1;
  208.         for (j = 1 ; j < le ; j++) {
  209.             u = *wptr;
  210.             for (i = j ; i < n ; i = i + 2*le) {
  211.                 xi = x + i;
  212.                 xip = xi + le;
  213.                 temp.m_re = xi->m_re + xip->m_re;
  214.                 temp.m_im = xi->m_im + xip->m_im;
  215.                 tm.m_re = xi->m_re - xip->m_re;
  216.                 tm.m_im = xi->m_im - xip->m_im;
  217.                 xip->m_re = tm.m_re*u.m_re - tm.m_im*u.m_im;
  218.                 xip->m_im = tm.m_re*u.m_im + tm.m_im*u.m_re;
  219.                 *xi = temp;
  220.             }
  221.             wptr = wptr + windex;
  222.         }
  223.         windex = 2*windex;
  224.     }
  225.     j = 0;
  226.     for (i = 1 ; i < (n-1) ; i++) {
  227.         k = n/2;
  228.         while(k <= j) {
  229.             j = j - k;
  230.             k = k/2;
  231.         }
  232.         j = j + k;
  233.         if (i < j) {
  234.             xi = x + i;
  235.             xj = x + j;
  236.             temp = *xj;
  237.             *xj = *xi;
  238.             *xi = temp;
  239.         }
  240.     }
  241. }
  242. /* pruned FFT */
  243. void PRFFT_NEW(float *a, float *b, int m, int n_pts, int iff)
  244. {
  245. int l,lmx,lix,lm,li,j1,j2,ii,jj,nv2,nm1,k,lmxy,n;
  246. float scl,s,c,arg,T_a,T_b;
  247. n = 1 << m;
  248. for( l=1 ; l<=m ; l++ ) {
  249. lmx = 1 << (m - l) ;
  250. lix = 2 * lmx ;
  251. scl = 2 * (float)M_PI/(float)lix ;
  252. if(lmx < n_pts) lmxy = lmx ;
  253. else lmxy = n_pts ;
  254. for( lm = 1 ; lm <= lmxy ; lm++ ) {
  255. arg=((float)(lm-1)*scl) ;
  256. c = (float)cos(arg) ;
  257. s = iff * (float)sin(arg) ;
  258. for( li = lix ; li <= n ; li += lix ) {
  259. j1 = li - lix + lm ;
  260. j2 = j1 + lmx ;
  261. if(lmxy != n_pts ) {
  262. T_a=a[j1-1] - a[j2-1] ;
  263. /* T_a : real part */
  264. T_b=b[j1-1] - b[j2-1] ;
  265. /* T_b : imaginary part */
  266. a[j1-1] = a[j1-1] + a[j2-1] ;
  267. b[j1-1] = b[j1-1] + b[j2-1] ;
  268. a[j2-1] = T_a*c + T_b*s ;
  269. b[j2-1] = T_b*c - T_a*s ;
  270. } else{
  271. a[j2-1] = a[j1-1]*c + b[j1-1]*s ;
  272. b[j2-1] = b[j1-1]*c - a[j1-1]*s ;
  273. }
  274. }
  275. }
  276. }
  277. nv2 = n/2 ;
  278. nm1 = n - 1 ;
  279. jj = 1 ;
  280. for( ii = 1 ; ii <= nm1 ;) {
  281. if( ii < jj ) {
  282. T_a = a[jj-1] ;
  283. T_b = b[jj-1] ;
  284. a[jj-1] = a[ii-1] ;
  285. b[jj-1] = b[ii-1] ;
  286. a[ii-1] = T_a ;
  287. b[ii-1] = T_b ;
  288. }
  289. k = nv2 ;
  290. while( k < jj ) {
  291. jj = jj - k ;
  292. k = k/2 ;
  293. }
  294. jj = jj + k ;
  295. ii = ii + 1 ;
  296. }
  297. if(iff == (-1)){
  298. for( l=0 ; l<n ; l++ ) {
  299. a[l]/=(float)n;
  300. b[l]/=(float)n;
  301. }
  302. }
  303. }