基音周期预测
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
专业班级组别
成员
实验内容:编程求解出各自声音信号的基音周期。
1 程序代码(或者软件流程图等)
(1)function zhouqi=jiyinzhouqi(filename)
%帧长和帧位移是重要的参数,位移是帧长的0~1/2
%短时自相关分析
%filename语音文件*.wav
%zhouqi基音周期,以毫秒为单位表示
[signal,fs]=wavread(filename); %用于得到声音文件的数据和采样率shift=0.02; %每次移动20毫秒
shift=round(fs*shift); %帧移
n1=fix(fs*0.01)+1; %分析起点0.01ms,帧长20ms
n2=fix(fs*0.03)+1;
shift_count=fix((length(signal)-n1)/shift);
value =zeros(1,shift_count); %存放每次移位后的帧的基音周期
for ii=1:shift_count %分析次数
if n2 data=signal(n1:n2); %加窗,提取一帧数据 N=n2-n1+1; %每一帧的长度 R=zeros(1,N); %创建一个一行N列的矩阵 for k=1:N-1 %求自相关序列 for jj=1:N-k R(k)=R(k)+data(jj)*data(jj+k); %矩阵用于储存每次自相关的结果; end end value(ii)=find_maxn(R); %调用基音周期分析函数,求最大值所对应的位置,即基音周期 n1=n1+shift; %移动帧,计算下一帧的基音周期 n2=n2+shift; end end figure(1) stem(value); %画出基因周期走势图 axis([0 length(value) 0 1000]) aver=mean(value); %基音周期的平均值,未去除野点value=value(logical(abs(value-aver)<=aver/5));%找出偏移均值超出均值的1/5的基音周期,将其去除 len= length(value); %去除大野点后剩余的基音点数 for jj=1:3:len/3 %中值平滑,滑动窗口宽度3,精度为中值1/4(剔除野点) average=(value(jj)+value(jj+1)+value(jj+2))/3; for kk=1:3 if abs((value(jj-1+kk))-average)>average/4 value(jj-1+kk)=0; %将野点置零,同时数组长度减一 end end end value=value(( value~=0)); %出去所有野点后的基音周期数组 len= length(value); %去除野点以后的基音点数 figure(2) stem(value); axis([0 length(value) 0 max(value)]) zhouqi=1000*sum(value)/len/fs; %求平均的基音周期,单位是毫秒 (2) function nmax=find_maxn(r) %寻找峰值最大的n值及基音周期 %r,自相关序列 %maxn,为峰值最大的n zer=find(r==0); %找第一个零点如果存在 jiaocha=0; %找第一近零点 ii=1; while (jiaocha<=0) if(r(ii)>0 && r(ii+1)<0 && (ii+1) jiaocha=ii; end ii=ii+1; if ii==length(r) %没有找到符合要求的点jiaocha=1; end end if length(zer)>0 %检查是否存在零点if zer(1) jiaocha=zer(1); end end r(1:jiaocha)=0; %祛除影响 maxn=max(r); %找最大值 temp=find(r==maxn); %返回第一个最大值 nmax=temp(1); (3) function zhouqi=get_frq_frame(filename) %帧长和帧位移是重要的参数,位移是帧长的0~1/2 %短时自相关分析 %filename语音文件*.wav %zhouqi基音周期,以毫秒为单位表示 [signal,fs]=wavread(filename);%用于得到声音文件的数据和采样率 shift=0.02; %每次移动20毫秒 shift=round(fs*shift); %帧移 n1=fix(fs*0.01)+1; %分析起点0.01ms,帧长20ms n2=fix(fs*0.03)+1; shift_count=fix((length(signal)-n1)/shift); value = zeros(1,shift_count); %存放每次移位后的帧的基音周期 zhouqi = zeros(1,shift_count); %存放每次移位后的帧的基音周期 for ii=1:shift_count %分析次数 if n2 data=signal(n1:n2); %加窗,提取一帧数据 N=n2-n1+1; %每一帧的长度 R=zeros(1,N); for k=1:N-1 %求自相关序列 for jj=1:N-k R(k)=R(k)+data(jj)*data(jj+k); end end value(ii)=find_maxn(R); %调用基音周期分析函数,求最大值所对应的位置,即基音周期 n1=n1+shift; %移动帧,计算下一帧的基音周期 n2=n2+shift; zhouqi(ii) = 8000/value(ii); end end for ii=1:length(zhouqi) if zhouqi(ii)==0 zhouqi(ii) = []; end end plot(zhouqi);