emmanouil@71: function [Pre,Rec,F,Acc,PreOff,RecOff,FOff,AccOff] = computeNoteLevelAccuracy(nmat1,nmat2) emmanouil@71: emmanouil@71: % Compute note-level onset-only and onset-offset accuracy (Bay09) emmanouil@71: emmanouil@71: emmanouil@71: % Initialize emmanouil@71: if (isempty(nmat1)) Pre=0; Rec=0; F=0; Acc=0; return; end; emmanouil@71: emmanouil@71: % Total number of transcribed notes emmanouil@71: Ntot = size(nmat1,1); emmanouil@71: emmanouil@71: % Number of reference notes emmanouil@71: Nref = size(nmat2,1); emmanouil@71: emmanouil@71: % Number of correctly transcribed notes, onset within a +/-50 ms range emmanouil@71: Ncorr = 0; emmanouil@71: NcorrOff = 0; emmanouil@71: for j=1:size(nmat2,1) emmanouil@71: for i=1:size(nmat1,1) emmanouil@71: if( (nmat1(i,3) == nmat2(j,3)) && (abs(nmat2(j,1)-nmat1(i,1))<=0.05) ) emmanouil@71: Ncorr = Ncorr+1; emmanouil@71: emmanouil@71: % If offset within a +/-50 ms range or within 20% of ground-truth note's duration emmanouil@71: if abs(nmat2(j,2) - nmat1(i,2)) <= max(0.05, 0.2 * (nmat2(j,2) - nmat2(j,1))) emmanouil@71: NcorrOff = NcorrOff +1; emmanouil@71: end; emmanouil@71: emmanouil@71: break; % In order to consider duplicates as false alarms emmanouil@71: emmanouil@71: end; emmanouil@71: end; emmanouil@71: end; emmanouil@71: emmanouil@71: % Number of onset-only P-R-F-Acc emmanouil@71: Nfp = Ntot-Ncorr; emmanouil@71: Nfn = Nref-Ncorr; emmanouil@71: Rec = Ncorr/Nref; emmanouil@71: Pre = Ncorr/Ntot; emmanouil@71: F = 2*((Pre*Rec)/(Pre+Rec)); emmanouil@71: Acc= Ncorr/(Ncorr+Nfp+Nfn); emmanouil@71: emmanouil@71: % Number of onset-offset P-R-F-Acc emmanouil@71: NfpOff = Ntot-NcorrOff; emmanouil@71: NfnOff = Nref-NcorrOff; emmanouil@71: RecOff = NcorrOff/Nref; emmanouil@71: PreOff = NcorrOff/Ntot; emmanouil@71: FOff = 2*((PreOff*RecOff)/(PreOff+RecOff)); emmanouil@71: AccOff= NcorrOff/(NcorrOff+NfpOff+NfnOff);