Mercurial > hg > emotion-detection-top-level
comparison Code/Descriptors/yin/private/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); |