Home > ACA-Code > ComputeFingerprint.m

ComputeFingerprint

PURPOSE ^

computes a fingerprint of the audio data (only the subfingerprint, one

SYNOPSIS ^

function [SubFingerprint, tf] = ComputeFingerprint (x, f_s)

DESCRIPTION ^

computes a fingerprint of the audio data (only the subfingerprint, one
fingerprint is comprised of 256 consecutive subfingerprints.
>
> @param x: time domain sample data, 
> @param f_s: sample rate of audio data
>
> @retval F series of subfingerprints
> @retval tf time stamps for the subfingerprints
 ======================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 %computes a fingerprint of the audio data (only the subfingerprint, one
0002 %fingerprint is comprised of 256 consecutive subfingerprints.
0003 %>
0004 %> @param x: time domain sample data,
0005 %> @param f_s: sample rate of audio data
0006 %>
0007 %> @retval F series of subfingerprints
0008 %> @retval tf time stamps for the subfingerprints
0009 % ======================================================================
0010 function [SubFingerprint, tf] = ComputeFingerprint (x, f_s)
0011 
0012     % set default parameters
0013     target_fs = 5000;
0014     iBlockLength = 2048;
0015     iHopLength = 64;
0016   
0017     % pre-processing: down-mixing
0018     x = ToolDownmix(x);
0019 
0020     % pre-processing: normalization (not really necessary here)
0021     x = ToolNormalizeAudio(x);
0022 
0023     % pre-processing: downsampling to target sample rate
0024     if (f_s ~= target_fs)
0025         x = resample(x, target_fs, f_s);
0026     end
0027 
0028     % initialization: generate transformation matrix for 33 frequency bands
0029     H = generateBands_I(iBlockLength, target_fs);
0030     
0031     % initialization: generate FFT window
0032     afWindow = hann(iBlockLength, 'periodic');
0033     if (length(afWindow) ~= iBlockLength)
0034         error('window length mismatch');
0035     end                        
0036 
0037     % in the real world, we would do this block by block...
0038     [X, f, tf] = ComputeSpectrogram(x, ...
0039                                 f_s, ...
0040                                 afWindow, ...
0041                                 iBlockLength, ...
0042                                 iHopLength);
0043 
0044     % power spectrum
0045     X = abs(X) * 2 / iBlockLength;
0046     X([1 end], :) = X([1 end], :) / sqrt(2); % normalization
0047     X = abs(X).^2;
0048     
0049     % group spectral bins in bands
0050     E = H * X;
0051     
0052     % extract fingerprint through diff (both time and freq)
0053     SubFingerprint = diff(diff(E, 1, 1), 1, 2);
0054     tf = tf(1:end-1) + iHopLength / (2 * target_fs);
0055 
0056     % quantize fingerprint
0057     SubFingerprint(SubFingerprint<0) = 0;
0058     SubFingerprint(SubFingerprint>0) = 1;
0059 end
0060 
0061 function [H] = generateBands_I(iFFTLength, f_s)
0062 
0063     % constants
0064     iNumBands   = 33;
0065     f_max       = 2000;
0066     f_min       = 300;
0067     
0068     % initialize
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     % get indices falling into each band
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

Generated on Fri 22-Apr-2022 20:59:51 by m2html © 2005