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