annotate TWM.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
rev   line source
yading@10 1
yading@10 2 function [f0, f0error] = TWM (ploc, pmag, N, fs, minf0, maxf0)
yading@10 3 % Two-way mismatch algorithm (by Beauchamp&Maher)
yading@10 4 % ploc, pmag: peak locations and magnitudes, N: size of complex spectrum
yading@10 5 % fs: sampling rate of sound, minf0: minimum f0, maxf0: maximum f0
yading@10 6 % f0: fundamental frequency detected, f0error: error measure
yading@10 7 pfreq = (ploc-1)/N*fs; % frequency in Hertz of peaks
yading@10 8 [zvalue,zindex] = min(pfreq);
yading@10 9 if (zvalue==0) % avoid zero frequency peak
yading@10 10 pfreq(zindex) = 1;
yading@10 11 pmag(zindex) = -100;
yading@10 12 end
yading@10 13 ival2 = pmag;
yading@10 14 [Mmag1,Mloc1] = max(ival2); % find peak with maximum magnitude
yading@10 15 ival2(Mloc1) = -100; % clear max peak
yading@10 16 [Mmag2,Mloc2]= max(ival2); % find second maximum magnitude peak
yading@10 17 ival2(Mloc2) = -100; % clear second max peak
yading@10 18 [Mmag3,Mloc3]= max(ival2); % find third maximum magnitude peak
yading@10 19 nCand = 3; % number of possible f0 candidates for each max peak
yading@10 20 f0c = zeros(1,3*nCand); % initialize array of candidates
yading@10 21 f0c(1:nCand)=(pfreq(Mloc1)*ones(1,nCand))./((nCand+1-(1:nCand))); % candidates
yading@10 22 f0c(nCand+1:nCand*2)=(pfreq(Mloc2)*ones(1,nCand))./((nCand+1-(1:nCand)));
yading@10 23 f0c(nCand*2+1:nCand*3)=(pfreq(Mloc3)*ones(1,nCand))./((nCand+1-(1:nCand)));
yading@10 24 f0c = f0c((f0c<maxf0)&(f0c>minf0)); % candidates within boundaries
yading@10 25 if (isempty(f0c)) % if no candidates exit
yading@10 26 f0 = 0; f0error=100;
yading@10 27 return
yading@10 28 end
yading@10 29 harmonic = f0c;
yading@10 30 ErrorPM = zeros(fliplr(size(harmonic))); % initialize PM errors
yading@10 31 MaxNPM = min(10,length(ploc));
yading@10 32 for i=1:MaxNPM % predicted to measured mismatch error
yading@10 33 difmatrixPM = harmonic' * ones(size(pfreq))';
yading@10 34 difmatrixPM = abs(difmatrixPM-ones(fliplr(size(harmonic)))*pfreq');
yading@10 35 [FreqDistance,peakloc] = min(difmatrixPM,[],2);
yading@10 36 Ponddif = FreqDistance .* (harmonic'.^(-0.5));
yading@10 37 PeakMag = pmag(peakloc);
yading@10 38 MagFactor = 10.^((PeakMag-Mmag1)./20);
yading@10 39 ErrorPM = ErrorPM+(Ponddif+MagFactor.*(1.4*Ponddif-0.5));
yading@10 40 harmonic = harmonic+f0c;
yading@10 41 end
yading@10 42 ErrorMP = zeros(fliplr(size(harmonic))); % initialize MP errors
yading@10 43 MaxNMP = min(10,length(pfreq));
yading@10 44 for i=1:length(f0c) % measured to predicted mismatch error
yading@10 45 nharm = round(pfreq(1:MaxNMP)/f0c(i));
yading@10 46 nharm = (nharm>=1).*nharm + (nharm<1);
yading@10 47 FreqDistance = abs(pfreq(1:MaxNMP) - nharm*f0c(i));
yading@10 48 Ponddif = FreqDistance.* (pfreq(1:MaxNMP).^(-0.5));
yading@10 49 PeakMag = pmag(1:MaxNMP);
yading@10 50 MagFactor = 10.^((PeakMag-Mmag1)./20);
yading@10 51 ErrorMP(i) = sum(MagFactor.*(Ponddif+MagFactor.*(1.4*Ponddif-0.5)));
yading@10 52 end
yading@10 53 Error = (ErrorPM/MaxNPM) + (0.3*ErrorMP/MaxNMP); % total errors
yading@10 54 [f0error, f0index] = min(Error); % get the smallest error
yading@10 55 f0 = f0c(f0index); % f0 with the smallest error