项目总结报告—基音周期的检测1.项目整体框架1.1目标了解语音基音周期估计方法,掌握自相关法估计基音周期的原理。1.2主要内容本次基音周期的估算,我们选用的是短时自相关函数法,包括四个模块。第一个模块为基音的端点检测,主要为了区分浊音和清音。第二个模块为基音检测中的带通滤波器,主要为了减少共振峰的干扰。第三个模块为短时自相关函数法做基音检测,主要为了计算出基音周期。第四个模块为平滑处理,主要为了消除偏离值点。2.模块一(端点检测)2.1主要负责工作利用能熵比法进行语音端点检测,区分语音帧的起点以及终点。2.2具体实现方法2.2.1实验步骤1)取一段语音“tone4.wav”,该语音内容是“妈妈,好吗,上马,骂人”,语音长度为3.5秒,采样率Fs=8000.进行简单的去除直流分量,然后幅值归一化,时域波形如图1所示。2)设置好分帧参数,帧长wlen=320,帧移inc=80,调用函数y=enframe(x,wlen,inc)';对语音信号x分帧处理。最后帧数Fn=337。3)设置端点检测门限值T1=0.05,使用能熵比法进行端点检测。对分帧后的语音y每一帧进行FFT运算,然后计算每一帧的能熵比值。从而计算出语音y中的语音端点。结果如图2所示。2.2.2能熵比法设语音信号时域波形为X(n),加窗分帧处理后得到的第i帧语音信号为Xi(m),则FFT后表示为Xi(k),其中下标i表示为第i帧,而k表示为第k条谱线。该语音帧在频域中的短时能量为𝐸𝑖=∑Xi(k)∗𝑛2𝑘=0𝑋𝑖(𝑘)式中,N为FFT的长度,只去正频率部分。而对于某一谱线k的能量谱为Yi(k)=Xi(k)∗Xi(k),则每个频率分量的归一化谱概率密度函数定义为𝑃𝑖(𝑘)=𝑌𝑖(𝑘)∑𝑌𝑖(𝑙)𝑁/2𝑙=0=𝑌𝑖(𝑘)𝐸𝑖𝑘=0,1,…,𝑁−1该语音帧的短时谱熵定义为𝐻𝑖=−∑𝑃𝑖(𝑘)𝑙𝑜𝑔𝑃𝑖(𝑘)𝑁/2𝑘=0其中,只取正频率部分的谱熵,对应的能熵比表示为𝐸𝐸𝐹𝑖=√1+|𝐸𝑖/𝐻𝑖|2.2.3代码编写在主程序中,执行的是[voiceseg,vosl,SF,Ef]=pitch_vad1(y,fn,T1);而调用了以下函数function[voiceseg,vosl,SF,Ef]=pitch_vad1(y,fn,T1,miniL)ifnargin4,miniL=10;endifsize(y,2)~=fn,y=y';end%把y转换为每列数据表示一帧语音信号wlen=size(y,1);%取得帧长fori=1:fnSp=abs(fft(y(:,i)));%FFT取幅值(:表示所有y(:,1)表示第一列)Sp=Sp(1:wlen/2+1);%只取正频率部分Esum(i)=sum(Sp.*Sp);%计算能量值(能量放入Esum里)prob=Sp/(sum(Sp));%计算概率H(i)=-sum(prob.*log(prob+eps));%求谱熵值(eps表示很小的数,避免为零)(谱熵放入H里)endhindex=find(H0.1);%(find返回非零元素,hindex放入,即谱熵值小于0.1的索引)H(hindex)=max(H);%(除去元音)Ef=sqrt(1+abs(Esum./H));%计算能熵比(将每一帧的能熵比放入Ef里)Ef=Ef/max(Ef);%归一化zindex=find(Ef=T1);%寻找Ef中大于T1的部分zseg=findSegment(zindex);%给出端点检测各段的信息zsl=length(zseg);%给出段数j=0;SF=zeros(1,fn);fork=1:zsl%在大于T1中剔除小于miniL的部分ifzseg(k).duration=miniLj=j+1;in1=zseg(k).begin;in2=zseg(k).end;voiceseg(j).begin=in1;voiceseg(j).end=in2;voiceseg(j).duration=zseg(k).duration;SF(in1:in2)=1;%设置SF(有话段的SF帧为1)endendvosl=length(voiceseg);%有话段的段数2.2.4实验结果图1“妈妈,好吗,上马,骂人”语音的时域波形图2图中实线代表语音起始点,虚线代表语音终点2.2.5结果分析基音周期是语音信号的重要参数之一,它描述了语音激励源的一个重要特征。语音的头、尾部并不能具有声带振动那样的周期性,也就是检测不到相应的基音周期。如果要进行基音周期的计算,首要的必然是检测语音端点,将有话段从整段语音中分离出来,才能开始对语音的基音周期进行计算.利用能熵比法检测语音端点后,该语音段可分为四段,每段的起点以及终点如图二所示.2.3总结语音的预处理是非常关键的一环,做好这个实验的关键在于理解matlab语句的作用,录入语音信号,设定好参数,进行分帧处理,并通过能熵值的大小标比较,确定好语音信号的端点。通过这次的检测,我了解了Matlab函数库非常的多,理解起来需要查阅很多公式以及资料,非常的耗时。做实验务必讲究认真专心,一步一个脚印的去做好每一个环节就可以了,与队友的配合以及沟通也是重要的一环,及时了解队友的情况,做好衔接。3.模块二(基音检测中的带通滤波器)3.1主要负责工作用带通滤波器减少共振峰的干扰。3.2具体实现方法3.2.1算法原理在使用相关法和AMDF法的基音检测之前常用到低通滤波器和带通滤波器,其主要目的是减少共振峰的干扰。在文献中作者选用了500Hz作为滤波器的上限频率,并指出选择截止频率高不利于减少噪声和共振峰的影响。所以在本书的基音检测中的预滤波器选择的带宽为60~500Hz,高频截止频率选择500Hz,是因为基频区间的高端就在这个区域中,低频截止频率选择60Hz是为了减少工频和低频噪声的干扰。我们选用IIR滤波器中的椭圆滤波器,因为IIR滤波器的运算量比FIR少,当然IIR滤波器会带来延迟,也就是相位的变化,但语音信号是对相位不敏感的信号;又选用椭圆滤波器,因为它在经典滤波器设计中相同过渡带和带宽条件下,需要的阶数比较小。在阶数相同的条件下,椭圆滤波器相比于其他类型的滤波器,能获得更窄的过渡带宽和较小的阻带波动,就这点而言,椭圆滤波器是最优的。滤波器的要求为采样频率8000Hz,通带是60~500Hz,通带波纹为1dB,阻带分别为30Hz和2000Hz,阻带衰减为40dB。3.2.2代码编写%%pr8_1_1clearall;clc;closeall;fs=8000;fs2=fs/2;%采样频率Wp=[60500]/fs2;%滤波器通带Ws=[202000]/fs2;%滤波器阻带Rp=1;Rs=40;%通带的波纹和阻带的衰减[n,Wn]=ellipord(Wp,Ws,Rp,Rs);%计算滤波器的阶数[b,a]=ellip(n,Rp,Rs,Wn);%计算滤波器的系数fprintf('b=%5.6f%5.6f%5.6f%5.6f%5.6f%5.6f%5.6f\n',b)fprintf('a=%5.6f%5.6f%5.6f%5.6f%5.6f%5.6f%5.6f\n',a)[db,mag,pha,grd,w]=freqz_m(b,a);%求取频率响应曲线plot(w/pi*fs/2,db,'k');%作图grid;ylim([-9010]);xlabel('频率/Hz');ylabel('幅值/dB');title('椭圆6阶带通滤波器频率响应曲线');3.2.3实验结果由程序计算出滤波器系数为:b=0.012280-0.0395080.0421770.000000-0.0421770.039508-0.012280a=1.000000-5.52714612.854342-16.11030711.479789-4.4101790.713507实验结果图:图3滤波前和后的语音信号3.2.4结果分析带通滤波器使原始信号变得更加平整,滤去了杂音,为基音检测减少干扰,使检测更加顺利进行。3.3总结通过这次课程实践,我深刻体会到自己在课程理论方面的不足,MATLAB的应用也相当生疏。在设计过程中,看不懂的东西很多,但是学会了通过上网搜查资料和自主从书本寻找知识。实践中遇到许多问题,但是和同学分工合作与讨论让我学会了很多平常学不到的知识。这次实践让我明白知识就像大海一样宽广,我们要像海绵吸水一样吸取有用的知识。4.模块三(短时自相关函数法做基音检测)4.1主要负责工作在前面两个步骤之后用自相关函数法去实现基音周期的检测4.2具体实现方法4.2.1算法设语音信号的时间序列x(n),它的自相关函数定义为:R(k)=Σx(n)x(n-k),K是时间的延迟量。短时自相关函数有以下重要性质:①如果信号x(n))具有周期性,周期是P,那么它的自相关函数R(k)也具有周期性,而且周期与信号x(n)的周期性相同。②当k=0时,短时自相关函数具有最大值,即在延迟量为0,±P,±2P,,,时,周期信号的自相关函数也达到最大值。③短时自相关函数是偶函数,即R(k)=R(-k)。短时自相关函数基因检测的主要原理大都是利用它的这些性质,通过比较原始信号和它的延迟后的信号之间的类似性质来确定基音周期。如果延迟量等于基音周期,那么两个信号具有最大类似性,或是直接找出短时自相关函数的两个最大值间的距离,即为基音周期的初估值。在用短时自相关函数检测基音是,常用归一化的短时自相关函数,表达式为r(k)=R(k)/R(0)以上性质②中已指出,k=0,R(0)为最大值。所以r(k)的模值永远小于或等于1。已知基音频率范围为60Hz~500Hz之间,采样率为fs时,则基音周期(样点值)范围在fs/500~fs/60之间,然后在这个范围之间寻找归一化相关函数的最大值,对应的延迟量就是基音周期。4.2.2代码编写步骤①根据前面步骤所得分帧后的语音数组,对它进行处理,把它转换为每一列数据表示一阵语音信号,行数为总的帧长。②对每一帧语音信号的基音周期进行初始化,让其为零保证清音段无基音周期。③利用前面端点检测后所得的有话段和有话段段数,对每一段的有话段的每一帧数据计算归一化自相关函数。④最后对每一帧所得的归一化自相关函数取正延迟量的部分,然后在基音频率范围内得最大值,从而可得最大值对应的样点数,利用函数循环计算,最后可以得出每段有话段内每一帧的基音周期。4.2.3代码编写用短时自相关函数法的程序:functionperiod=ACF_corr(y,fn,vseg,vsl,lmax,lmin)pn=size(y,2);ifpn~=fn,y=y';end%把y转换为每列数据表示一帧语音信号wlen=size(y,1);%取得帧长period=zeros(1,fn);%初始化fori=1:vsl%只对有话段数据处理ixb=vseg(i).begin;ixe=vseg(i).end;ixd=ixe-ixb+1;%求取一段有话段的帧数fork=1:ixd%对该段有话段数据处理u=y(:,k+ixb-1);%取来一帧数据ru=xcorr(u,'coeff');%计算归一化自相关函数ru=ru(wlen:end);%取延迟量为正值的部分[tmax,tloc]=max(ru(lmin:lmax));%在基音频率范围内寻找最大值period(k+ixb-1)=lmin+tloc-1;%给出对应最大值的延迟量endend4.2.4实验结果图4端点检测的语音信号图5有话段的基音周期4.2.5结果分析在端点检测和滤波后,经过短时自相关函数法处理后,由上面的实验结果图可看出基音周期有很多的偏离点即野点,需要进行平滑处理,也可以看出基音周期大约为40个样点数,即基音周期为40/fs,采样率为8000Hz,得周期为0.005s,基音频率为200Hz.4.3总结通过这次设计,我深刻体会到在信号处理方面我的严重不足,MATLAB的应用也相当生疏。在设计过程中