Daniel@0: function d = mirdist(x,y,dist) Daniel@0: % d = mirdist(x,y) evaluates the distance between x and y. Daniel@0: % x is the feature values corresponding to one audio file, and y is the Daniel@0: % values (for the same feature) corrdponding to one (or several) Daniel@0: % audio files. Daniel@0: % If x and y are not decomposed into frames, Daniel@0: % d = mirdist(x,y,f) specifies distance function. Daniel@0: % Default value: f = 'Cosine' Daniel@0: % If x and y are composed of clustered frames (using mircluster), the Daniel@0: % cluster signatures are compared using Earth Mover Distance. Daniel@0: % (Logan, Salomon, 2001) Daniel@0: % If x and y contains peaks, the vectors representing the peak Daniel@0: % distributions are compared using Euclidean distance. Daniel@0: % (used with mirnovelty in Jacobson, 2006) Daniel@0: % Daniel@0: % The Earth Mover Distance is based on the implementation by Yossi Rubner, Daniel@0: % wrapped for Matlab by Elias Pampalk. Daniel@0: Daniel@0: if not(isa(x,'mirdata')) Daniel@0: x = miraudio(x); Daniel@0: end Daniel@0: if not(isa(y,'mirdata')) Daniel@0: y = miraudio(y); Daniel@0: end Daniel@0: Daniel@0: clx = get(x,'Clusters'); Daniel@0: if isempty(clx{1}) Daniel@0: px = get(x,'PeakPos'); Daniel@0: if not(iscell(px)) || isempty(px{1}) || ... Daniel@0: not(iscell(px{1})) || isempty(px{1}{1}) || not(iscell(px{1}{1})) Daniel@0: if nargin < 3 Daniel@0: dist = 'Cosine'; Daniel@0: end Daniel@0: Daniel@0: d = get(x,'Data'); Daniel@0: dd = d{1}{1}; Daniel@0: if iscell(dd) Daniel@0: dd = dd{1}; Daniel@0: end Daniel@0: if size(dd,2)>1 Daniel@0: if size(dd,1)>1 Daniel@0: error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); Daniel@0: else Daniel@0: dd = dd'; Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: e = get(y,'Data'); Daniel@0: dt = cell(1,length(e)); Daniel@0: for h = 1:length(e) Daniel@0: ee = e{h}{1}; Daniel@0: if iscell(ee) Daniel@0: ee = ee{1}; Daniel@0: end Daniel@0: if size(ee,2)>1 Daniel@0: if size(ee,1)>1 Daniel@0: error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.'); Daniel@0: else Daniel@0: ee = ee'; Daniel@0: end Daniel@0: end Daniel@0: if isempty(ee) Daniel@0: if isempty(dd) Daniel@0: dt{h}{1} = 0; Daniel@0: else Daniel@0: dt{h}{1} = Inf; Daniel@0: end Daniel@0: else Daniel@0: if length(dd)