端点检测Word格式文档下载.docx
《端点检测Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《端点检测Word格式文档下载.docx(8页珍藏版)》请在冰豆网上搜索。
利用倒谱方法求出自己的基音周期。
三、实验仪器:
Cooledit、Matlab软件
四、实验代码:
取端点流程图
一:
clc,clear
[x,fs,nbits]=wavread('
fighting.wav'
);
%x为0~N-1即1~N
x=x/max(abs(x));
%幅度归一化到[-1,1]
%参数设置
FrameLen=240;
%帧长,每帧的采样点
inc=80;
%帧移对应的点数
T1=10;
%短时能量阈值,语音段
T2=5;
%短时能量阈值,过渡段
T3=1;
%过零率阈值,起止点
minsilence=6;
%无声的长度来判断语音是否结束
silence=0;
%用于无声的长度计数
minlen=15;
%判断是语音的最小长度
state=0;
%记录语音段状态0=静音,1=语音段,2=结束段
count=0;
%语音序列的长度
%计算短时能量
shot_engery=sum((abs(enframe(x,FrameLen,inc))).^2,2);
%计算过零率
tmp1=enframe(x(1:
end-1),FrameLen,inc);
%tmp1为二维数组=帧数*每帧的采样点FrameLen
tmp2=enframe(x(2:
end),FrameLen,inc);
%
signs=(tmp1.*tmp2)<
0;
%signs为一维数组,符合的置1,否则置0
zcr=sum(signs,2);
%开始端点检测,找出A,B点
forn=1:
length(zcr)
ifstate==0%0=静音,1=可能开始
ifshot_engery(n)>
T1%确信进入语音段
x1=max(n-count-1,1);
%记录语音段的起始点
state=2;
silence=0;
count=count+1;
elseifshot_engery(n)>
T2||zcr(n)>
T3%只要满足一个条件,可能处于过渡段
status=1;
x2=max(n-count-1,1);
else%静音状态
state=0;
count=0;
end
ifstate==2%1=语音段
T2%保持在语音段
elseifzcr(n)>
T3%保持在语音段
x3=max(n-count-1,1);
else%语音将结束
silence=silence+1;
ifsilence<
minsilence%静音还不够长,尚未结束
elseifcount<
minlen%语音段长度太短,认为是噪声
silence=0;
else%语音结束
state=3;
ifstate==3%2=结束段
break;
end
x1,x2,x3%A、C、E坐标
x11=x1+count-1%B坐标
x22=x2+count-1%D坐标
x33=x3+count-1%F坐标
%画图
subplot(3,1,1)
plot(x)
axis([1length(x)-11])%标定横纵坐标
title('
原始语音信号'
'
fontsize'
17);
xlabel('
样点数'
ylabel('
Speech'
line([x3*incx3*inc],[-11],'
Color'
'
red'
%画竖线
line([x33*incx33*inc],[-11],'
subplot(3,1,2)
plot(shot_engery);
axis([1length(shot_engery)0max(shot_engery)])
短时能量'
帧数'
Energy'
line([x1x1],[min(shot_engery),T1],'
line([x11x11],[min(shot_engery),T1],'
%
line([x2x2],[min(shot_engery),T2],'
line([x22x22],[min(shot_engery),T2],'
line([1length(zcr)],[T1,T1],'
linestyle'
:
'
%画横线
line([1length(zcr)],[T2,T2],'
text(x1,-5,'
A'
%标写A、B、C、D
text(x11-5,-5,'
B'
text(x2-10,-5,'
C'
text(x22-5,-5,'
D'
subplot(3,1,3)
plot(zcr);
axis([1length(zcr)0max(zcr)])
过零率'
ZCR'
line([x3x3],[min(zcr),max(zcr)],'
line([x33x33],[min(zcr),max(zcr)],'
line([1length(zcr)],[T3,T3],'
text(x3-10,-3,'
E起点'
%标写E、F
text(x33-40,-3,'
F终点'
运行结果与分析:
x1=650,x11=734,x2=646,x22=752,x3=643,x33=763
得出的值x3<
x2<
x1<
x11<
x22<
x33,基本符合要求
1、主要是学习了一些新的函数。
[x,fs,nbit]=wavread(wavFile);
x就是音频信号;
fs是采样频率,比如说16000就是每秒16000次;
nbit是采样精度,比如说16就是指16位精度的采样。
y=enframe(x,FrameLen,inc);
包含语音采样的以为数组x经过处理后得到二维数组y,FrameLen为帧长,即每帧的采样点,inc为帧移对应的点数。
sum(x,2)表示矩阵x的横向相加,求每行的和,结果是列向量。
而缺省的sum(x)就是竖向相加,求每列的和,结果是行向量。
line([X1X2],[Y1Y2],S);
%点A(X1,Y1)和点B(X2Y2)之间画一条直线,S为其它属性(颜色,线的粗细等)
2、端点检测可分为四段:
静音段、过渡段、语音段、结束。
实验时使用一个变量表示当前状态。
静音段,如果能量或过零率超过低门限,就开始标记起始点,进入过渡段。
过渡段当两个参数值都回落到低门限以下,就将当前状态恢复到静音状态。
而如果过渡段中两个参数中的任一个超过高门限,即被认为进入语音段。
处于语音段时,如果两参数降低到门限以下,而且总的计时长度小于最短时间门限,则认为是一段噪音,继续扫描以后的语音数据,否则标一记结束端点。
根据这些关系画出流程图,然后再编写程序就比较有条理,且思路清晰。
二:
[y,fs,nbits]=wavread('
time=(1:
length(y))/fs;
frameSize=floor(40*fs/1000);
%帧长
startIndex=round(10000);
%起始序号,这个位置开始正好是语音开始
endIndex=startIndex+frameSize-1;
%结束序号
frame=y(startIndex:
endIndex);
%取出该帧
frameSize=length(frame);
%求帧长
frame2=frame.*(hamming(frameSize));
frame2=frame;
dp=rceps(frame2);
%求倒谱
ylen=length(dp);
cepstrum=dp(1:
ylen/2);
%基音检测
LF=floor(fs/500);
%设置基音搜索的范围
HF=floor(fs/70);
cn=cepstrum(LF:
HF);
%
[mx_cepind]=max(cn);
ifmx_cep>
0.08&
ind>
LF%求基因周期
basic_T=(LF+ind)/fs;
%由点转化为毫秒,即基音周期
else
basic_T=0;
end
fprintf('
基因周期=%d\n'
basic_T);
%basic_T所求基因周期
%画图
subplot(2,1,1);
plot(frame);
axis([1frameSize-1*10.^(-3)1*10.^(-3)])
某个加窗信号'
subplot(2,1,2);
plot(cepstrum);
axis([1ylen/2-55])
倒谱图'
1、根据倒谱图可以看出信号没有周期性,应该是清音,所有求出的结果为第一个峰值位置,即0,则基音周期为0/8000s=0,结果基本符合。
2、从自相关函数图中也可以看出在0点峰值最高。
3、总觉得“自相关函数”、“倒谱”、“分帧”、“基音周期”
等概念有些弄不清楚
五、