m=m(x1-2:x2-4,:); test(i).mfcc=m; end
disp('正在进行模板匹配...') dist=zeros(10,10); for i=1:10 for j=1:10
dist(i,j)=dtw(test(i).mfcc,ref(j).mfcc); end end
disp('正在计算匹配结果...') for i=1:10
[d,j]=min(dist(i,:));
fprintf('测试模板%d的识别结果为:%d\\n',i-1,j-1); end
子程序: Vad.m
function [x1,x2]=vad(x) %幅度归一化到[-1,1] x=double(x); x=x/max(abs(x));
%常数设置 FrameLen=240; FrameInc=80;
amp1=10; amp2=2; zcr1=10; zcr2=5;
maxsilence=3; %3*10ms=30ms minlen=15; *10ms=150ms status=0; count=0; silence=0;
%计算过零率
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.02; zcr=sum(signs.*diffs,2);
15
%计算短时能量
amp=sum(abs(enframe(filter([1 -0.9375],1,x),FrameLen,FrameInc)),2);
%调整能量门限
amp1=min(amp1,max(amp)/4); amp2=min(amp2,max(amp)/8);
%开始端点检测 x1=0; x2=0;
for n=1:length(zcr) goto=0;
switch status
case{0,1} %0=静音,1=可能开始 if amp(n)>amp1 %确信进入语音段 x1=max(n-count-1,1); status=2; silence=0;
count=count+1;
elseif amp(n)>amp2 zcr(n)>zcr(2) %可能处于语音段 status=1;
count=count+1; else %静音状态 status=0; count=0; end
case 2, %2=语音段
if amp(n)>amp(2) zcr(n)>zcr(2) %保持在语音段 count=count+1; else %语音将结束 silence=silence+1;
if silence elseif count else %语音结束 status=3; end end case 3, break; end 16 end count=count-silence/2; x2=x1+count-1; mfcc.m function ccc=mfcc(x) %设定mel滤波器系数 bank=melbankm(24,256,8000,0,0.5,'m' ); bank=full(bank); bank=bank/max(bank(:)); %设定DCT系数 for k=1:12 n=0:23;dctcoef(k,:)=cos((2*n+1)*k*pi/(2*24)); end %设置归一化的倒谱提升窗口 w=1+6*sin(pi*[1:12]./12); w=w/max (w); %设置预加重滤波器 xx=double(x); xx=filter([1-0.9375],1,xx); %对语音信号进行分帧 xx=enframe(xx,hamming(256),80); %计算每帧的mfcc参数 for i=1:size(xx,1) y=xx(i,:); s=y'.*hamming(256); %对信号S进行m计算 t=abs(fft(s)); t=t.^2; %对fft参数进行mel滤波取对数再计算倒谱 c1=dctcoef*log(bank*t(1:129) ); c2=c1.*w' ; %mfcc参数 m(i,:) =c2'; end %计算mfcc参数的一阶差分 dtm=zeros(size(m)); for i=3:size(m,1)-2 dtm (i,:) =-2*m(i-2,:)-m(i-1,:) +m(i+1,:)+2*m(i+2,:); end dtm =dtm/3; %合并mfcc参数和一阶差分参数 ccc= [m dtm]; %去除首尾两帧,因为这两帧一阶差分参数为0 17 ccc=ccc(3:size(m,1)-2,:); dtw.m function dist=dtw(t,r) n=size(t,1); m=size(r,1); %帧匹配距离矩阵 d=zeros(n,m); for i=1:n for j=1:m d(i,j)=sum((t(i,:)-r(j,:)).^2); end end %累积距离矩阵 D=ones(n,m)*realmax; D(1,1)=d(1,1); %动态规划 for i=2:n for j=1:m D1=D(i-1,j); if j>1 D2=D(i-1,j-1); else D2=realmax; end if j>2 D3=D(i-1,j-2); else D3=realmax; end D(i,j)=d(i,j)+min([D1,D2,D3]); end end dist=D(n,m); 18 参考文献 [1]王炳锡.语音编码[M].西安:西安电子科技大学出版社,2002. [2]何强,何英.MATLAB扩展编程[M].北京:清华大学出版社,2002. [3]王炳锡,屈丹,彭煊.实用语音识别基础[M].北京:国防工业出版社,2005. [4]易克初,等.语音信号处理[M].北京:国防工业出版社,2006,6. [5]胡航.语音信号处理[M].哈尔滨:哈尔滨工业大学出版社,2000,5. [6]胡广书.数字信号处理理论、算法与实现[M].北京:清华大学出版社,1997. [7]王炳锡,等.实用语音识别基础[M].北京:国防工业出版社,2005. [8]林波,吕明.基于DTW改进算法的弧立词识别系统的仿真与分析[J].信息技术,2006,30(4):56-59. [9]韩纪庆,张磊,郑铁然.语音信号处理[M].北京:清华大学出版社,2004 [10]李晋.语音信号端点检测算法研究[D].长沙:湖南师范大学,2006. 19