function [R,L] = match_query(D,SR,IX) % [R,L] = match_query(D,SR,IX) % Match landmarks from an audio query against the database. % Rows of R are potential maxes, in format % songID modalDTcount modalDT % i.e. there were occurrences of hashes % that occurred in the query and reference with a difference of % frames. % Input D is either audio waveform at sample rate SR, or a % 3-column array of hashes (e.g., from landmark2hash, or get_hashes_for_track). % L returns the actual landmarks that this implies for IX'th return. % 2008-12-29 Dan Ellis dpwe@ee.columbia.edu if nargin < 3 IX = 1; end if size(D, 2) == 3 % We were passed hashes, not audio Lq = []; Hq = D; else % Target query landmark density % (reference is 7 lm/s, query can be maybe 4x denser?) dens = 20; % collapse stereo if size(D,2) == 2 D = mean(D,2); end %Rt = get_hash_hits(landmark2hash(find_landmarks(D,SR))); Lq = find_landmarks(D,SR, dens); %%Lq = fuzzify_landmarks(Lq); % Augment with landmarks calculated half-a-window advanced too landmarks_hopt = 0.032; Lq = [Lq;find_landmarks(D(round(landmarks_hopt/4*SR):end),SR, dens)]; Lq = [Lq;find_landmarks(D(round(landmarks_hopt/2*SR):end),SR, dens)]; Lq = [Lq;find_landmarks(D(round(3*landmarks_hopt/4*SR):end),SR, dens)]; % add in quarter-hop offsets too for even better recall Hq = unique(landmark2hash(Lq), 'rows'); end disp(['landmarks ',num2str(size(Lq,1)),' -> ', num2str(size(Hq,1)),' hashes']); Rt = get_hash_hits(Hq); nr = size(Rt,1); if nr > 0 % Find all the unique tracks referenced [utrks,xx] = unique(sort(Rt(:,1)),'first'); utrkcounts = diff([xx',nr]); [utcvv,utcxx] = sort(utrkcounts, 'descend'); % Keep at most 20 per hit utcxx = utcxx(1:min(20,length(utcxx))); utrkcounts = utrkcounts(utcxx); utrks = utrks(utcxx); nutrks = length(utrks); R = zeros(nutrks,4); for i = 1:nutrks tkR = Rt(Rt(:,1)==utrks(i),:); % Find the most popular time offset [dts,xx] = unique(sort(tkR(:,2)),'first'); dtcounts = 1+diff([xx',size(tkR,1)]); [vv,xx] = max(dtcounts); R(i,:) = [utrks(i),vv,dts(xx),size(tkR,1)]; R(i,:) = [utrks(i),sum(abs(tkR(:,2)-dts(xx))<=1),dts(xx),size(tkR,1)]; end % Sort by descending match count [vv,xx] = sort(R(:,2),'descend'); R = R(xx,:); % Extract the actual landmarks H = Rt((Rt(:,1)==R(IX,1)) & (Rt(:,2)==R(IX,3)),:); % Restore the original times for i = 1:size(H,1) hix = find(Hq(:,3)==H(i,3)); hix = hix(1); % if more than one... H(i,2) = H(i,2)+Hq(hix,2); L(i,:) = hash2landmark(H(i,:)); end % Return no more than 100 hits, and only down to 10% the #hits in % most popular maxrtns = 100; if size(R,1) > maxrtns R = R(1:maxrtns,:); end maxhits = R(1,2); nuffhits = R(:,2)>(0.1*maxhits); %R = R(nuffhits,:); else R = []; disp('*** NO HITS FOUND ***'); end