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

语音合成与识别

开发平台:

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. typedef CPolynomial<float> Polynomial;
  11. typedef Complex<float> CComplex;
  12. int Fe::fftcep_spectrum_basic(short *sample, int frameSize, float *spectrum, int fftSize, int cepFilterLen)
  13. {
  14. _fft_spectrum_basic(sample, frameSize, spectrum, fftSize, 1, cepFilterLen);
  15. return 1;
  16. }
  17. int Fe::lpc_basic(short *sample, int frameSize, float *acf, int norder, float *G)
  18. {
  19. vector<float> frameA(frameSize);
  20. preprocessing(sample, frameSize, &frameA[0]);
  21. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  22. _lpc_basic(&frameA[0], frameSize, acf, norder, G);
  23. return(1);
  24. }
  25. int Fe::lpc_cov_basic(short *sample, int frameSize, float *acf, int norder, float *G)
  26. {
  27. vector<float> frameA(frameSize);
  28. for(int i=0;i<frameSize;i++) frameA[i]=sample[i];
  29. FeMatrix<float> cov(norder+1, norder+1);
  30. lpc_cov(&frameA[0], frameSize, cov, acf, norder, G);
  31. return(1);
  32. }
  33. int Fe::parcor_basic(short *sample, int frameSize, float *kcf, int norder)
  34. {
  35. float G;
  36. vector<float> acf(norder+1);
  37. vector<float> frameA(frameSize);
  38. preprocessing(sample, frameSize, &frameA[0]);
  39. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  40. _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], kcf, norder, &G);
  41. return(1);
  42. }
  43. int Fe::lar_basic(short *sample, int frameSize, float *lar, int norder)
  44. {
  45. float G;
  46. vector<float> acf(norder+1);
  47. vector<float> kcf(norder+1);
  48. vector<float> frameA(frameSize);
  49. preprocessing(sample, frameSize, &frameA[0]);
  50. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  51. _lpc_parcor_basic(&frameA[0], frameSize, &acf[0], &kcf[0], norder, &G);
  52. lar[0] = 0;
  53. for(int i=1; i<= norder; i++){
  54. lar[i] = (float)log((1-kcf[i])/(1+kcf[i]));
  55. }
  56. return(1);
  57. }
  58. int Fe::lpc_spectrum_basic(short *sample, int frameSize, int norder, float *spectrum, int fftSize)
  59. {
  60. int i;
  61. float G;
  62. vector<float> acf(fftSize);
  63. lpc_basic(sample, frameSize, &acf[0], norder, &G);
  64. int log2fftsize = (int)(log(fftSize)/log(2)+0.5);
  65. float logGdb = (G>0 ? 20*LOG10(G) : FE_MIN_LOG_ENERGY); /* power spectrum */
  66. acf[0] = 1;
  67. /* Note that the definition of a[] is y(n) = a(1)y(n-1) + a(2)y(n-2) + ... */
  68. for(i=1;i<=norder;i++) acf[i] = -acf[i];
  69. compute_spectrum(&acf[0], spectrum, norder+1, log2fftsize);
  70. /* Note that spectrum is in the power domain. */
  71. for(i=0;i<fftSize;i++){
  72. float db=(spectrum[i]>FE_MIN_ENERGY ? 10*LOG10(spectrum[i]) : 10*LOG10(FE_MIN_ENERGY));
  73. spectrum[i] = (float)(logGdb-db);
  74. }
  75. return(1);
  76. }
  77. int Fe::lpccep_spectrum_basic(short *sample, int frameSize, int ceporder, int norder, float *spectrum, int fftSize)
  78. {
  79. int i;
  80. float G;
  81. vector<float> acf(fftSize);
  82. lpc_basic(sample, frameSize, &acf[0], norder, &G);
  83. vector<float> lpc_cep(fftSize);
  84. lpc_to_cepstrum(&acf[0], norder, &lpc_cep[0], ceporder, G);
  85. lpc_cep[0] = 0.5*lpc_cep[0]; /* we need log magnitude because fft_pow will give power spectrum */
  86. int log2fftsize = (int)(log(fftSize)/log(2)+0.5);
  87. compute_spectrum(&lpc_cep[0], spectrum, ceporder+1, log2fftsize);
  88. /* need 10/log(10) to get dB scale because lpc_cep is in the natural log scale. */
  89. float log10db=(float)(10/log(10));
  90. for(i=0;i<fftSize;i++){
  91. spectrum[i] = log10db*spectrum[i];
  92. }
  93. return(1);
  94. }
  95. int Fe::melcep_spectrum_basic(short *sample, int frameSize, int ceporder, float *spectrum, int fftSize)
  96. {
  97. int i,k;
  98. vector<float> mel_cep(ceporder+1);
  99. mel_cepstrum_basic(sample, frameSize, &mel_cep[0], ceporder, fftSize);
  100. MfccIDCT (&mel_cep[0], &m_idctMatrix[0], ceporder, m_fbOrder, spectrum);
  101. /* scale up to be consistent with other kinds of cepstrum coefficients */
  102. float g=2*fftSize/(float)m_fbOrder;
  103. for(i=0;i<m_fbOrder;i++) spectrum[i] *= g;
  104. float log10db=(float)(10/log(10));
  105. for(i=m_fbOrder;i>=1;i--){
  106. int kmin=(m_MelCenterIdx[i-1]+m_MelCenterIdx[i])/2;
  107. int kmax=(m_MelCenterIdx[i]+m_MelCenterIdx[i+1])/2;
  108. for(k=kmin;k<kmax;k++) spectrum[k]=log10db*spectrum[i-1];
  109. }
  110. {
  111. int kmax=(m_MelCenterIdx[0]+m_MelCenterIdx[1])/2;
  112. for(k=0;k<kmax;k++) spectrum[k]=spectrum[m_MelCenterIdx[1]];
  113. int kmin=(m_MelCenterIdx[m_fbOrder]+m_MelCenterIdx[m_fbOrder+1])/2;
  114. for(k=kmin;k<=fftSize/2;k++) spectrum[k]=spectrum[m_MelCenterIdx[m_fbOrder]];
  115. }
  116. return(1);
  117. }
  118. int Fe::lpc_error_basic(short *sample, int frameSize, float *acf, int norder, float* residual)
  119. {
  120. int i,n;
  121. for(n=0;n<norder && n<frameSize;n++){
  122. short si;
  123. residual[n] = sample[n];
  124. for(i=1;i<=norder;i++){
  125. si = (n-i>=0) ? sample[n-i] : 0;
  126. residual[n] -= acf[i]*si;
  127. }
  128. }
  129. for(n=norder;n<frameSize;n++){
  130. residual[n] = sample[n];
  131. for(i=1;i<=norder;i++){
  132. residual[n] -= acf[i]*sample[n-i];
  133. }
  134. }
  135. return(1);
  136. }
  137. int Fe::formant_basic(short *sample, int frameSize, float *formant, int formantN, int norder)
  138. {
  139. float G;
  140. vector<float> acf(norder+1);
  141. lpc_basic(sample, frameSize, &acf[0], norder, &G);
  142. vector<CComplex> rootsA;
  143. int nf = lpc_to_formant(&acf[0], norder, formant, formantN, rootsA);
  144. for(int i=0; i<nf; i++)
  145. formant[i] *= (m_sampleRate/(float)(2*M_PI));
  146. return(1);
  147. }
  148. /*
  149. sigma2 = r[0] - sum_{k=1}^N {a[k]*r[k]}
  150. return value = G = sqrt(sigma2)
  151. */
  152. float Fe::calc_lpc_gain_basic(float *r, float *acf, int norder)
  153. {
  154. int i;
  155. float sigma2 = r[0];
  156. for(i=1; i<=norder; i++){
  157. sigma2 -= acf[i]*r[i];
  158. }
  159. return (float)sqrt(sigma2);
  160. }
  161. int Fe::_lpc_parcor_basic(float *sample, int frameSize, float *acf, float *kcf, int norder, float *G)
  162. {
  163. int i, winSize;
  164. vector<float> r(norder+1);
  165. vector<float> rorg(norder+1);
  166. winSize = frameSize;
  167. {
  168. auto_correlation(sample, &r[0], frameSize, norder);
  169. for(i=0; i<=norder; i++) rorg[i] = r[i];
  170. /* solving the autocorrelation matrix */
  171. levins(&r[0], kcf, acf, norder);
  172. /* just for completeness */
  173. kcf[0] = 0;
  174. acf[0] = 1;
  175. /* G denotes LPC gain G */
  176. if(G) (*G) = calc_lpc_gain_basic(&rorg[0], acf, norder);
  177. }
  178. return(1);
  179. }
  180. /*
  181. H(z) = G / (1 - sum_{i=1}^N {a[i]*z^{-i}} )
  182. acf[0] = G, acf[i] = a[i], i=1,...,N
  183. */
  184. int Fe::_lpc_basic(float *sample, int frameSize, float *acf, int norder, float *G)
  185. {
  186. int i, winSize;
  187. vector<float> r(norder+1);
  188. vector<float> rorg(norder+1);
  189. vector<float> kcf(norder+1);
  190. winSize = frameSize;
  191. {
  192. auto_correlation(sample, &r[0], frameSize, norder);
  193. for(i=0; i<=norder; i++) rorg[i] = r[i];
  194. /* solving the autocorrelation matrix */
  195. levins(&r[0], &kcf[0], acf, norder);
  196. /* just for completeness */
  197. kcf[0] = 0; 
  198. acf[0] = 1;
  199. /* G denotes LPC gain G */
  200. if(G) (*G) = calc_lpc_gain_basic(&rorg[0], acf, norder);
  201. }
  202. return(1);
  203. }
  204. int Fe::_lpc_error_basic(float *sample, int frameSize, float *acf, int norder, float* residual)
  205. {
  206. int i,n;
  207. for(n=0;n<norder && n<frameSize;n++){
  208. float si;
  209. residual[n] = sample[n];
  210. for(i=1;i<=norder;i++){
  211. si = (n-i>=0) ? sample[n-i] : 0;
  212. residual[n] -= acf[i]*si;
  213. }
  214. }
  215. for(n=norder;n<frameSize;n++){
  216. residual[n] = sample[n];
  217. for(i=1;i<=norder;i++){
  218. residual[n] -= acf[i]*sample[n-i];
  219. }
  220. }
  221. return(1);
  222. }
  223. /* preprocessing */
  224. int Fe::preprocessing(short *sample, int sampleN, float *out)
  225. {
  226. for(int i=0;i<sampleN;i++) out[i]=sample[i];
  227. if (m_dither) Dither(out, sampleN);
  228. preemphasize(out, sampleN, m_emphFac);
  229. return 1;
  230. }
  231. /* energy */
  232. float Fe::compute_energy(float *sample, int sampleN, float mean)
  233. {
  234. float sum = 0;
  235. for(int i=0; i<sampleN; i++){
  236. sum += (sample[i]-mean)*(sample[i]-mean);
  237. }
  238. float v=((sampleN>0) ? sum/sampleN : (float)0);
  239. v = v+1; /* to make happy feature extraction and analysis routines */
  240. return v;
  241. }
  242. /* zero crossing rate */
  243. int Fe::compute_zero_cross_rate(float *sample, int sampleN, int level, int dc_bias)
  244. {
  245. if(sampleN<1) return 0;
  246. int zcr=0;
  247. float prev = sample[0]-dc_bias-level;
  248. for(int i=1; i<sampleN; i++) {
  249. float val  = sample[i]-dc_bias-level;
  250. float ztmp=val*prev;
  251. if(ztmp<0) zcr++;
  252. prev=val;
  253. }
  254. return zcr;
  255. }
  256. /* cepstral weighting */
  257. /* cepstral coefficients are ordered as [c0, c1, c2, ..., c12] */
  258. int Fe::cepstral_window(float *cep, int ceporder, FeLifter lifter)
  259. {
  260. int i;
  261. switch(lifter){
  262. case LIFT_NO:
  263. break;
  264. case LIFT_SIN:
  265. for (i=0; i<=ceporder; i++)
  266. cep[i] *= (float)(1. + (float)ceporder/2. * sin((M_PI*(i+1))/(float)ceporder));
  267. break;
  268. case LIFT_LINEAR:
  269. for (i=0; i<=ceporder; i++)
  270. cep[i] *= (i+1);
  271. break;
  272. case LIFT_SQRT:
  273. for (i=0; i<=ceporder; i++)
  274. cep[i] *= (float)sqrt(i+1);
  275. break;
  276. case LIFT_CUBE_ROOT:
  277. for (i=0; i<=ceporder; i++)
  278. cep[i] *= (float)pow(i+1,1/3.0);
  279. break;
  280. }
  281. return(1);
  282. }
  283. /* in-place preemphasis */
  284. int Fe::preemphasize(float *sample, int sampleN, float emphFac)
  285. {
  286. /* Setting emphFac=0 turns off preemphasis. */
  287. int i;
  288. for (i = sampleN-1; i > 0; i--) {
  289. sample[i] = sample[i] - emphFac * sample[i-1];
  290. }
  291. sample[0] = (float)(1.0 - emphFac) * sample[0];
  292. return(1);
  293. }