码迷,mamicode.com
首页 > 其他好文 > 详细

离线版-端点检测代码重写

时间:2015-04-18 08:54:31      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:端点检测 vad 汉字切分

      根据对双门限的理解和修改,重写了一个离线版端点检测。

 

技术分享  

技术分享
function [st,en]=VAD(x, fs)
x=double(x);
x=x/max(abs(x));
framelen= floor(fs*40/1000);%
frameinc= floor(fs*10/1000);%
y=enframe(x,framelen,frameinc);
%计算短时间能量 
amp=sum(abs(y),2);    
%开始端点检测
tmp1=enframe(x(1:length(x)-1),framelen,frameinc);
tmp2=enframe(x(2:length(x)),framelen,frameinc);
signs=(tmp1.*tmp2)<0;    %
diffs=(tmp1-tmp2)>0.01;
zcr=sum(signs.*diffs,2);  %    
zcr=[zcr;zcr(end)];
zcr_yu=0.2*mean(zcr);%
yuzhi=0.2*mean(amp);%
minspeech=10;
count=0;%
start=[];
tail=[];
N=length(amp);
flag=0;%


biaozhi2=0;
biaozhi3=0;
%%%%%%%%%%%%
for n=1:N 
    if amp(n)<yuzhi || (zcr(n)<zcr_yu)
        continue;
    end
    kaitou=n;
    break;
end
for n=N:-1:1
    if amp(n)<yuzhi || (zcr(n)<zcr_yu)
        continue;
    end
    jiewei=n;
    break;
end
noise=[amp(1:kaitou-1);amp(jiewei+1:end)];
noise_mean=mean(noise);
noise_var = std(noise);
speech_mean=mean(amp(kaitou:jiewei));%noise_mean
yuzhi1= 0.3*speech_mean; %
yuzhi2= max(0.3*speech_mean , (noise_mean + noise_var)*1.3);%



noise_zcr=[zcr(1:kaitou-1);zcr(jiewei+1:end)];
noise_zcr_mean = mean(noise_zcr);
noise_zcr_std = std(noise_zcr);
speech_zcr_mean=mean(zcr(kaitou:jiewei));
zcr_yu1 = 0.3*speech_zcr_mean;
zcr_yu2 = max(0.3*speech_zcr_mean , (noise_zcr_mean+noise_zcr_std)*0.3);
%%%%%%%%%%%%%%

st = [];
en = [];
bstart_state = 0;
bend_state = 0;
segment = 0;
unvoice = 0;
voice_min_len = 7;% 最短语音长度70ms  
unvoice_min_len = 5;%结束段最小持续50ms
st_candicate = 0;
en_candicate = 0;
for  i = 1:N    

    if( (amp(i) >= yuzhi2 && zcr(i) >= zcr_yu1) && ~bstart_state ) %find  start
            bstart_state = 1;  %     
            if(~st_candicate)
                st_candicate = i;
            end
            segment = segment + 1;            
            
    elseif( (amp(i) >= yuzhi2 || zcr(i) >= zcr_yu1) && bstart_state )%
        if(unvoice >= unvoice_min_len) %
            st = [st; st_candicate];
            en_candicate = en_candicate + unvoice_min_len - 1;
            en = [en; en_candicate];
       
            bstart_state = 0;
            bend_state = 1;
            unvoice = 0;
            segment = 0;
            st_candicate = 0;
        else %
            unvoice = 0;  %
            bend_state = 0;
            segment = segment + 1;       
        end
    elseif( (amp(i) < yuzhi2 && zcr(i) < zcr_yu1)  && bstart_state )     %
         if segment >= voice_min_len  %  
             unvoice = unvoice + 1; %
             if ~bend_state  %
                 en_candicate = i;
             end
             bend_state = 1; %
         else %              
             bstart_state = 0; %
             segment = 0;
             bend_state = 0;
             unvoice = 0;      
             st_candicate = 0;
             %prepare_for_start = 0;
             en_candicate = 0;
         end         
            
    elseif((amp(i) >= yuzhi2 || zcr(i) >= zcr_yu1) && ~bstart_state) %
          if ~ st_candicate
              st_candicate = i;
          end                   
    else%
        st_candicate = 0;
        continue;
    end
    
end


if(unvoice >= unvoice_min_len )%
    st = [st; st_candicate];              
    en = [en; (en_candicate + unvoice_min_len -1)];
    segment = 0;
end
if( segment >= voice_min_len) %
    st = [st; st_candicate];  
    en = [en; N];
end

figure(1);
subplot(3,1,1)
plot(x);  %原始语音波形
axis([1,length(x),-1,1])
ylabel(‘speech‘);
xlabel(‘样本点‘);

for  k=1:length(st)
line([st(k)*frameinc,st(k)*frameinc],[-1,1],‘linestyle‘,‘:‘,‘color‘,‘blue‘,‘LineWidth‘,2);
line([en(k)*frameinc,en(k)*frameinc],[-1,1],‘linestyle‘,‘:‘,‘color‘,‘red‘,‘LineWidth‘,2);
end

subplot(3,1,2)
plot(amp);%原始语音能量
axis([1,length(amp),0,max(amp)])
ylabel(‘energy‘);
xlabel(‘帧数‘);
line([1,N],[yuzhi1,yuzhi1],‘color‘,‘yellow‘,‘LineWidth‘,2);%由语音能量
line([1,N],[yuzhi2,yuzhi2],‘color‘,‘red‘,‘LineWidth‘,2);%由噪声平均能量和语音能量比较而得

for  k=1:length(st)
line([st(k),st(k)],[min(amp),max(amp)],‘linestyle‘,‘:‘,‘color‘,‘blue‘,‘LineWidth‘,2);
line([en(k),en(k)],[min(amp),max(amp)],‘linestyle‘,‘:‘,‘color‘,‘red‘,‘LineWidth‘,2);
end

subplot(3,1,3)
plot(zcr);%原始语音过零率
axis([1,length(zcr),0,max(zcr)])
ylabel(‘zcr‘);
xlabel(‘帧数‘);
line([1,N],[zcr_yu1,zcr_yu1],‘color‘,‘yellow‘,‘LineWidth‘,2);%由语音能量
line([1,N],[zcr_yu2,zcr_yu2],‘color‘,‘red‘,‘LineWidth‘,2);%语音加噪音

for  k=1:length(st)
line([st(k),st(k)],[min(zcr),max(zcr)],‘linestyle‘,‘:‘,‘color‘,‘blue‘,‘LineWidth‘,2);
line([en(k),en(k)],[min(zcr),max(zcr)],‘linestyle‘,‘:‘,‘color‘,‘red‘,‘LineWidth‘,2);

end

end
技术分享

                                   用语音识别的强制对齐自动切分连续语音汉字,工程量和资源巨大,此处做了个简易版的汉字自动切分,效果还可以。

技术分享

离线版-端点检测代码重写

标签:端点检测 vad 汉字切分

原文地址:http://blog.csdn.net/weiqiwu1986/article/details/45102043

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!