DTW语音识别算法部分.docx
《DTW语音识别算法部分.docx》由会员分享,可在线阅读,更多相关《DTW语音识别算法部分.docx(14页珍藏版)》请在冰豆网上搜索。
DTW语音识别算法部分
附录2:
训练函数:
train.m
disp('正在生成训练参数……');
fori=1:
20
fname=sprintf('train\\%d0.wav',i);
[k,fs]=audioread(fname);
[StartPoint,EndPoint]=vad_m(k,fs);
cc=mfcc(k);
cc=cc(StartPoint-2:
EndPoint-2,:
);
ref(i+1).StartPoint=StartPoint;
ref(i+1).EndPoint=EndPoint;
ref(i+1).mfcc=cc;
end
disp('正在存储模板库……');
save'mfcc.mat'ref;
disp('存储完毕')
附录3:
测试函数:
dtwtest.m
clear;closeall;clc;
disp('正在导入参考模板参数...');
loadmfcc.mat;
disp('正在计算测试模板的参数...')
fori=0:
3
fname=sprintf('test\\%d1.wav',i);
[k,fs]=audioread(fname);
[StartPoint,EndPoint]=vad_m(k,fs);
cc=mfcc(k);
cc=cc(StartPoint-2:
EndPoint-2,:
);
test(i+1).StartPoint=StartPoint;
test(i+1).EndPoint=EndPoint;
test(i+1).mfcc=cc;
end
disp('正在进行模板匹配...')
dist=zeros(1,20);
fori=1:
4
forj=1:
20
dist(i,j)=dtw(test(i).mfcc,ref(j).mfcc);
end
end
disp('正在计算匹配结果...')
fori=1:
4
[d,j]=min(dist(i,:
));
if(j>=1&&j<=5)
fprintf('测试模板%d1.wav的识别结果为:
前进\n',i-1);
end
if(j>=6&&j<=10)
fprintf('测试模板%d1.wav的识别结果为:
停止\n',i-1);
end
if(j>=11&&j<=15)
fprintf('测试模板%d1.wav的识别结果为:
左转\n',i-1);
end
if(j>=16&&j<=20)
fprintf('测试模板%d1.wav的识别结果为:
右转\n',i-1);
end
end
closeall;
附录4:
特征提取函数:
vad_m.m
function[StartPoint,EndPoint]=vad(k,fs)
%%[StartPoint,EndPoint]=vad(k,fs)
%%语音信号端点检测程序,k为语音信号,
%%fs为其采样频率,程序绘制出语音信号
%%相关波形图并返回起止端点所对帧号
closeall
%幅度归一化到[-1,1]
k=double(k);
k=k./max(abs(k));
%------------------------------
%显示波形
%------------------------------
SNR=5;%设置SNR
signal=Gnoisegen(k,SNR);%叠加噪声
snr1=SNR_singlech(k,signal);%计算叠加噪声后的信噪比
N=length(k);%信号长度
t=(0:
N-1)/fs;%设置时间
IS=.25;%设置IS
%调用WienerScalart96m_2函数做维纳滤波
output=WienerScalart96m_2(signal,fs,IS,0.12);
ol=length(output);%把output补到与x等长
ifoloutput=[output;zeros(N-ol,1)];
end
snr2=SNR_singlech(k,output);%计算维纳滤波后的信噪比
snr=snr2-snr1;
fprintf('snr1=%5.4fsnr2=%5.4fsnr=%5.4f\n',snr1,snr2,snr);
subplot311;plot(t,k,'k');grid;axistight;
title('纯语音波形');ylabel('幅值')
subplot312;plot(t,signal,'k');grid;axistight;
title(['带噪语音信噪比='num2str(SNR)'dB']);ylabel('幅值')
subplot313;plot(t,output,'k');grid;ylim([-11]);
title('维纳滤波后波形');ylabel('幅值');xlabel('时间/s');
disp('显示原始波形图……');
t=0:
1/fs:
(length(k)-1)/fs;
%subplot(3,1,1);
plot(t,k);
axis([0,(length(k)-1)/fs,min(k),max(k)]);
title('语音信号波形');
xlabel('Time:
s');
ylabel('Amplitude(normalized)');
disp('显示语音起始处放大波形图……');
t1=0.2:
1/fs:
0.3;
k1=k(0.2*fs:
0.3*fs);
subplot(3,1,2);
plot(t1,k1);
axis([0.2,0.3,min(k),max(k)]);
title('(II)“00.wav”语音起始处放大波形图');
xlabel('Time:
s');
ylabel('Amplitude(normalized)');
disp('显示语音结束处放大波形图……');
t1=0.4:
1/fs:
0.5;
k1=k(0.4*fs:
0.5*fs);
subplot(3,1,3);
plot(t1,k1);
axis([0.4,0.5,min(k),max(k)]);
title('(III)“00.wav”语音结束处放大波形图');
xlabel('Time:
s');
ylabel('Amplitude(normalized)');
%------------------------------
%计算短时过零率
%------------------------------
k=output;
FrameLen=240;
FrameInc=80;
FrameTemp1=enframe(k(1:
end-1),FrameLen,FrameInc);
FrameTemp2=enframe(k(2:
end),FrameLen,FrameInc);
signs=(FrameTemp1.*FrameTemp2)<0;
diffs=abs(FrameTemp1-FrameTemp2)>0.01;
zcr=sum(signs.*diffs,2);
zcrm=multimidfilter(zcr,5);
disp('显示原始波形图……');
figure,subplot(3,1,1);
plot(t,k);
axis([0,(length(k)-1)/fs,min(k),max(k)]);
title('(I)语音信号波形');
xlabel('Time:
s');
ylabel('Amplitude(normalized)');
disp('显示短时过零率……')
zcrInd=1:
length(zcrm);
subplot(3,1,2);
plot(zcrInd,zcr);
axis([0,length(zcr),0,max(zcr)]);
title('(II)短时过零率');
xlabel('Frame');
ylabel('Zcr');
%------------------------------
%计算短时能量
%------------------------------
amp=sum(abs(enframe(filter([1-0.9375],1,k),FrameLen,FrameInc)),2);
ampm=multimidfilter(amp,5);
disp('显示短时能量……')
ampInd=1:
length(ampm);
subplot(3,1,3);
plot(ampInd,amp);
axis([0,length(amp),0,max(amp)]);
title('(III)短时能量');
xlabel('Frame');
ylabel('Energy');
%------------------------------
%设置门限
%------------------------------
disp('设置门限……');
ZcrLow=max([round(mean(zcr)*0.1),3]);%过零率低门限
ZcrHigh=max([round(max(zcr)*0.1),5]);%过零率高门限
AmpLow=min([min(amp)*10,mean(amp)*0.2,max(amp)*0.1]);%能量低门限
AmpHigh=max([min(amp)*10,mean(amp)*0.2,max(amp)*0.1]);%能量高门限
%------------------------------
%端点检测
%------------------------------
MaxSilence=30;%最长语音间隙时间
MinAudio=15;%最短语音时间
Status=0;%状态:
0静音段,1过渡段,2语音段,3结束段
HoldTime=0;%语音持续时间
SilenceTime=0;%语音间隙时间
disp('开始端点检测……');
forn=1:
length(zcr)
switchStatus
case{0,1}
ifamp(n)>AmpHigh|zcr(n)>ZcrHigh
StartPoint=n-HoldTime;
Status=2;
HoldTime=HoldTime+1;
SilenceTime=0;
elseifamp(n)>AmpLow|zcr(n)>ZcrLow
Status=1;
HoldTime=HoldTime+1;
else
Status=0;
HoldTime=0;
end
case2,
ifamp(n)>AmpLow|zcr(n)>ZcrLow
HoldTime=HoldTime+1;
else
SilenceTime=SilenceTime+1;
ifSilenceTimeHoldTime=HoldTime+1;
elseif(HoldTime-SilenceTime)Status=0;
HoldTime=0;
SilenceTime=0;
else
Status=3;
end
end
case3,
break;
end
ifStatus==3
break;
end
end
HoldTime=HoldTime-SilenceTime;
EndPoint=StartPoint+HoldTime;
disp('显示端点……');
figure,subplot(3,1,1);
plot(k);
axis([1,length(k),min(k),max(k)]);
title('(I)语音信号');
xlabel('Sample');
ylabel('Speech');
line([StartPoint*FrameInc,StartPoint*FrameInc],[min(k),max(k)],'color','red');
line([EndPoint*FrameInc,EndPoint*FrameInc],[min(k),max(k)],'color','red');
subplot(3,1,2);
plot(zcr);
axis([1,length(zcr),0,max(zcr)]);
title('(II)短时过零率');
xlabel('Frame');
ylabel('ZCR');
line([StartPoint,StartPoint],[0,max(zcr)],'Color','red');
line([EndPoint,EndPoint],[0,max(zcr)],'Color','red');
subplot(3,1,3);
plot(amp);
axis([1,length(amp),0,max(amp)]);
title('(III)短时能量');
xlabel('Frame');
ylabel('Energy');
line([StartPoint,StartPoint],[0,max(amp)],'Color','red');
line([EndPoint,EndPoint],[0,max(amp)],'Color','red');
附录5:
DTW算法
functiondist=dtw(test,ref)
globalxy_miny_max
globaltr
globalDd
globalmn
t=test;
r=ref;
n=size(t,1);
m=size(r,1);
d=zeros(m,1);
D=ones(m,1)*realmax;
D
(1)=0;
%如果两个模板长度相差过多,匹配失败
if(2*m-n<3)|(2*n-m<2)
dist=realmax;
return
end
%计算匹配区域
xa=round((2*m-n)/3);
xb=round((2*n-m)*2/3);
ifxb>xa
%xb>xa,按下面三个区域匹配
%1:
xa
%xa+1:
xb
%xb+1:
N
forx=1:
xa
y_max=2*x;
y_min=round(0.5*x);
warp
end
forx=(xa+1):
xb
y_max=round(0.5*(x-n)+m);
y_min=round(0.5*x);
warp
end
forx=(xb+1):
n
y_max=round(0.5*(x-n)+m);
y_min=round(2*(x-n)+m);
warp
end
elseifxa>xb
%xa>xb,按下面三个区域匹配
%0:
xb
%xb+1:
xa
%xa+1:
N
forx=1:
xb
y_max=2*x;
y_min=round(0.5*x);
warp
end
forx=(xb+1):
xa
y_max=2*x;
y_min=round(2*(x-n)+m);
warp
end
forx=(xa+1):
n
y_max=round(0.5*(x-n)+m);
y_min=round(2*(x-n)+m);
warp
end
elseifxa==xb
%xa=xb,按下面两个区域匹配
%0:
xa
%xa+1:
N
forx=1:
xa
y_max=2*x;
y_min=round(0.5*x);
warp
end
forx=(xa+1):
n
y_max=round(0.5*(x-n)+m);
y_min=round(2*(x-n)+m);
warp
end
end
%返回匹配分数
dist=D(m);
functionwarp
globalxy_miny_max
globaltr
globalDd
globalmn
d=D;
fory=y_min:
y_max
D1=D(y);
ify>1
D2=D(y-1);
else
D2=realmax;
end
ify>2
D3=D(y-2);
else
D3=realmax;
end
d(y)=sum((t(x,:
)-r(y,:
)).^2)+min([D1,D2,D3]);
end
D=d;