gusucode.com > matlab编程倒谱法来进行基音周期检测源码程序 > gusucode/CEP/CEP2.m
clear all load ma1_4; x=ma1_4; figure,plot(x); len=length(x); fss=enframe(x,256,128);xlabel('采样点数');ylabel('幅度');title('原始语音图像'); %分帧加窗 F=8000; [row,col]=size(fss);%记录分帧后矩阵大小:row代表帧数,col代表帧长 T=zeros(1,row);%用来存储检测出的基音周期对应的抽样点数 zeronum=0;sum1=0;k=0; zcr=countoverzeroing(x,256,128); %计算过零率 figure,plot(zcr,'.');xlabel('分帧数');ylabel('过零率');title('过零率统计');grid on; %绘制过零率图像 for m=1:row-1 f1=zeros(1,col);%用来存储当前正在检测基音周期的帧 for n=1:col f1(1,n)=fss(m,n); end A1=lpc(f1,18); E1=abs(filter(A1,1,f1)); % LPC系数 逆滤波 e1=abs(fftshift(fft(E1))); % FFT if e1~=0 e1=log(e1); end % 绝对值取对数 for n=1:128 e1(n)=0; end for n=144:256 e1(n)=0; end %高频分量置零 500/800*128+128=144 EE1=abs(ifft(e1)); % IDFT for n=1:64 EE1(n)=0; end for n=181:256 EE1(n)=0; end %噪音尖峰置零 N=max(EE1); for n=1:128 if abs(EE1(n)-N)<0.0001 n1=n; end end %根据峰值,检出基音周期 if zcr(m,1)>1 && zcr(m,1)<8 T(1,m)=n1;sum1=sum1+T(1,m);k=k+1; else T(1,m)=0;zeronum=zeronum+1; end end %根据过零率,去除静音,清音 mean=sum1/(row-zeronum); zeronum=0;sum=0; for m=1:row if T(1,m)<mean*0.5|T(1,m)>mean*1.5 T(1,m)=0;zeronum=zeronum+1; end sum=sum+T(1,m); end turemean=sum/(row-zeronum); %去除幅度与均值相差较大的野点,剔除后再求平均值 zeronum=0;sum=0; for m=1:row if T(1,m)<turemean*0.8|T(1,m)>turemean*1.2 T(1,m)=F;zeronum=zeronum+1; end sum=sum+T(1,m); if T(1,m)~=0 T(1,m)=1/T(1,m); end end %第二次去除野点,求平均值 turemean1=(sum-zeronum*F)/(row-zeronum); figure,plot(F*T,'.');hold on;xlabel('分帧数');ylabel('基音频率/HZ');title('基音周期统计'); %转换各帧周期为频域数据,绘图 for m=1:row if turemean1~=0 T(1,m)=1/turemean1; end end plot(F*T,'r');hold off; axis([0 row+5 0 140]);grid on; %绘制基音周期平均值 fmean=F*T(1)