view extra/f0detectionyin.m @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
line wrap: on
line source
function f0 = f0detectionyin(x,fs,ws,minf0,maxf0) 
% x: input signal, fs: sampling rate, ws: integration window length, minf0: minimum f0, maxf0: maximum f0 
% f0: fundamental frequency detected in Hz 
maxlag = ws-2;                            % maximum lag 
th = 0.1;                                 % set threshold 
d = zeros(maxlag,1);                      % init variable 
d2 = zeros(maxlag,1);                     % init variable 
% compute d(tau) 
x1 = x(1:ws);  
cumsumx = sum(x1.^2); 
cumsumxl = cumsumx; 
xy = xcorr(x(1:ws*2),x1); 
xy = xy(ws*2+1:ws*3-2); 
for lag=0:maxlag-1 
    d(1+lag) = cumsumx + cumsumxl - 2*xy(1+lag); 
    cumsumxl = cumsumxl - x(1+lag).^2 + x(1+lag+ws+1)^2; 
end 
cumsum = 0; 
% compute d'(tau) 
d2(1) = 1; 
for lag=1:maxlag-1 
    cumsum = cumsum + d(1+lag); 
    d2(1+lag) = d(1+lag)*lag./cumsum; 
end 
% limit the search to the target range 
minf0lag = 1+round(fs./minf0);            % compute lag corresponding to minf0 
maxf0lag = 1+round(fs./maxf0);            % compute lag corresponding to maxf0 
if (maxf0lag>1 && maxf0lag<maxlag) 
    d2(1:maxf0lag) = 100;                 % avoid lags shorter than maxf0lag 
end 
if (minf0lag>1 && minf0lag<maxlag) 
        d2(minf0lag:end) = 100;               % avoid lags larger than minf0lag 
end 
% find the best candidate 
mloc = 1 + find((d2(2:end-1)<d2(3:end)).*(d2(2:end-1)<d2(1:end-2)));  % minima 
candf0lag = 0; 
if (length(mloc)>0) 
    I = find(d2(mloc)<th); 
    if (length(I)>0) 
        candf0lag = mloc(I(1)); 
    else 
        [Y,I2] = min(d2(mloc)); 
        candf0lag = mloc(I2); 
    end 
    candf0lag = candf0lag;                % this is zero-based indexing     
    if (candf0lag>1 & candf0lag<maxlag) 
        % parabolic interpolation 
        lval = d2(candf0lag-1);  
        val = d2(candf0lag);  
        rval= d2(candf0lag+1);  
        candf0lag = candf0lag + .5*(lval-rval)./(lval-2*val+rval);   
    end 
end         
ac = min(d2);  
f0lag = candf0lag-1;                      % convert to zero-based indexing 
f0 = fs./f0lag;                           % compute candidate frequency in Hz 
if (ac > 0.2)                             % voiced/unvoiced threshold 
    f0 = 0;                               % set to unvoiced 
end