关于vad_ezm1端点检测的问题《MATLAB在语音信号分析和合成中的应用》(含第二版)

该文详细解释了一段语音处理代码,涉及初始化参数如maxsilence和minlen的作用,以及如何通过状态机进行静音、语音段的检测。代码中的变量如x1、x2用于标记语音段的起始和结束,el变量调整确保正确处理长静音情况。此外,还讨论了如何处理录音结束异常的情况。
摘要由CSDN通过智能技术生成

1.一开始对于书中的初始化参数不是很理解:

特别是:

maxsilence = 15;                        % 初始化
minlen  = 5;    
status  = 0;
count   = 0;
silence = 0;
其中maxsilence是一段语音结束时静音区的最小长度。

minlen=minlin是有话段的最小长度。

status表示静音、语音段、结束标准。

count 是一个列表(python用习惯了),比如count(1)表示第一次检测到的有话段目前的有话的长度,所以后面才有不断的 count(xn)   = count(xn) + 1操作(所以xn=1时候,里面的xn就是表示目前是检测到第一组有话段),就是检测到一个样本点是有话的,那就自己+1。

silence也是一个列表,和count差不多,也是表示目前检测到的静音部分的长度,有以后面才有(if silence(xn) < maxsilence    % 静音还不够长,语音尚未结束)的判断,就是前面书本说的第二级判决中F+问题。

2.后面的el变量那段的问题,有原贴回答:

关于第六章vad_ezm1函数中x1有话段开始位置的确定

页面重载开启解释双门限函数的一小部分开启

补充:

比如像使用了书本源代码运行后,结果:

(1)x1、x2变量都是第四个是0,是因为这个音频尾部有很长的静音 ,所以在前面的开始端点检测的for循环中,检测到第3组的结束点后,运行到了case 3,x1和x2都会同时被置0,表示语音结束,为下一段准备,这个时候可能循环没有结束,但是会一直在case{0,1}中,表示这一段都是静音。这样运行了

if x1(el)==0, el=el-1; end              % 获得x1的实际长度

这一步后,相当于把第4组的x1,x2都删除了,看起来是只删除了x1,但是实际上因为有el=el-1这个操作,后面的循环

 这里相当于不考虑第4组了,也就是课本案例的情况(后面好长的静音)。

(2)关于这段

if x2(el)==0                            % 如果x2最后一个值为0,对它设置为fn
    fprintf('Error: Not find endding point!\n');
    x2(el)=fn;
end

就是消除那种“LZ录制的语音出现Error: Not find endding point,这主要在语音的结束部分不是无话段,即在语音没有完全结束时就终断了录音。LZ可以对已录制的语音读入后在最后补上几帧0值。”

意思就是倒数第一次循环

 会进入case {0,1},if amp(n) > amp1或者elseif amp(n) > amp2 | ...        % 可能处于语音段zcr(n) > zcr2,继续最后一次循环,这个时候n=fn,循环结束,但是x2还是保持0(从确认最后一组语音开始点开始,先一直保持0)

3.以上代码均来自书本

function [voiceseg,vsl,SF,NF]=vad_ezm1(x,wlen,inc,NIS)
x=x(:);                                 % 把x转换成列数组
maxsilence = 15;                        % 初始化
minlen  = 5;    
status  = 0;
count   = 0;
silence = 0;

y=enframe(x,wlen,inc)';                 % 分帧
fn=size(y,2);                           % 帧数
amp=sum(y.^2);                          % 求取短时平均能量
zcr=zc2(y,fn);                          % 计算短时平均过零率
ampth=mean(amp(1:NIS));                 % 计算初始无话段区间能量和过零率的平均值               
zcrth=mean(zcr(1:NIS));
amp2=2*ampth; amp1=4*ampth;             % 设置能量和过零率的阈值
zcr2=2*zcrth;

%开始端点检测
xn=1;
for n=1:fn
   switch status
   case {0,1}                           % 0 = 静音, 1 = 可能开始
      if amp(n) > amp1                  % 确信进入语音段
         x1(xn) = max(n-count(xn)-1,1);
         status  = 2;
         silence(xn) = 0;
         count(xn)   = count(xn) + 1;
      elseif amp(n) > amp2 | ...        % 可能处于语音段
             zcr(n) > zcr2
         status = 1;
         count(xn)  = count(xn) + 1;
      else                              % 静音状态
         status  = 0;
         count(xn)   = 0;
         x1(xn)=0;
         x2(xn)=0;
      end
   case 2,                              % 2 = 语音段
      if amp(n) > amp2 & ...            % 保持在语音段
         zcr(n) > zcr2
         count(xn) = count(xn) + 1;
      else                              % 语音将结束
         silence(xn) = silence(xn)+1;
         if silence(xn) < maxsilence    % 静音还不够长,语音尚未结束
            count(xn)  = count(xn) + 1;
         elseif count(xn) < minlen      % 语音长度太短,认为是静音或噪声
            status  = 0;
            silence(xn) = 0;
            count(xn)   = 0;
         else                           % 语音结束
            status  = 3;
            x2(xn)=x1(xn)+count(xn);
         end
      end
   case 3,                              % 语音结束,为下一个语音准备
        status  = 0;          
        xn=xn+1; 
        count(xn)   = 0;
        silence(xn)=0;
        x1(xn)=0;
        x2(xn)=0;
   end
end 

el=length(x1);             
if x1(el)==0, el=el-1; end              % 获得x1的实际长度
if x2(el)==0                            % 如果x2最后一个值为0,对它设置为fn
    fprintf('Error: Not find endding point!\n');
    x2(el)=fn;
end
SF=zeros(1,fn);                         % 按x1和x2,对SF和NF赋值
NF=ones(1,fn);
for i=1 : el
    SF(x1(i):x2(i))=1;
    NF(x1(i):x2(i))=0;
end
speechIndex=find(SF==1);                % 计算voiceseg
voiceseg=findSegment(speechIndex);
vsl=length(voiceseg);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值