0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 function [SubFingerprint, tf] = ComputeFingerprint (x, f_s)
0011
0012
0013 target_fs = 5000;
0014 iBlockLength = 2048;
0015 iHopLength = 64;
0016
0017
0018 x = ToolDownmix(x);
0019
0020
0021 x = ToolNormalizeAudio(x);
0022
0023
0024 if (f_s ~= target_fs)
0025 x = resample(x, target_fs, f_s);
0026 end
0027
0028
0029 H = generateBands_I(iBlockLength, target_fs);
0030
0031
0032 afWindow = hann(iBlockLength, 'periodic');
0033 if (length(afWindow) ~= iBlockLength)
0034 error('window length mismatch');
0035 end
0036
0037
0038 [X, f, tf] = ComputeSpectrogram(x, ...
0039 f_s, ...
0040 afWindow, ...
0041 iBlockLength, ...
0042 iHopLength);
0043
0044
0045 X = abs(X) * 2 / iBlockLength;
0046 X([1 end], :) = X([1 end], :) / sqrt(2);
0047 X = abs(X).^2;
0048
0049
0050 E = H * X;
0051
0052
0053 SubFingerprint = diff(diff(E, 1, 1), 1, 2);
0054 tf = tf(1:end-1) + iHopLength / (2 * target_fs);
0055
0056
0057 SubFingerprint(SubFingerprint<0) = 0;
0058 SubFingerprint(SubFingerprint>0) = 1;
0059 end
0060
0061 function [H] = generateBands_I(iFFTLength, f_s)
0062
0063
0064 iNumBands = 33;
0065 f_max = 2000;
0066 f_min = 300;
0067
0068
0069 f_band_bounds = f_min * exp(log(f_max / f_min)*(0:iNumBands) / iNumBands);
0070 f_fft = linspace(0, f_s/2, iFFTLength/2+1);
0071 H = zeros(iNumBands, iFFTLength/2+1);
0072 idx = zeros(length(f_band_bounds), 2);
0073
0074
0075 for k = 1:length(f_band_bounds)-1
0076 idx(k, 1) = find(f_fft > f_band_bounds(k), 1, 'first' );
0077 idx(k, 2) = find(f_fft < f_band_bounds(k+1), 1, 'last' );
0078 H(k,idx(k, 1):idx(k, 2)) = 1;
0079 end
0080 end