% 同一种思想,三种实现方法求短时过零率,并互相验证
[x,fs,bits]=wavread('F:\语音\语料\字训练\m1出1.wav');
x = filter([1 -0.9375],1,x);%预加重
x = double(x); %归一化
x = x / max(abs(x));
n=length(x);
N=256; %窗长(帧长),每帧的时间长度为N/fs
shift=N/2;
win=hamming(N);
%法一
k=1;
j=0;%初始化帧数
while (k+N-1)<n %一帧的右边界k+N-1还未超出语音段时
Zm(k)=0;x1=x(k:k+N-1).*win;
for i=1:N-1
if x1(i)>=0
b(i)=1;
else
b(i)=-1;
end
if x1(i+1)>=0
b(i+1)=1;
else
b(i+1)=-1;
end
w(i)=abs(b(i+1)-b(i)); %求出每相邻两点符号的差值的绝对值
%若相邻点符号相同(无过零)则w(i)=0;否则(过零),w(i)=2
c(i)=abs(x1(i+1)-x1(i))>0.02;%同时,符号相异的相邻点要有一定距离
end
w=w.*c;
Zm(k)=sum(w);%一帧内(k:k+N-1)相邻两点符号差值的绝对值的总和,
%其数值为过零率的2倍
j=j+1;
k=k+shift; %每次移动半个窗
end
for w=1:j
zcr1(w)=Zm(shift*(w-1)+1)/2;%第w帧的短时过零率 (zcr1/N就变成了短时平均过零率)
end
%法二
y=enframe(x,win,shift);
zcr2 = zeros(size(y,1),1);
delta = 0.02;% 经验值
for i=1:size(y,1)
x2 = y(i,:);
for j=1:length(x2)-1
if x2(j) * x2(j+1)<0 & abs(x2(j)-x2(j+1))>delta
zcr2(i) = zcr2(i)+1;
end
end
end
%法三
tmp1 = enframe(x(1:end-1), win, shift);
tmp2 = enframe(x(2:end) , win, shift);% tmp2与tmp1错开一点
signs = (tmp1.*tmp2)<0; % 标记tmp1与tmp2相应位置符号不同的点,即过零点
diffs = abs(tmp1 -tmp2)>0.02; % 并且还要满足这个条件
zcr3 = sum(signs.*diffs, 2);
% plot(a);title('原信号');figure;
subplot(311),plot(zcr1);title('zcr based on defination ');% 横轴为帧数
subplot(312),plot(zcr2);title('zcr by func enframe');
subplot(313),plot(zcr3);title('zcr with a new method');
评论0