endpoint_b.m
上传用户:ay_070428
上传日期:2014-12-04
资源大小:11427k
文件大小:5k
源码类别:

语音合成与识别

开发平台:

Matlab

  1. function out = endpoint(y, fs, plotOpt, epdParam)
  2. % ENDPOINT End point detection
  3. if nargin==0, selfdemo; return; end
  4. if nargin<4,
  5. epdParam.frameSize = 256;
  6. epdParam.overlap = 86;
  7. epdParam.deltaEnergyLevel1 = -28;
  8. epdParam.deltaEnergyLevel2 = -14;
  9. epdParam.zcrRatio = 0.5;
  10. end
  11. if nargin<3, plotOpt=0; end
  12. if nargin<2, fs=8000; end
  13. frameSize=epdParam.frameSize;
  14. overlap=epdParam.overlap;
  15. deltaEnergyLevel1=epdParam.deltaEnergyLevel1;
  16. deltaEnergyLevel2=epdParam.deltaEnergyLevel2;
  17. zcrRatio=epdParam.zcrRatio;
  18. % ====== Zero adjusted
  19. y = y-mean(y);
  20. %wavplay(y, fs, 'sync');
  21. % ====== Take frames
  22. framedY  = buffer(y, frameSize, overlap);
  23. frameNum = size(framedY, 2); % Number of frames
  24. % ====== Compute log energy
  25. meanFrame = (mean(framedY.^2));
  26. meanFrame(meanFrame==0) = eps;
  27. energy = 10*log10(meanFrame);
  28. time = (1:frameNum)*(frameSize-overlap)/fs;
  29. energyLevel1 = max(energy)+deltaEnergyLevel1;
  30. energyLevel2 = max(energy)+deltaEnergyLevel2;
  31. % ====== Compute zero crossing rate
  32. zcr = zcratemex(framedY);
  33. % ====== Find initial end points according energy level2 (upper level)
  34. voicedIndex = find(energy>=energyLevel2);
  35. zcrThreshold = max(zcr)*zcrRatio;
  36. sound = [];
  37. k = 1;
  38. sound(k).begin = voicedIndex(1);
  39. for i=2:length(voicedIndex)-1,
  40. if voicedIndex(i+1)-voicedIndex(i)>1,
  41. sound(k).end = voicedIndex(i);
  42. sound(k+1).begin = voicedIndex(i+1);
  43. k = k+1;
  44. end
  45. end
  46. sound(k).end = voicedIndex(end);
  47. % ====== Delete short sound clips
  48. index = [];
  49. for i=1:length(sound),
  50. if (sound(i).end-sound(i).begin)<5
  51. index = [index, i];
  52. end
  53. end
  54. sound(index) = [];
  55. %minIndex = localmax(-energy); % Find index of local minima
  56. % ====== Expand end points to energy level1 (lower level)
  57. for i=1:length(sound),
  58. head = sound(i).begin;
  59. % while (head-1)>=1 & energy(head-1)>energyLevel1 & ~minIndex(head-1),
  60. while (head-1)>=1 & energy(head-1)>energyLevel1,
  61. head=head-1;
  62. end
  63. sound(i).begin = head;
  64. tail = sound(i).end;
  65. % while (tail+1)<=length(energy) & energy(tail+1)>energyLevel1 & ~minIndex(tail+1),
  66. while (tail+1)<=length(energy) & energy(tail+1)>energyLevel1,
  67. tail=tail+1;
  68. end
  69. sound(i).end = tail;
  70. end
  71. % ====== Expand end points to include high zcr region
  72. for i=1:length(sound),
  73. head = sound(i).begin;
  74. while (head-1)>=1 & zcr(head-1)>zcrThreshold,
  75. head=head-1;
  76. end
  77. sound(i).begin = head;
  78. end
  79. % ====== Delete repeated sound segments
  80. if length(sound) ~=0,
  81. index = [];
  82. for i=1:length(sound)-1,
  83. if sound(i).begin==sound(i+1).begin & sound(i).end==sound(i+1).end,
  84. index=[index, i];
  85. end
  86. end
  87. sound(index) = [];
  88. end;
  89. % ====== Transform sample-point-based index
  90. if length(sound) ~=0,
  91. for i=1:length(sound),
  92. out(i).begin = sound(i).begin*(frameSize-overlap);
  93. out(i).end   = min(length(y), sound(i).end*(frameSize-overlap));
  94. end
  95. else
  96.    out = [];
  97. end;
  98. if plotOpt,
  99. subplot(3,1,1);
  100. plot((1:length(y))/fs, y);
  101. axis([-inf inf -1 1]);
  102. ylabel('Amplitude');
  103. title('Wave form');
  104. subplot(3,1,2);
  105. plot(time, energy);
  106. line([min(time), max(time)], energyLevel1*[1 1], 'color', 'c');
  107. line([min(time), max(time)], energyLevel2*[1 1], 'color', 'c');
  108. axis tight
  109. ylabel('Log energy (dB)');
  110. title('Log energy');
  111. subplot(3,1,3);
  112. plot(time, zcr);
  113. line([min(time), max(time)], zcrThreshold*[1 1], 'color', 'c');
  114. axis([-inf inf 0 inf]);
  115. ylabel('ZCR');
  116. title('Zero crossing rate');
  117. % Plot end points
  118. subplot(3,1,1);
  119. yBound = [-1 1];
  120. for i=1:length(sound),
  121. line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r');
  122. line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g');
  123. end
  124. % Plot end points
  125. subplot(3,1,2);
  126. yBound = [min(energy) max(energy)];
  127. for i=1:length(sound),
  128. line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r');
  129. line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g');
  130. end
  131. % Plot end points
  132. subplot(3,1,3);
  133. yBound = [0 max(zcr)];
  134. for i=1:length(sound),
  135. line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r');
  136. line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g');
  137. end
  138. % Play the segmented sound
  139. fprintf('%g sound clips are collected.n', length(sound));
  140. for i=1:length(sound),
  141. head = sound(i).begin*(frameSize-overlap);
  142. tail = min(length(y), sound(i).end*(frameSize-overlap));
  143. thisY = y(head:tail);
  144. fprintf('His return to hear the cutted sound %g:', i);
  145. pause;
  146. fprintf('n');
  147. wavplay(thisY, fs, 'sync');
  148. end
  149. fprintf('n');
  150. end
  151. % ====== Self demo
  152. function selfdemo
  153. epdParam.frameSize = 256;
  154. epdParam.overlap = 86;
  155. epdParam.deltaEnergyLevel1 = -28;
  156. epdParam.deltaEnergyLevel2 = -14;
  157. epdParam.zcrRatio = 0.5;
  158. fs = 8000;
  159. duration = 3;
  160. plotOpt = 1;
  161. %y = recsound('test.wav', duration, fs);
  162. [y, fs] = wavreadc('wavefile/1Roger/