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

语音合成与识别

开发平台:

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. static const int SkipF = 16;
  11. static const int WinSize = 320;
  12. static const int MinPitchInterval = 40; // org=24.
  13. static const int MaxPitchInterval = 140;
  14. static const float VoiceThreshold = (float)0.05; // org=0.1
  15. static const int SamplesBetweenPeaks = 40; // For male=40. For female=20.
  16. int Fe::calc_epoch(float *sample, int sampleN, vector<short>& epoch, short* PitchPeriod)
  17. {
  18. int i,j,k;
  19. valarray<float> dataA(sampleN);
  20. valarray<int> len(3);
  21. valarray<float> dwt[3];
  22. valarray<float> a[3];
  23. float mean = 0;
  24. for(i=0;i<sampleN;i++) mean += sample[i];
  25. mean /= sampleN;
  26. for(i=0;i<sampleN;i++) dataA[i] = sample[i]-mean;
  27. /* init */
  28. for(k=0;k<3;k++){
  29. len[k] = SamplesBetweenPeaks*ipower(2,k);
  30. dwt[k].resize(sampleN+SamplesBetweenPeaks, 0);
  31. a[k].resize(WinSize+1, 0);
  32. for(i=0;i<=WinSize;i++){
  33. float x = M_PI*(i-len[k]/2)/(float)len[k];
  34. a[k][i] = ((i <= len[k]) ? (float)((0.48829*sin(2*x)+0.28256*sin(4*x)+0.03504*sin(6*x))*cos(x)*cos(x)) : (float)0);
  35. }
  36. }
  37. /* dwt */
  38. valarray<float> maxdwt((float)0, 3);
  39. for(k=0; k<3; k++){
  40. // first pass
  41. maxdwt[k] = (float)0;
  42. for(i=len[k];i<sampleN-len[k];i+=SkipF){
  43. dwt[k][i] = calc_DWT(&dataA[i-len[k]/2], &a[k][0], len[k]);
  44. if(dwt[k][i] > maxdwt[k]) maxdwt[k] = dwt[k][i];
  45. }
  46. // second pass
  47. float th = (float)0.8*maxdwt[k];
  48. int delta = (SkipF/4 > 0) ? SkipF/4 : 1;
  49. for(i=len[k];i<sampleN-len[k];i+=SkipF){
  50. if(dwt[k][i] < th) continue;
  51. for(j=i+delta;j<i+SkipF;j+=delta){
  52. dwt[k][j] = calc_DWT(&dataA[j-len[k]/2], &a[k][0], len[k]);
  53. if(dwt[k][j] > maxdwt[k]) maxdwt[k] = dwt[k][j];
  54. }
  55. }
  56. }
  57. /* peak */
  58. int bCanceled = 0;
  59. float pc0,pc1,pc2;
  60. vector<int> pc;
  61. pc.push_back(0);
  62. int epochN = 1;
  63. for(i=0;i<MinPitchInterval/2+3;i++) epoch[i] = 0;
  64. for(i=sampleN-3; i<sampleN; i++) epoch[i] = 0;
  65. epoch[0] = 10; // To show epoch clearly!
  66. pc0 = VoiceThreshold*maxdwt[0];
  67. pc1 = VoiceThreshold*maxdwt[1];
  68. pc2 = VoiceThreshold*maxdwt[2];
  69. for(i=MinPitchInterval/2+3;i<sampleN-3;i++){
  70. if(!CheckWinMessage()) {
  71. bCanceled = 1;
  72. break;
  73. }
  74. ShowProgress((int)((i*100)/sampleN));
  75. if(dwt[0][i] == 0) dwt[0][i] = calc_DWT(&dataA[i-len[0]/2], &a[0][0], len[0]);
  76. if(dwt[0][i-1] == 0) dwt[0][i-1] = calc_DWT(&dataA[i-1-len[0]/2], &a[0][0], len[0]);
  77. if(dwt[0][i+1] == 0) dwt[0][i+1] = calc_DWT(&dataA[i+1-len[0]/2], &a[0][0], len[0]);
  78. if((dwt[0][i]>=pc0) && (dwt[0][i]>=dwt[0][i-1]) && (dwt[0][i]>=dwt[0][i+1])){
  79. for(j=i-MinPitchInterval/2;j<=i+MinPitchInterval/2;j++){
  80. if(dwt[1][j] == 0) dwt[1][j] = calc_DWT(&dataA[j-len[1]/2], &a[1][0], len[1]);
  81. if(dwt[1][j-1] == 0) dwt[1][j-1] = calc_DWT(&dataA[j-1-len[1]/2], &a[1][0], len[1]);
  82. if(dwt[1][j+1] == 0) dwt[1][j+1] = calc_DWT(&dataA[j+1-len[1]/2], &a[1][0], len[1]);
  83. if((dwt[1][j]>=pc1) && (dwt[1][j]>=dwt[1][j-1]) && (dwt[1][j]>=dwt[1][j+1])){
  84. if(j-MinPitchInterval/2>=0){
  85. for(k=j-MinPitchInterval/2;k<=j+MinPitchInterval/2;k++){
  86. if(dwt[2][k] == 0) dwt[2][k] = calc_DWT(&dataA[k-len[2]/2], &a[2][0], len[2]);
  87. if(dwt[2][k-1] == 0) dwt[2][k-1] = calc_DWT(&dataA[k-1-len[2]/2], &a[2][0], len[2]);
  88. if(dwt[2][k+1] == 0) dwt[2][k+1] = calc_DWT(&dataA[k+1-len[2]/2], &a[2][0], len[2]);
  89. if((dwt[2][k]>=pc2) && (dwt[2][k]>=dwt[2][k-1]) && (dwt[2][k]>=dwt[2][k+1])){
  90. if(i-pc[epochN-1]<=MinPitchInterval){
  91. //printf("Too narrown");
  92. if(dwt[0][i]>dwt[0][pc[epochN-1]]){
  93. epoch[i]=7;
  94. epoch[pc[epochN-1]]=0;
  95. //printf("reset t=%f,j=%d,k=%dn",pc[epochN-1]/16000.0,j,k);
  96. pc[epochN-1]=i;
  97. //printf("t=%f,j=%d,k=%dn",i/16000.0,j,k);
  98. }
  99. else{
  100. epoch[i]=0;
  101. //printf("set zero t=%f,j=%d,k=%dn",i/16000.0,j,k);
  102. }
  103. }
  104. else{
  105. epoch[i]=7;
  106. pc.push_back(i);
  107. epochN++;
  108. //printf("t=%f,j=%d,k=%dn",i/16000.0,j,k);
  109. }
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. else{
  117. epoch[i]=0;
  118. }
  119. }
  120. /* pitch */
  121. if(PitchPeriod){
  122. for(i=0;i<sampleN;i++) PitchPeriod[i] = 0;
  123. for(i=1;i<=epochN;i++){
  124. if((pc[i]-pc[i-1]>=MinPitchInterval) && (pc[i]-pc[i-1]<=MaxPitchInterval))
  125. for(k=pc[i-1]; k<pc[i]; k++)
  126. PitchPeriod[k] = pc[i]-pc[i-1];
  127. }
  128. }
  129. return sampleN;
  130. }
  131. float Fe::calc_DWT(float *sample, float *a, int len)
  132. {
  133. int k;
  134. float sum = 0;
  135. for(k=0;k<len/2;k++)
  136. sum += sample[k]*a[k];
  137. if(sum < 0) return (float)(-len);
  138. for(k=len/2;k<=len;k++)
  139. sum += sample[k]*a[k];
  140. return sum/100;
  141. }