语音信号处理实验报告
实验一:语音信号的端点检测
学院:电子与信息学院
专业:11级信息工程
姓名:
学号:
提交日期:2014.4.23
实验一:语音信号的端点检测
1、 实验内容
语音信号端点检测技术其目的就是从包含语音的一段信号中准确地确定语音的起始点和终止点,区分语音和非语音信号,它是语音处理技术中的一个重要方面。本实验的目的就是要掌握基于MATLAB编程实现带噪语音信号端点检测,利用MATLAB对信号进行分析和处理,学会利用短时过零率和短时能量,对语音信号的端点进行检测。
2、 实验方法
本实验中,端点检测的方法有两种:短时能量和短时过零率。
2.1.1、短时能量
语音和噪声的区别可以体现在它们的能量上,语音段的能量比噪声段能量大,语音段的能量是噪声段能量叠加语音声波能量的和。在信噪比很高时,那么只要计算输入信号的短时能量或短时平均幅度就能够把语音段和噪声背景区分开。这是仅基于短时能量的端点检测方法。
信号{x(n)}的短时能量定义为:
2.1.2、短时平均过零率
短时过零表示一帧语音信号波形穿过横轴(零电平)的次数。过零分析是语音时域分析中最简单的一种。对于连续语音信号,过零意味着时域波形通过时间轴;而对于离散信号,如果相邻的取样值的改变符号称为过零。过零率就是样本改变符号次数。
信号{x(n)}的短时平均过零率定义为:
2.2、检测方法
利用过零率检测清音,用短时能量检测浊音,两者配合。首先为短时能量和过零率分别确定两个门限,一个是较低的门限数值较小,对信号的变化比较敏感,很容易超过;另一个是比较高的门限,数值较大。低门限被超过未必是语音的开始,有可能是很短的噪声引起的,高门限被超过并且接下来的自定义时间段内的语音超过低门限,意味着信号开始。
此时整个端点检测可分为四段:静音段、过渡段、语音段、结束。实验时使用一个变量表示当前状态。静音段,如果能量或过零率超过低门限,就开始标记起始点,进入过渡段。过渡段当两个参数值都回落到低门限以下,就将当前状态恢复到静音状态。而如果过渡段中两个参数中的任一个超过高门限,即被认为进入语音段。处于语音段时,如果两参数降低到门限以下,而且总的计时长度小于最短时间门限,则认为是一段噪音,继续扫描以后的语音数据,否则标一记结束端点。
2.3、实验过程
1、录取一段录音,采样率8K,单声道
2、用MATLAB的wavread函数把录音都进来并进行归一化处理
3、对语音信号进行预加重,分帧处理
4、对每帧分别计算短时能量和短时门限过零率
5、进行短时能量阈值、过零率阈值等参数
6、编写程序实现语音检测端点并绘出检测图
3、实验结果
4、实验分析
4.1结果分析
从结果图可知,本次实验是成功的,语音信号的端点基本都检测出来了。短时能量和短时过零率的检测结果和信号的端点分布一致。语音段的能量值比过渡段和静音段的能量都大,语音的过零率比过渡段和静音段的也都大。
4.2实验总结
这次实验利用MATLAB对信号进行分析和处理,利用短时过零率和短时能量,对语音信号的端点进行检测。由于知识储备的不足,在实验过程中还是遇到比较大的困难,端点检测代码是参考网上的,在理解的基础上加以修改和改进。但是预处理、加窗分帧、短时能量、短时过零率的代码都是我自己根据原理编写的,所有总的来说收获还是很大的。
代码如下:
function point_check()
s1=wavread('1_1.wav');
s=s1/max(abs(s1));
s=filter([1 -0.9375],1,s);%预加重
plot(s);
len=length(s);
round=160;%帧长
repeat=80;%帧移
inc=round-repeat;%b_len-2*repeat;
ka=ceil((len-round)/(round-repeat))+1;%总帧数
s=[s;zeros((round-repeat)*(ka-1)+round-len,1)];
len=length(s);
%以下进行分针操作
w=zeros(round,ka);
for i=1:ka
for k=1:round
w(k,i)=s(k+(i-1)*(round-repeat),1);
end
end
%计算过零率
ST=0.01;%过零门限
f=zeros(ka,1);
%计算短时能量幅度差
F=zeros(ka,round);
for i=1:ka
for k=0:round-1
for j=1:round-k
F(ka,k+1)=F(ka,k+1)+abs(w(j,i)-w(j+k,i));%计算短时能量幅度差
end
if(k<round-1)
if(w(k+1,i)>0&&w(k+2,i)<0)
z=sign(w(k+1,i)-ST)-sign(w(k+2,i)+ST);%计算过零率
elseif(w(k+1,i)<0&&w(k+2,i)>0)
z=sign(w(k+2,i)-ST)-sign(w(k+1,i)+ST);%计算过零率
end
if(z==2)
f(i,1)=f(i,1)+1;%计算过零率
end
end
end
end
amp=sum(abs(w).^2,1);
%计算端点
amp1=10;%短时能量阈值?
amp2=2;
zcr1=10;%过零率阈值?
zcr2=6;
minsilence=6;%用无声的长度来判断语音是否结束?
minlen=15;%判断是语音的最小长度?
status=0;%记录语音段的状态?
count=0;%语音序列的长度?
silence=0;%无声的长度
xpoint=[];
amp1=min(amp1,max(amp)/4);
amp2=min(amp2,max(amp)/8);
%一下开始断点检测
for n=1:ka
%goto =0;
switch status
case {0,1};%?0?=?静音,?1?=?可能开始
if amp(n) > amp1 %?确信进入语音段????????
x1=max(n-count-1,1);%?记录语音段的起始点????????
xpoint=[xpoint,x1];
status = 2;
silence = 0;
count = count + 1;
elseif amp(n) > amp2 || f(n) > zcr2 % 可能处于语音段
status = 1;
count = count + 1;
else % 静音状态
status = 0;
count = 0;
end
case 2, % 2 = 语音段
if amp(n) > amp2 ||f(n) > zcr2 % 保持在语音段
count = count + 1;
else % 语音将结束
silence = silence+1;
if silence < minsilence % 静音还不够长,尚未结束
count = count + 1;
elseif count < minlen % 语音长度太短,认为是噪声
status = 0;
silence = 0;
count = 0;
else % 语音结束
status = 3;
end
end
case 3,
status=0;
count = count-silence/2;
x2 = x1 + count -1; %记录语音段结束点
xpoint=[xpoint,x2];
count=0;
silence=0;
end
end
subplot(3,1,1)
plot(s)
axis([1 length(s) -1 1])
ylabel('Speech');
for i=1:length(xpoint)
line([xpoint(i)*inc xpoint(i)*inc], [-1 1], 'Color', 'red');
end
subplot(3,1,2)
plot(amp);
axis([1 length(amp) 0 max(amp)])
ylabel('Energy');
for i=1:length(xpoint)
line([xpoint(i) xpoint(i)],[min(amp),max(amp)], 'Color', 'green');
end
subplot(3,1,3)
plot(f);
axis([1 length(f) 0 max(f)])
ylabel('ZCR');
for i=1:length(xpoint)
line([xpoint(i) xpoint(i)],[min(f),max(f)], 'Color', 'black');
end
第二篇:语音信号处理实验一
实验一 语音信号的采集及预处理
一、 实验目的
在理论学习的基础上,进一步地理解和掌握语音信号预处理及短时加窗的意义及基于matlab的实现方法。
二、 撰写实验报告要求
要求随本次上机撰写完成实验报告,报告中要有实验目的、实验步骤、实验程序、实验中得出的图形结果及结论等。另外,总结本次上机实验的收获。
三、 实验内容及步骤
1. 语音信号的录音、读入、放音等:练习matlab中几个音频处理函数,利用函数wavread对语音信号进行采样,记住采样频率和采样点数,给出以下语音的波形图(2.wav),wavread的用法参见mablab帮助文件。利用wavplay或soundview放音。也可以利用wavrecord自己录制一段语音,并进行以上操作(需要话筒)。
[Y,FS,NBITS,OPTS]=wavread('9.wav')
FS =
10000
NBITS =
16
OPTS =
fmt: [1x1 struct]
2. 语音信号的分帧:选择20ms左右为一帧,帧移取1/2帧长,对语音信号进行分帧,可以利用voicebox工具箱中的函数enframe。voicebox工具箱是基于GNU协议的自由软件,其中包含了很多语音信号相关的函数。
voicebox工具箱安装方法:
把工具箱拷贝入.\MatLab\toolbox目录下;
菜单file-set path-"Add folder" 导入voicebox;
菜单file-Preference-General-"Updata Toolbox Path Cache
分帧函数的调用:
y=enframe(x,len,inc)
x为输入语音信号,len指定了帧长,inc指定帧移,函数返回为n×len的一个矩阵,每一行都是一帧数据。
帧长=10000X0.02=200s
x=wavread('9.wav')
y=enframe(x,200,100)
subplot(2,1,1),plot(x)
subplot(2,1,2),plot(y)
3 窗函数及其时频特性:本步要求利用window函数设计窗口长度为200(N=200)的矩形窗(rectwin)、汉明窗(hamming)及汉宁窗(hann)),利用wvtool函数观察其时域波形图及频谱特性,比较得出结论。
w = window(fhandle,n)
w = window(fhandle,n,winopt)
w = window(fhandle,n) returns the n-point window, specified by its function handle, fhandle, in column vector w. Function handles are window function names preceded by an @.
@barthannwin
@bartlett
@blackman
@blackmanharris
@bohmanwin
@chebwin
@flattopwin
@gausswin
@hamming
@hann
@kaiser
@nuttallwin
@parzenwin
@rectwin
@triang
@tukeywin
w = window(fhandle,n,winopt) returns the window specified by its function handle, fhandle, and its winopt value or sampling flag string. For chebwin, kaiser, and tukeywin, you must enter a winopt value. For the other windows listed below, winopt values are optional.
Examples:Create Blackman Harris, Hamming, and Gaussian windows and plot them in the same WVTool.
N = 65;
w = window(@blackmanharris,N);
w1 = window(@hamming,N);
w2 = window(@gausswin,N,2.5);
wvtool(w,w1,w2)
N = 200;
w = window(@rectwin,N);
w1 = window(@hamming,N);
w2 = window(@hann,N);
wvtool(w,w1,w2)
3. 语音信号加窗:观察信号加矩形窗及汉明窗后的波形,取出其中一帧,利用subplot与reshape函数将一帧语音的波形、加矩形窗波形及加汉明窗波形画在一张图上比较将得出结论。
例:语音信号分帧,每一帧加哈宁窗
y=enframe(x,hanning(len),inc);
[x,fs,nbits]=wavread('2.wav');
x1=enframe(x,200,100);
x2=enframe(x,hamming(200),100);
subplot(2,1,1),plot(x1(50,:))
subplot(2,1,2),plot(x2(50,:))
4. 预加重:即语音信号通过一个一阶高通滤波器。
例如:y=filter([1 -0.9375],1,x)
利用subplot画出预加重前后的波形图。
x=wavread('1.wav')
y=filter([1 -0.9375],1,x)
subplot(2,1,1),plot(x)
subplot(2,1,2),plot(y)
5. (选做)改变帧长、帧移重复上述步骤。
6. (选做)换一段语音重复上述步骤。
7. 重点编写短时加窗部分的程序,得出结论,撰写实验报告。
四、 思考题
1. 语音信号包括哪些预处理,作用分别是什么?
2. 不同窗口的优缺点,窗口长度如何选取?