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

语音合成与识别

开发平台:

Matlab

  1. function [x1,x2] = vad(x)
  2. %幅度归一化到[-1,1]
  3. x = double(x);
  4. x = x / max(abs(x));
  5. %常数设置
  6. FrameLen = 240;
  7. FrameInc = 80;
  8. amp1 = 10;
  9. amp2 = 2;
  10. zcr1 = 10;
  11. zcr2 = 5;
  12. maxsilence = 8;  % 6*10ms  = 30ms
  13. minlen  = 15;    % 15*10ms = 150ms
  14. status  = 0;
  15. count   = 0;
  16. silence = 0;
  17. %计算过零率
  18. tmp1  = enframe(x(1:end-1), FrameLen, FrameInc);
  19. tmp2  = enframe(x(2:end)  , FrameLen, FrameInc);
  20. signs = (tmp1.*tmp2)<0;
  21. diffs = (tmp1 -tmp2)>0.2;
  22. zcr   = sum(signs.*diffs, 2);
  23. %计算短时能量
  24. amp = sum(abs(enframe(filter([1 -0.9375], 1, x), FrameLen, FrameInc)), 2);
  25. %调整能量门限
  26. amp1 = min(amp1, max(amp)/4);
  27. amp2 = min(amp2, max(amp)/8);
  28. %开始端点检测
  29. x1 = 0; 
  30. x2 = 0;
  31. for n=1:length(zcr)
  32.    goto = 0;
  33.    switch status
  34.    case {0,1}                   % 0 = 静音, 1 = 可能开始
  35.       if amp(n) > amp1          % 确信进入语音段
  36.          x1 = max(n-count-1,1);
  37.          status  = 2;
  38.          silence = 0;
  39.          count   = count + 1;
  40.       elseif amp(n) > amp2 | ... % 可能处于语音段
  41.              zcr(n) > zcr2
  42.          status = 1;
  43.          count  = count + 1;
  44.       else                       % 静音状态
  45.          status  = 0;
  46.          count   = 0;
  47.       end
  48.    case 2,                       % 2 = 语音段
  49.       if amp(n) > amp2 | ...     % 保持在语音段
  50.          zcr(n) > zcr2
  51.          count = count + 1;
  52.       else                       % 语音将结束
  53.          silence = silence+1;
  54.          if silence < maxsilence % 静音还不够长,尚未结束
  55.             count  = count + 1;
  56.          elseif count < minlen   % 语音长度太短,认为是噪声
  57.             status  = 0;
  58.             silence = 0;
  59.             count   = 0;
  60.          else                    % 语音结束
  61.             status  = 3;
  62.          end
  63.       end
  64.    case 3,
  65.       break;
  66.    end
  67. end   
  68. count = count-silence/2;
  69. x2 = x1 + count -1;