短时能量 过零率.docx
《短时能量 过零率.docx》由会员分享,可在线阅读,更多相关《短时能量 过零率.docx(19页珍藏版)》请在冰豆网上搜索。
短时能量过零率
1前言和开发背景
1.1前言
本课题为给语音识别系统提供语音信号端点检测的功能,对语音信号端点检测进行了探讨和研究。
语音信号处理部分包括:
语音信号的电压放大、反混叠滤波、自动增益控制、模/数变换、去除声门激励及口唇辐射的影响等。
本课题主要是侧重语音区间的端点检测,端点检测的目的是从包含语音的一段信号中确定出语音的起点以及终点。
为了实现可靠的端点检测,在算法Vad中主要应用了短时能量和过零率两者配合实现,并且在端点检测的过程中采取四个阶段标识语音信号的状态来实现的。
对大象声音进行录制和处理,利用MATLAB软件进行端点检测,MATLAB软件是语音识别系统中有效,方便的工具,提供了强大的科学运算、灵活的程序设计流程、高质量的图形可视化与界面设计、便捷地与其他程序和语言接口的功能。
结果表明,基于端点检测算法Vad和应用MATLAB工具,可以有效确定语音的起点和终点,并能够以图像的形式直观的表示出来,端点检测使处理时间减到最小,排除无声段的噪声干扰,从而使识别系统具有良好的识别功能[1]。
1.2开发背景
本项目来源于云南省重点项目西双版纳自然保护区系统建设。
综合应用传感器技术,数字仿真技术,数据编码与数据压缩技术,DSP技术,无线传输技术等,研究自然保护区视频信号、声音信号以及其他监测信号的采集、传送、处理方案,设备选型方案,二次开发技术,为自然保护区信息系统建设。
本课题重点是语音识别系统的开发与研究,侧重于语音识别系统的语音信号的端点检测。
本课题研究的目的在于为开发一个能够识别野象声音的语音识别系统提供语音信号的端点检测功能,端点检测在语音识别系统中有重要地位,是语音识别系统中不可缺少的一部分,也是预处理中很重要的一个环节,这个功能使处理时间减到最小,排除无声段的噪声干扰,从而使识别系统具有良好的识别功能,提高语音识别系统的识别效率和准确率。
研究的内容是:
首先录制大象的声音,并处理声音文件达到MATLAB识别的扩展名为wav的声音文件格式,在声音时间上也要有控制。
然后对端点检测的核心算法vad进行探讨和研究,主要运用了短时能量和过零率两者配合实现可靠的端点检测,并对其中参数进行一步探讨。
2语音信号端点检测概述
2.1语音识别系统简介
在做本课题的过程中,采用的是非实时的处理方法,在录音时必须声音进行声音控制。
在一个语音识别系统中,程序必须能够判断当前是静音还是对象在说话,如果对象发出了语音信号,那么应该保存这段语音信号,将其头部和尾部的静音部分删除掉。
这一功能被称为语音信号的端点检测[2]。
语音识别系统是建立在一定的硬件平台和操作系统之上的一套应用软件系统。
其硬件平台一般是一台个人机或是一台工作站;操作系统可以选择UNIX或WINDOWS系列。
语音识别一般分两个步骤。
第一步是系统“学习”或“训练”阶段。
这一阶段的任务是建立识别基本单元的声学模型以及进行文法分析的语言模型等。
第二步是“识别”或“测试”阶段。
根据识别系统的类型选择能够满足要求的一种识别方法,采用语音分析方法分析出这种识别方法所要求的语音特征参数,按照一定的准则和测度与系统模型进行比较,通过判决得出识别结果。
图1语音识别系统的组成框图
语音识别系统,除了包括核心的识别程序,还必须包括语音输入手段、参数分析、标准声学模型、词典、文法语言模型等,以及制作这些东西所需的工具。
根据识别结果在实际环境下实现一定的应用,还必须考虑耐环境技术,用户接口输入和输出技术等。
因此,语音识别技术加上各种外围技术的组合,才能构成一个完整的实际应用的语音识别系统。
从语音识别系统的各个功能划分的角度出发,语音识别系统可分为语音信号的预处理部分、语音识别系统的核心算法部分以及语音识别系统的基本数据库等几部分。
图1给出了一般语音识别系统的组成框图[5]。
图1给出了一般语音识别系统的组成框图。
识别预处理的过程主要是对通过话筒或电话线路输入的语音信号进行数字化采样、在语音检测部切出语音区间、经过语音分析部变换成特征向量,在语音识别部根据单词字典和文法的约束进行语音特征向量时间序列和语音声学模型的匹配输出识别结果,然后或直接把识别出的单词或由单词列组成的句子输出给应用部分(Application),或把识别结果转接成控制信号,控制应用部分的动作[3]。
2.2语音信号的端点检测在语音识别系统中的地位和作用
端点检测的目的是从包含语音的一段信号中确定出语音的起点以及终点。
有效的端点检测不仅能使处理时间减到最小,而且能排除无声段的噪声干扰,从而使识别系统具有良好的识别性能。
有学者用一个多话者的数字识别系统做了如下一个实验。
首先对所有记录的语音用手工找出准确的端点,得到它们的识别率;然后逐帧(帧长为15ms)加大端点检测的误差,在每次加大误差的同时得到它们的识别率。
结果表明在端点检测准确时识别率为93%的系统,当端点检测的误差在+60ms(4帧)时,识别率降低了3%;在+90ms(6帧)时,降低了10%;而当误差在进一步加大时,识别率急剧下降。
这说明端点检测的成功与否甚至在某种程度上直接决定了整个语音识别系统的成败[4]。
在设计一个成功的端点检测模块时,会遇到下列一些实际困难:
⑴信号取样时,由于电平的变化,难于设置对各次试验都适用的阀值。
⑵在发音时,人的咂嘴声或其他某些杂音会使语音波形产生一个很小的尖峰,并可能超过所设计的门限值。
此外,人呼吸时的气流也会产生电平较高的噪声。
⑶取样数据中,有时存在突发性干扰,使短时参数变得很大,持续很短时间后又恢复为寂静特性。
应该将其计入寂静段中。
⑷弱摩擦音时或终点处是鼻音时,语音的特性与噪声极为接近,其中鼻韵往往还拖得很长。
⑸如果输入信号中有50Hz工频干扰或者A/D变换点的工作点偏移时,用短时过零率区分无声和清音就变的不可靠。
一种解决方法是算出每一帧的直流分量予以减除,但是这无疑加大了运算量,不利于端点检测算法的实时执行;另一种解决方法是采用一个修正短时参数,它是一帧语音波形穿越某个非零电平的次数,可以恰当地设置参数为一个接近于零的值,使得过零率对于清音仍具有很高的值,而对于无声段值却很低。
但事实上,由于无声段以及各种清音的电平分布情况变化很大,在有些情况下,二者的幅度甚至可以相比拟,这给这个参数的选取带来了极大的困难[5]。
由上可见,一个优秀的端点检测算法应该能满足:
⑴门限值应该可以对背景噪声的变化有一定的适应。
⑵将短时冲击噪声和人的咂嘴等瞬间超过门限值的信号纳入无声段而不是有声段。
⑶对于爆破音的寂静段,应将其纳入语音的范围而不是无声段。
⑷应该尽可能避免在检测中丢失鼻韵和弱摩擦音等与噪声特性相似、短时参数较少的语音。
⑸应该避免使用过零率作为判决标准而带来的负面影响。
在做本课题时,端点检测方法是将语音信号的短时能量与过零率相结合加以判断的。
但这种端点检测算法如果运用不好,将会发生漏检或虚检的情况。
语音信号大致可以分为浊音和清音两部分,在语音激活期的开始往往是电平较低的清音,当背景噪声较大时,清音电平与噪声电平相差无几。
采用传统的语音端点检测方法很容易造成语音激活的漏检。
而语音信号的清音段,对于语音的质量起着非常重要的作用。
另一方面,较大的干扰信号,又有可能被当成是语音信号,造成语音激活的虚检。
如可能出现弱摩擦音和鼻韵被切除、误将爆破音的寂静段或字与字的间隔认为是语音的结束、误将冲击噪声判决为语音等情况,因而实际运用中,如果处理的不好,则效果欠佳。
为了克服传统端点检测算法的缺点,已有很多改进方法被提出来。
例如,可以考虑采用基于相关性的语音端点检测算法。
这种方法依据的理论是:
语音信号具有相关性,而背景噪声则无相关性。
因而利用相关性的不同,可以检测出语音,尤其是可以将清音从噪声中检测出来。
为此,可以定义一种有效的相关函数,并且通过实验可以找到判别门限设定方法以及防止漏检和虚检的方法[6]。
3语音信号端点检测vad算法的探讨和实现
本课题的端点检测算法,该算法采用的是非实时运行的,并且在实现端点检测时,是在MATLAB下运行实现的,在MATLAB中,声音文件是扩展名为wav文件中获取语音采样,所以在进行端点检测之前要将声音文件先处理和转换为wav文件格式的声音文件,再将其分帧并计算短时能量和过零率参数,然后进行端点检测。
这种工作方式被称为离线(off-line)处理方法,而实时的处理方法则是在线(on-line)的。
以下将对语音信号的分帧,短时能量,过零率以及端点检测进行探讨和实现。
3.1语音信号的分帧
对语音信号进行分帧,本课题采用了voicebox工具箱中的函数enframe。
其函数主要功能是将待端点检测的声音文件进行分帧,进行语音信号的采样,以便计算短时能量和过零率,为端点检测做基本的准备,在进行分帧时,根据实际的要求定义帧的属性,比如帧长和帧移。
在使用这个函数时,非常方便,只用将其加入到MATLAB的搜索路径,就可以直接使用该函数了。
Enframe函数的语法为:
f=enframe(x,len,inc);这里x为输入语音信号,len指定了帧长,inc指定帧移。
函数返回为n*len的一个矩阵,每行都是一帧数据。
例如对大象声音的采样序列进行分帧的过程为以下所示,以下命令在MATLAB中的commandwindow里直接就可以看到变量的属性[8]。
>>y=enframe(x,240,80);
>>whosyx
NameSizeBytesClass
x66156x1529248doublearray
y824x2401582080doublearray
Grandtotalis263916elementsusing2111328bytes
可以看到包含语音采样的一维数组x经过enframe处理后得到二维数组y,有824行,表示总的帧数为有824帧,每行都是240个采样,为一帧,帧移是80,在进行采样时,当一帧采样完时,采样第二帧,那么就有80帧与第一次采样是一样的,这就是帧移的用法。
还可以看到属性,比如x是66156*1的矩阵,有529248bytes,y是824*240的矩阵,有1582020bytes。
如果改变帧长为120和帧移为40,输出结果如下,同样可以看到采样后变量x和y的属性如下:
>>y=enframe(x,120,40);
>>whosyx
NameSizeBytesClass
x66156x1529248doublearray
y1651x1201584960doublearray
Grandtotalis264276elementsusing2114208bytes
3.2短时能量的计算
图2是数字“0”的波形图,可以看到,在7500之前的部分信号幅度很低,明显是属于静音,而在7500以后,信号幅度开始增强,并呈现比较明显的周期性。
在波形下半部分可以观察到有规律的尖峰,两个尖峰之间的距离就是所谓的基音周期,实际上也就是说话人的声带振动的周期[9]。
图2数字“0”的语音波形
由图可以很直观地想到,可以用信号的幅度作为特征,区分静音和语音。
只要设定一个门限,当信号的幅度超过该门限的时候,就认为语音开始,当幅度降低到门限以下就认为语音结束。
实际上,一般是用短时能量的概念来描述语音信号的幅度的。
对于输入的语音信号X(N),其中N为采样点,首先进行帧的操作,将语音信号分成每20—30毫秒一段,相邻两帧起始点之间的间隔为10毫秒,也就是说两帧之间有10—20毫秒的交叠。
由于采样频率的差异,帧长和帧移所对应的实际采样点数也是不同的。
对于8KHZ采样频率,30毫的帧长对应240点,记为N,而10毫秒的帧移对应80点,记为M[11]。
对于第i帧,第n个样本,它与原始语音信号的关系为:
xi(n)=x[(i-1)M+n]
第i帧语音信号的短时能量可以用下面几种算法得到:
e(i)=Σ|xi(n)|
e(i)=Σx²n(n)
e(i)=∑logx²n(n)
三种定义的短时能量分别用下面三行MATLAB命令实现:
amp1=sum(abs(y),2);
amp2=sum(y.*y,2);
amp3=sum(log(y.*y+eps),2);
其中amp3中之所以加上小的浮点数eps,是为了防止log运算中可能出现的溢出。
以下利用语音信号分帧的帧长和帧移的不同取值,对三种短时能量的图形进行分析。
图3为当帧长len=240,帧移inc=80时,大象声音的三种短时能量的图形:
图3len=240,inc=80大象三种短时能量图
图4为当帧长len=120,帧移inc=40时,大象声音的三种短时能量的图形:
图4len=120,inc=40大象三种短时能量图
由以上两图可以看出,三种能量的输出要由语音信号的分帧函数enframe决定,当分帧的帧长和帧移比较大的时候,那么输出的短时能量值就比较大,当语音信号的分帧的帧长和帧移比较小的时候,那么输出的短时能量值就比较小。
而且由以上两图可以看出,图3相对应的值几乎是图4的两倍,这主要是图3的帧长和帧移的取值是图4的两倍,并且短时能量的主要是对矩阵y求和的过程,所以从图形中可以直观地看到,不同的帧长和帧移对短时能量输出的影响[7]。
能量之前应用该滤波器,还可以起到消除直流漂移、抑制随机噪声和提升清音部分能量的效果。
将这些写在MATLAB语句是[12]:
amp=sum(abs(enframe(filter([1-0.9375],1,x),framelen,frameinc)),2);
在这里采用的是绝对值能量,实际上就是平均幅度。
3.3过零率的计算
将语音信号分帧后计算每帧的短时能量,再设定一个门限,就可以实现一个简单的端点检测算法。
但是这样的算法是很不可靠的,因为人的语音分清音和浊音两种,浊音为声带振动发出,对应的语音信号有幅度高,周期性明显的特点,而清音则不会有声带的振动,只是靠空气在口腔中的摩擦,冲击或爆破而发声,其短时能量一般比较小,如声母“s”,“c”等的幅度很低,往往会基于能量的算法漏过去。
图5显示的是数字“7”的波形,可见声母“q”的范围约为6500-7500,其幅度明显比后面的幅度低,而比前面的静音部分高。
声母“s”和“c”的幅度往往更低,以至于有时用肉眼都难以与静音部分相辨别,因此基于能量的算法对这些清音信号几乎无能为力[9]。
图5数字“7”的波形
对于图5的静音段声母开始段,可以发现静音和声母的区分点大致在6550左右。
尽管此时不能用短时能量可靠地区分,但是可以发现在静音段信号的波形变化相对比较缓慢,而在清音段,由于口腔空气摩擦的效果,所造成的波形在幅度上的变化比较剧烈,通常可以用一帧信号中波形穿越零电平的次数来描述这种变化的剧烈程度,称为过零率。
实际应用中,为了避免静音段的随机噪声产生过高的过零率,通常都先设定一个门限,当前后两个采样的符号不同,而且差值大于该门限的时候,就将过零率的数值加1。
在MATLAB中,用以下核心代码实现过零率:
zcr=zeros(size(y,1),1);
delta=0.02;
fori=1:
size(y,1)
x=y(i,:
);
forj=1:
length(x)-1
ifx(j)*x(j+1)<0&abs(x(j)-x(j+1))>delta
zcr(i)=zcr(i)+1;
end
end
end
其核心思想是:
判断相邻两帧的符号是否小于零,并且两帧的差值是否大于设定的一个门限值delta,如果满足以上两个条件,那么过零率加1。
其中设置了门限delta=0.02,这是个经验值,可以进行细微的调整。
在此条件下,可以得到大象的过零率波形,如图6所示:
图6大象声音的过零率
为了进一步探讨过零率对语音信号的判断作用,分别对数字“7”和“5”进行过零率输出图形进行比较,图7为数字“7”的过零率图形,图8为数字“5”的过零率图形:
图7数字“7”的过零率
图8数字“5”的过零率
从图可以看到,数字“7”语音信号部分的幅度比较低,但是其过零率的数值却很高,峰值将近50,而在后面的韵母部分过零率则比较低,在20左右。
而数字“5”语音信号部分一开始的幅度就比较高,而过零率也比较高,随着幅度的升高,过零率也升高。
由此可见,过零率能够敏感得表示清音。
在实际应用中,通常是利用过零率来检测清音,用短时能量来检测浊音,两者配合实现可靠的端点检测。
3.4端点检测的流程和算法实现
3.4.1端点检测的流程
在开始进行端点检测之前,首先为短时能量和过零率分别确定两个门限。
一个是比较低的门限,其数值比较小,对信号的变化比较敏感,很容易就会被超过。
另一个是比较高的门限,数值比较大,信号必须达到一定的强度,该门限才可能被超过。
低门限被超过未必就是语音的开始,有可能是时间很短的噪声引起的。
高门限被超过则可以基本确信是由于语音信号引起的。
整个语音信号的端点检测可以分为四段:
静音,过渡段,语音段,结束。
程序中使用一个变量status来表示当前所处的状态。
在静音段,如果能量或过零率超过了低门限,就应该开始标记起始点,进入过度段。
在过度段中,由于参数的数值比较小,不能确信是否处于真正的语音段,因此只要两个参数的数值都回落到低门限以下,就将当前状态恢复到静音状态。
而如果在过度段中两个参数中的任一个超过了高门限,就可以确信进入语音段了。
一些突发性的噪声也可以引起短时能量或过零率的数值很高,但是往往不能维持足够长的时间,如门窗的开关、物体的碰撞等引起的噪声,这些都可以通过设定最短时间门限来判别。
当前状态处于语音段时,如果两个参数的数值降低到低门限以下,而且总的记时长度小于最短时间门限,则认为这是一段噪音,继续扫描以后的语音数据。
否则就标记好结束端点,并返回。
3.4.2端点检测算法的实现
在实现端点检测的算法中,对语音信号的分帧,设帧长len=240,帧移inc=80。
在进行端点检测之前,首先将语音信号进行幅度归一化处理到[-1,1],为了避免幅度太大,不便于分析。
在MATLAB中,用以下语句实现:
x=double(x);
x=x/max(abs(x));在端点检测时,设置最大静音长度maxsilence=3,也就是为3*10ms=30ms,并且设置一个符号标记静音,用silence表示,在实际设置时,可以根据实际情况进行微调,不同的对象发出的声音的特点不同,比如音频,音调以及发音的连续性,比如大象发出的声音一般都是连续性的吼叫,而人发出声音,一般都是字词句,所以二者有者的最大静音长度的设置有着很大的不同,大象的最大静音长度可以设置相对小一些。
在端点检测的过程中,处于语音段的时候,那么就要对语音段中出现的静音进行判断,如果出现静音(silence)的长度小于maxsilence,那么认为静音还不够长,语音段还尚未结束,语音还在进行,将继续判断语音信号。
与此同时,还要设置一个最小噪声长度minlen=15,也就是为15*10ms=150ms,并且设置一个标记语音信号的长度,用count来表示,此参数主要是用于判断一些突发性和偶然性的噪声,比如关门声和关窗声,这些突发性的声音的能量都很大,甚至于可以达到所设定的能量的高门限,但是这些声音属于噪声,并不是我们所需要的有效语音信号部分,所以必须能够判断出来并且过滤。
在实际应用时,也可以对此参数根据实际情况进行调整。
在语音段的过程中,要对已经满足短时能量和过零率的语音信号进行进一步的判断,如果语音信号长度标记count小于最小噪声长度minlen,那么认为语音长度太短,判断为噪声[13]。
在前面的过零率计算方法用到了两重循环,其速度比较慢,为了提高算法的效率,在端点检测中采用一种矢量化的计算方法在,MATLAB中是用以下核心代码实现的:
tmp1=enframe(x(1:
end-1),FrameLen,FrameInc);
tmp2=enframe(x(2:
end),FrameLen,FrameInc);
signs=(tmp1.*tmp2)<0;diffs=(tmp1-tmp2)>0.02;
zcr=sum(signs.*diffs,2);
temp1和temp2都是由X得到,但是相互之间相差一个采样点,即相邻的两帧。
signs为符号数组,用于存储相邻两个采样点的符号是否相同,即是否穿越零电频,如果为负,则表明穿越零电频,反之则没有穿越。
设置了门限0.02,这是个经验值,diffs用来度量相邻两个采样点之间的距离,要为相邻两个采样点定义一个距离门限,如果信号只是简单地穿越零电频,也不能说明是语音信号,因为一些噪声也是有可能穿越零电频,但是其幅度很小,所以就为其设置一个门限,可以有效地防止噪声。
如果距离大于门限0.02,则为1,否则为0。
然后将两个矩阵点相乘就可以得到同时满足两个基本点条件的采样点矩阵。
然后将其按帧求和,就可以得到过零率。
在计算短时能量时,主要用的时取绝对值的短时能量。
计算短时能量之前,首先将语音信号通过一个一阶高通滤波器1-0.9375z-1,可以有效滤除低频干扰,尤其是50Hz或60Hz的工频干扰,将对于语音识别更为有用的高频部分的频谱进行提升。
在计算短时能量之前应用该滤波器,还可以起到消除直流漂移、抑制随机噪声和提升清音部分能量的效果。
将这些写在MATLAB语句是:
amp=sum(abs(enframe(filter([1-0.9375],1,x),framelen,frameinc)),2);
在这里采用的是绝对值能量,实际上就是平均幅度。
以上进行了常数设置,以及短时能量和过零率的计算,然后分别为短时能量和过零率计算和定义两个门限,一个高门限和一个低门限。
以下将对端点检测的四个阶段进行讨论。
四个阶段:
静音,过渡段,语音段,结束,分别用0123来表示。
在静音段和过渡段(0,1),如果语音信号的短时能量amp(n)大于短时能量的高门限amp1,那么可以确信进入语音段,status=2;静音silence=0;语音长度标识count加1。
如果短时能量amp(n)只大于短时能量的低门限amp2或者过零率zcr(n)大于低门限zcr2,那么只能判断可能处于语音段,status=1。
在语音段
(2),如果短时能量amp(n)大于短时能量低门限amp2或者过零率zcr(n)大于过零率的低门限zcr2,那么就可以判断保持在语音段,语音长度count加1。
在语音段中,还要判断静音长度silence是否小于最大静音长度,如果小于,那么认为静音还不够长,语音还没有结束,语音还在进行,语音长度count加1。
同时也要判断语音的长度count,如果count小于最小噪声长度minlen,那么认为语音长度count太短,不是语音信号,是噪声,status=0;count=0。
最后一个阶段,结束(3)[10]。
程序在最后还将原始语音信号、短时能量和过零率绘制出来,同时在各自图形上用红线标出了开始端点和结束端点。
该函数vad返回两个变量x1和x2分别为起始端点和结束端点的帧数。
以下为数字“7”和数字“4”的端点检测图:
图9数字“7”的端点检测图
图10数字“4”的端点检测图
由图10可以看到,声母s的短时能量明显比较低,即便是用手工标注也很容易将其误认为是噪声而切除,但是该段的过零率很高,可以很准确地区分静音和声母,这就保证了端点检测的准确性[2]。
4课题过程中遇到的困难及解决
4.1遇到的主要困难
本课题主要是为语音识别系统提供一个语音信号的端点检测功能,端点检测就是要能够确定语音信号的起点和终点,使语音识别系统处理时间减到最小,排除无声段的噪声干扰,从而使识别系统具有良好的识别功能。
所以在设计