%自相关端点检测M1_009.wav,enframe.m放在当前路径
clear all;
[x,fs,bits]=wavread('M1_009.wav');
x=filter([1 -0.95],1,x);%对语音进行预加重,x[n]=y[n]-0.95y[n-1]
L=320; %窗长
FrameLen=320;
FrameInc=160;
%[f]=enframe(x,hamming(320,'periodic'),FrameInc);%加汉明窗
[framenum,f]=enframe(x,FrameLen,FrameInc);
%[framenum,L]=size(f);%显示帧数
P=framenum;%总帧数
%求每帧的自相关函数的最大值,用数组MCOR存储,第i个元素为第i帧自相关序列的最大值
for ii=1:P
s=f(ii,:);% 取出第ii帧语音样值
r=xcorr(s);%该帧的自相关序列,长度为2*序列长度-1,最大值在正中间
MCOR(ii)=r(FrameLen);%取r的中间值,即最大值
end
%%%观察
frameTime=(((1:P)-1)*FrameInc+FrameLen/2)/fs;%
%frameTime是数组,长度为帧长,第i个元素值是第i帧中间那个样值对应的时间
figure
subplot(2,1,1)
plot((0:length(x)-1)/fs,x);
xlabel('时间/s');ylabel('幅度');title('语音信号');
subplot(2,1,2)
plot(frameTime,MCOR);%画出各帧的倒谱距离值,从而预估起点和终点的帧序号及alpha1,alpha2大小
xlabel('时间/s');ylabel('幅度');title('自相关最大值');
%%%%取前导帧的自相关最大值的平均值
MR=mean(MCOR(1:5));% 取1-5帧做背景噪声的自相关最大值的平均值的2倍为门限值
MR=2*MR;
cx1=0;%检测出的起点帧号
cx2=0;%检测出的终点帧号
flag1=0;
flag2=0;
for i=1:P-3
if (MCOR(i)>MR)&&(MCOR(i+1)>MR)&&(MCOR(i+2)>MR)&&(MCOR(i+3)>MR)&&(flag1==0)
cx1=i;
flag1=1;
end
end
for i=cx1+1:P-3
if (MCOR(i)<MR)&&(MCOR(i+1)<MR)&&(MCOR(i+2)<MR)&&(MCOR(i+3)<MR)&&(flag2==0)
cx2=i-1;
flag2=1;
end
end
cx1
cx2
frameTime(cx1)
frameTime(cx2)
figure%显示图形
subplot(211),plot((0:length(x)-1)/fs,x);
title('语音波形');
xlabel({'时间/s' ; '(a)'});
ylabel('幅度');
line([frameTime(cx1),frameTime(cx1)],[min(x),max(x)],'color','r');
line([frameTime(cx2),frameTime(cx2)],[min(x),max(x)],'color','r');
subplot(212),plot(frameTime,MCOR);
title('自相关最大值');
xlabel({'时间/s' ; '(b)'});
ylabel('自相关最大值');
line([frameTime(cx1),frameTime(cx1)],[min(MCOR),max(MCOR)],'color','r');
line([frameTime(cx2),frameTime(cx2)],[min(MCOR),max(MCOR)],'color','r');
%%%%%%思考1:设定双门限,即起点和终点的判定门限大小是不同的
%%%%%%思考2:带噪情况下效果如果?