computes the lag of the average magnitude difference function > called by ::ComputePitch > > @param x: audio signal > @param iBlockLength: block length in samples > @param iHopLength: hop length in samples > @param f_s: sample rate of audio data > > @retval f_0 amdf lag (in Hz) > @retval t time stamp of f_0 estimate (in s) ======================================================================
0001 %computes the lag of the average magnitude difference function 0002 %> called by ::ComputePitch 0003 %> 0004 %> @param x: audio signal 0005 %> @param iBlockLength: block length in samples 0006 %> @param iHopLength: hop length in samples 0007 %> @param f_s: sample rate of audio data 0008 %> 0009 %> @retval f_0 amdf lag (in Hz) 0010 %> @retval t time stamp of f_0 estimate (in s) 0011 % ====================================================================== 0012 function [f_0, t] = PitchTimeAmdf(x, iBlockLength, iHopLength, f_s) 0013 0014 % blocking 0015 [x_b, t] = ToolBlockAudio(x, iBlockLength, iHopLength, f_s); 0016 iNumOfBlocks = size(x_b, 1); 0017 0018 % allocate memory 0019 f_0 = zeros(1, iNumOfBlocks); 0020 0021 % initialization 0022 f_max = 2000; 0023 f_min = 50; 0024 eta_min = round(f_s/f_max); 0025 eta_max = round(f_s/f_min); 0026 0027 for n = 1:iNumOfBlocks 0028 0029 if (sum(abs(x_b(n, :))) == 0) 0030 f_0(n) = 0; 0031 continue; 0032 end 0033 0034 % calculate the amdf_I minimum 0035 afAMDF = amdf_I(x_b(n, :), eta_max); 0036 [fDummy, T_0(n)] = min(afAMDF(1+eta_min:end)); 0037 0038 % convert to Hz 0039 f_0(n) = f_s ./ (T_0(n) + eta_min); 0040 end 0041 end 0042 0043 function [AMDF] = amdf_I(x, eta_max) 0044 K = length(x); 0045 0046 AMDF = ones(1, K); 0047 0048 for eta=0:min(K-1,eta_max-1) 0049 AMDF(eta+1) = sum(abs(x(1:K-1-eta) - x(eta+2:end))) / K; 0050 end 0051 end