Documentation of be_continuityBased
Index of all files: short | long | this subdirectory only: short | long
Function Synopsis
[cmlC,cmlT,amlC,amlT] = be_continuityBased(anns,beats,params)
Help text
function [cmlC,cmlT,amlC,amlT] = be_continuityBased(anns,beats,params) Description: Calculate the continuity based accuracy values as used in (Hainsworth, 2004) and (Klapuri et al, 2006) Inputs: anns - sequence of ground truth beat annotations (in seconds) beats - sequence of estimated beat times (in seconds) params - structure of beat evaluation parameters Ouputs: cmlC - beat tracking accuracy, continuity required at the correct metrical level cmlT - beat tracking accuracy, continuity not required at the correct metrical level amlC - beat tracking accuracy, continuity required at allowed metrical levels amlT - beat tracking accuracy, continuity not required at allowed metrical levels References: S. Hainsworth, "Techniques for the automated analysis of musical audio," Ph.D. dissertation, Department of Engineering, Cambridge University, 2004. A. P. Klapuri, A. Eronen, and J. Astola, "Analysis of the meter of acoustic musical signals," IEEE Transactions on Audio, Speech and Language Processing, vol. 14, no. 1, pp. 342–355, 2006. (c) 2009 Matthew Davies
Cross-Reference Information
| This function calls | This function is called by |
|---|---|
Listing of function be_continuityBased
function [cmlC,cmlT,amlC,amlT] = be_continuityBased(anns,beats,params) if nargin<3 params = be_params; end % put the beats and annotations into column vectors anns = anns(:); beats = beats(:); % remove beats and annotations that are within the first 5 seconds anns(anns<params.minBeatTime) = []; beats(beats<params.minBeatTime) = []; % Check if there are any beats, if not then exit if( or( (length(beats)<2), (length(anns)<2) ) ), disp('beat or annotation sequence is empty or too short, assigning zero to all outputs [cmlC,cmlT,amlC,amlT]'); cmlC = 0; cmlT = 0; amlC = 0; amlT = 0; return; end % also check that the beat times are in seconds and not any other time units if( or( (max(beats)>1000) , (max(anns)>1000) ) ) error('either beats or annotations are not in seconds, please rectify.'); return; end p = params.continuityBased.phaseThresh; t = params.continuityBased.periodThresh; doubleAnns = interp1([1:length(anns)],anns,[1:0.5:length(anns)]); % make different variants of annotations % normal annotations testAnns{1} = anns; % off-beats testAnns{2} = doubleAnns(2:2:end); % double tempo testAnns{3} = doubleAnns; % half tempo odd-beats (i.e. 1,3,1,3) testAnns{4} = anns(1:2:end); % half tempo even-beat (i.e. 2,4,2,4) testAnns{5} = anns(2:2:end); % loop analysis over number of variants on annotations for j=1:size(testAnns,2), [totAcc(j),contAcc(j)] = ContinuityEval(testAnns{j},beats,t,p); end % assign the accuracy scores cmlC = contAcc(1); cmlT = totAcc(1); amlC = max(contAcc); amlT = max(totAcc); function [totAcc,contAcc] = ContinuityEval(anns,beats,t,p) % sub-function for calculating continuity-based accuracy checkanns = zeros(1,max(length(anns),length(beats))); checkbeats = checkanns; cond = 0; for i=1:length(beats), cond = 0; [a,b] = min(abs(beats(i)-anns)); % look for nearest annotation to current beat if(checkanns(b)==1) % if we've already used this annotation.. cond = 0; else if or(i==1,b==1), % either first beat or first annotation, look forward on both if (and((abs(a/(anns(b+1)-anns(b)))<p), ... (abs(1-((beats(i+1)-beats(i))/(anns(b+1)-anns(b))))<t))); checkanns(b) = 1; cond = 1; end else % not first beat or first annotation, so can look backwards if (and((abs(a/(anns(b)-anns(b-1)))<p), ... (abs(1-((beats(i)-beats(i-1))/(anns(b)-anns(b-1))))<t))); checkanns(b) = 1; cond = 1; end end end % for i^th beat what is the condition checkbeats(i) = double(cond); end checkbeats = [0 checkbeats(:)' 0]; [d1,d2,d3] = find(checkbeats==0); checkbeats = checkbeats(2:end-1); % in best case, d2 = 1 & length(checkbeats) contAcc = 100*(max(diff(d2))-1)/length(checkbeats); totAcc = 100*sum(checkbeats)/length(checkbeats);
Produced by mtree2html by Hartmut Pohlheim