个人理解
我直接根据幅度来设置门限
a. 语音信号分帧处理
filedir=[];%设置路径
filename='D:\matlab\music\zj3.wav';
file=[filedir filename];
[x,Fs]=audioread(file);%得到语音信号的数据
wlen=200;%帧长
inc=100;%帧移
win=hamming(wlen);%海明窗
N=length(x);%信号长度
time=(0:N-1)/Fs;%计算出信号的时间刻度
X=enframe(x,win,inc)'; %分帧,一列是一帧
fn=size(X,2);%帧数
frameTime=frame2time(fn,wlen,inc,Fs); %求出每帧对应的时间
%这个公式得再看一下
b.
%短时能量
for i=1:fn
y=X(:,i);%每一帧数据
b=0;
for m=1:1:200 %这是根据帧长定的
b=b+y(m).^2;
end
E(i)=b;
end
%%参考-更简单点-尚未理解
fn=size(X,2); % 求出帧数
time=(0:N-1)/Fs; % 计算出信号的时间刻度
for i=1 : fn
u=X(:,i); % 取出一帧
u2=u.*u; % 求出能量
En(i)=sum(u2); % 对一帧累加求和
end
c. 短时帧过零数
%短时过零率
Z=zeros(1,fn); % 初始化
for i=1:fn
y=X(:,i);%每一帧数据
b=0;
for m=1:1:199 %根据帧长来定的
if y(m)*y(m+1)<0;
b=b+1;
end
Z(i)=b;
end
end
%%更简单点-尚未理解
fn=size(X,2); % 获取帧数
zcr1=zeros(1,fn); % 初始化
for i=1:fn
z=X(:,i); % 取得一帧数据
for j=1: (wlen- 1) ; % 在一帧内寻找过零点
if z(j)* z(j+1)< 0 % 判断是否为过零点
zcr1(i)=zcr1(i)+1; % 是过零点,记录1次
end
end
end
d.根据平均能量来设置门限
平均能量的结果:
[外链图片转存失败(img-Ciy7MbEu-1563959907473)(D:\matlab\语音信号处理实验教程-自己\assets\短时能量.jpg)]
E共有818个数据
T1设置为0.01,即当找到大于0.1标记。语音的开始
T2设置为0.001,即当找到小于0.001标记。语音的结束
找到了点,但是编程有点问题。就是要只显示端点而不是全部显示
[外链图片转存失败(img-2wWpu6Tz-1563959907475)(assets/找到了点-1但是没找到端点.jpg)]
经修改
[外链图片转存失败(img-SRvXb1fn-1563959907476)(assets/找到点-有点问题.jpg)]
过零率端点找得有点问题
%能量与过零数的端点检测算法1
clear all;
clc;
filedir=[];%设置路径
filename='D:\matlab\music\zs.wav';
file=[filedir filename];
[x,Fs]=audioread(file);
xmax=max(abs(x));
x=x/xmax';%归一化
x=filter([1 -0.98],[1],x);%预加重
wlen=200;%帧长
inc=100;%帧移
win=hamming(wlen);%海明窗
N=length(x);%信号长度
time=(0:N-1)/Fs;%计算出信号的时间刻度
X=enframe(x,win,inc)'; %分帧,一列是一帧
% Xmax=max(abs(X));%矩阵归一化,这个还不行
% X=X/Xmax;
fn=size(X,2)';%帧数
frameTime=frame2time(fn,wlen,inc,Fs); %求出每帧对应的时间
%这个公式得再看一下
%短时能量
for i=1:fn
y=X(:,i);%每一帧数据
b=0;
for m=1:1:200%一帧中的数据
b=b+y(m).^2;
end
E(i)=b;
end
%短时过零率
Z=zeros(1,fn); % 初始化,fn之前用过
for i=1:fn
y=X(:,i);%每一帧数据
b=0;
for m=1:1:199
if y(m)*y(m+1)<0;
b=b+1;
end
Z(i)=b;
end
end
%找短时能量的门限来确定语音的开始和结束
zeros(i);
q=[];%存储开始语音界限的位置
i1=1;
while (i10.1
q=[q i1-1];
i1=i1+1;
for i2=i1:length(E)
e=E(i2);
if e<0.1
q=[q i2+1];
i1=i2+1;
break
end
end
break
end
end
end
%过零率
i1=1;
w=[];%存储结束语音界限位置
while (i1120
w=[w i1];
i1=i1+1;
for i2=i1:length(Z)
e=Z(i2);
if e<50
w=[w i2+1];
i1=i2+1;
break
end
end
break
end
end
end
%画图
subplot(311)
plot(time,x);
title('原始信号')
xlabel('时间');ylabel('幅度');
subplot(312)
plot(frameTime(q),E(q),'or');
hold on
plot(frameTime,E);
title('短时能量')
xlabel('时间');ylabel('幅度');
subplot(313)
plot(frameTime(w),Z(w),'or');
hold on
plot(frameTime,Z);
title('过零率')
xlabel('时间');ylabel('次数');
最终结果