annotate Code/Descriptors/yin/private/src/yink.m @ 4:92ca03a8fa99 tip

Update to ICASSP 2013 benchmark
author Dawn Black
date Wed, 13 Feb 2013 11:02:39 +0000
parents
children
rev   line source
Dawn@4 1 function r=yink(p,fileinfo)
Dawn@4 2 % YINK - fundamental frequency estimator
Dawn@4 3 % new version (feb 2003)
Dawn@4 4 %
Dawn@4 5 %
Dawn@4 6
Dawn@4 7 %global jj;
Dawn@4 8 %jj=0;
Dawn@4 9 % process signal a chunk at a time
Dawn@4 10 idx=p.range(1)-1;
Dawn@4 11 totalhops=round((p.range(2)-p.range(1)+1) / p.hop);
Dawn@4 12 r1=nan*zeros(1,totalhops);r2=nan*zeros(1,totalhops);
Dawn@4 13 r3=nan*zeros(1,totalhops);r4=nan*zeros(1,totalhops);
Dawn@4 14 idx2=0+round(p.wsize/2/p.hop);
Dawn@4 15 while (1)
Dawn@4 16 start = idx+1;
Dawn@4 17 stop = idx+p.bufsize;
Dawn@4 18 stop=min(stop, p.range(2));
Dawn@4 19 xx=sf_wave(fileinfo, [start, stop], []);
Dawn@4 20 % if size(xx,1) == 1; xx=xx'; end
Dawn@4 21 xx=xx(:,1); % first channel if multichannel
Dawn@4 22 [prd,ap0,ap,pwr]=yin_helper(xx,p);
Dawn@4 23 n=size(prd ,2);
Dawn@4 24 if (~n) break; end;
Dawn@4 25 idx=idx+n*p.hop;
Dawn@4 26
Dawn@4 27 r1(idx2+1:idx2+n)= prd;
Dawn@4 28 r2(idx2+1:idx2+n)= ap0;
Dawn@4 29 r3(idx2+1:idx2+n)= ap;
Dawn@4 30 r4(idx2+1:idx2+n)= pwr;
Dawn@4 31 idx2=idx2+n;
Dawn@4 32 end
Dawn@4 33 r.r1=r1; % period estimate
Dawn@4 34 r.r2=r2; % gross aperiodicity measure
Dawn@4 35 r.r3=r3; % fine aperiodicity measure
Dawn@4 36 r.r4=r4; % power
Dawn@4 37 sf_cleanup(fileinfo);
Dawn@4 38 % end of program
Dawn@4 39
Dawn@4 40
Dawn@4 41
Dawn@4 42 % Estimate F0 of a chunk of signal
Dawn@4 43 function [prd,ap0,ap,pwr]=yin_helper(x,p,dd)
Dawn@4 44 smooth=ceil(p.sr/p.lpf);
Dawn@4 45 x=rsmooth(x,smooth); % light low-pass smoothing
Dawn@4 46 x=x(smooth:end-smooth+1);
Dawn@4 47 [m,n]=size(x);
Dawn@4 48 maxlag = ceil(p.sr/p.minf0);
Dawn@4 49 minlag = floor(p.sr/p.maxf0);
Dawn@4 50 mxlg = maxlag+2; % +2 to improve interp near maxlag
Dawn@4 51
Dawn@4 52
Dawn@4 53 hops=floor((m-mxlg-p.wsize)/p.hop);
Dawn@4 54 prd=zeros(1,hops);
Dawn@4 55 ap0=zeros(1,hops);
Dawn@4 56 ap=zeros(1,hops);
Dawn@4 57 pwr=zeros(1,hops);
Dawn@4 58 if hops<1; return; end
Dawn@4 59
Dawn@4 60 % difference function matrix
Dawn@4 61 dd=zeros(floor((m-mxlg-p.hop)/p.hop),mxlg);
Dawn@4 62 if p.shift == 0 % windows shift both ways
Dawn@4 63 lags1=round(mxlg/2) + round((0:mxlg-1)/2);
Dawn@4 64 lags2=round(mxlg/2) - round((1:mxlg)/2);
Dawn@4 65 lags=[lags1; lags2];
Dawn@4 66 elseif p.shift == 1 % one window fixed, other shifts right
Dawn@4 67 lags=[zeros(1,mxlg); 1:mxlg];
Dawn@4 68 elseif p.shift == -1 % one window fixed, other shifts right
Dawn@4 69 lags=[mxlg-1:-1:0; mxlg*ones(1,mxlg)];
Dawn@4 70 else
Dawn@4 71 error (['unexpected shift flag: ', num2str(p.shift)]);
Dawn@4 72 end
Dawn@4 73 rdiff_inplace(x,x,dd,lags,p.hop);
Dawn@4 74 rsum_inplace(dd,round(p.wsize/p.hop));
Dawn@4 75 dd=dd';
Dawn@4 76 [dd,ddx]=minparabolic(dd); % parabolic interpolation near min
Dawn@4 77 cumnorm_inplace(dd);; % cumulative mean-normalize
Dawn@4 78
Dawn@4 79 % first period estimate
Dawn@4 80 %global jj;
Dawn@4 81 for j=1:hops
Dawn@4 82 d=dd(:,j);
Dawn@4 83 if p.relflag
Dawn@4 84 pd=dftoperiod2(d,[minlag,maxlag],p.thresh);
Dawn@4 85 else
Dawn@4 86 pd=dftoperiod(d,[minlag,maxlag],p.thresh);
Dawn@4 87 end
Dawn@4 88 ap0(j)=d(pd+1);
Dawn@4 89 prd(j)=pd;
Dawn@4 90 end
Dawn@4 91
Dawn@4 92 % replace each estimate by best estimate in range
Dawn@4 93 range = 2*round(maxlag/p.hop);
Dawn@4 94 if hops>1; prd=prd(mininrange(ap0,range*ones(1,hops))); end
Dawn@4 95 %prd=prd(mininrange(ap0,prd));
Dawn@4 96
Dawn@4 97
Dawn@4 98 % refine estimate by constraining search to vicinity of best local estimate
Dawn@4 99 margin1=0.6;
Dawn@4 100 margin2=1.8;
Dawn@4 101 for j=1:hops
Dawn@4 102 d=dd(:,j);
Dawn@4 103 dx=ddx(:,j);
Dawn@4 104 pd=prd(j);
Dawn@4 105 lo=floor(pd*margin1); lo=max(minlag,lo);
Dawn@4 106 hi=ceil(pd*margin2); hi=min(maxlag,hi);
Dawn@4 107 pd=dftoperiod(d,[lo,hi],0);
Dawn@4 108 ap0(j)=d(pd+1);
Dawn@4 109 pd=pd+dx(pd+1)+1; % fine tune based on parabolic interpolation
Dawn@4 110 prd(j)=pd;
Dawn@4 111
Dawn@4 112 % power estimates
Dawn@4 113 idx=(j-1)*p.hop;
Dawn@4 114 k=(1:ceil(pd))';
Dawn@4 115 x1=x(k+idx);
Dawn@4 116 x2=k+idx+pd-1;
Dawn@4 117 interp_inplace(x,x2);
Dawn@4 118 x3=x2-x1;
Dawn@4 119 x4=x2+x1;
Dawn@4 120 x1=x1.^2; rsum_inplace(x1,pd);
Dawn@4 121 x3=x3.^2; rsum_inplace(x3,pd);
Dawn@4 122 x4=x4.^2; rsum_inplace(x4,pd);
Dawn@4 123
Dawn@4 124 x1=x1(1)/pd;
Dawn@4 125 x2=x2(1)/pd;
Dawn@4 126 x3=x3(1)/pd;
Dawn@4 127 x4=x4(1)/pd;
Dawn@4 128 % total power
Dawn@4 129 pwr(j)=x1;
Dawn@4 130
Dawn@4 131 % fine aperiodicity
Dawn@4 132 ap(j)=(eps+x3)/(eps+(x3+x4)); % accurate, only for valid min
Dawn@4 133
Dawn@4 134 %ap(j)
Dawn@4 135 %plot(min(1, d)); pause
Dawn@4 136
Dawn@4 137 prd(j)=pd;
Dawn@4 138 end
Dawn@4 139
Dawn@4 140
Dawn@4 141
Dawn@4 142 %cumulative mean-normalize
Dawn@4 143 function y=cumnorm(x)
Dawn@4 144 [m,n]=size(x);
Dawn@4 145 y = cumsum(x);
Dawn@4 146 y = (y)./ (eps+repmat((1:m)',1,n)); % cumulative mean
Dawn@4 147 y = (eps+x) ./ (eps+y);