wolffd@0
|
1 function d = mirdist(x,y,dist)
|
wolffd@0
|
2 % d = mirdist(x,y) evaluates the distance between x and y.
|
wolffd@0
|
3 % x is the feature values corresponding to one audio file, and y is the
|
wolffd@0
|
4 % values (for the same feature) corrdponding to one (or several)
|
wolffd@0
|
5 % audio files.
|
wolffd@0
|
6 % If x and y are not decomposed into frames,
|
wolffd@0
|
7 % d = mirdist(x,y,f) specifies distance function.
|
wolffd@0
|
8 % Default value: f = 'Cosine'
|
wolffd@0
|
9 % If x and y are composed of clustered frames (using mircluster), the
|
wolffd@0
|
10 % cluster signatures are compared using Earth Mover Distance.
|
wolffd@0
|
11 % (Logan, Salomon, 2001)
|
wolffd@0
|
12 % If x and y contains peaks, the vectors representing the peak
|
wolffd@0
|
13 % distributions are compared using Euclidean distance.
|
wolffd@0
|
14 % (used with mirnovelty in Jacobson, 2006)
|
wolffd@0
|
15 %
|
wolffd@0
|
16 % The Earth Mover Distance is based on the implementation by Yossi Rubner,
|
wolffd@0
|
17 % wrapped for Matlab by Elias Pampalk.
|
wolffd@0
|
18
|
wolffd@0
|
19 if not(isa(x,'mirdata'))
|
wolffd@0
|
20 x = miraudio(x);
|
wolffd@0
|
21 end
|
wolffd@0
|
22 if not(isa(y,'mirdata'))
|
wolffd@0
|
23 y = miraudio(y);
|
wolffd@0
|
24 end
|
wolffd@0
|
25
|
wolffd@0
|
26 clx = get(x,'Clusters');
|
wolffd@0
|
27 if isempty(clx{1})
|
wolffd@0
|
28 px = get(x,'PeakPos');
|
wolffd@0
|
29 if not(iscell(px)) || isempty(px{1}) || ...
|
wolffd@0
|
30 not(iscell(px{1})) || isempty(px{1}{1}) || not(iscell(px{1}{1}))
|
wolffd@0
|
31 if nargin < 3
|
wolffd@0
|
32 dist = 'Cosine';
|
wolffd@0
|
33 end
|
wolffd@0
|
34
|
wolffd@0
|
35 d = get(x,'Data');
|
wolffd@0
|
36 dd = d{1}{1};
|
wolffd@0
|
37 if iscell(dd)
|
wolffd@0
|
38 dd = dd{1};
|
wolffd@0
|
39 end
|
wolffd@0
|
40 if size(dd,2)>1
|
wolffd@0
|
41 if size(dd,1)>1
|
wolffd@0
|
42 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.');
|
wolffd@0
|
43 else
|
wolffd@0
|
44 dd = dd';
|
wolffd@0
|
45 end
|
wolffd@0
|
46 end
|
wolffd@0
|
47
|
wolffd@0
|
48 e = get(y,'Data');
|
wolffd@0
|
49 dt = cell(1,length(e));
|
wolffd@0
|
50 for h = 1:length(e)
|
wolffd@0
|
51 ee = e{h}{1};
|
wolffd@0
|
52 if iscell(ee)
|
wolffd@0
|
53 ee = ee{1};
|
wolffd@0
|
54 end
|
wolffd@0
|
55 if size(ee,2)>1
|
wolffd@0
|
56 if size(ee,1)>1
|
wolffd@0
|
57 error('ERROR IN MIRDIST: If the input is decomposed into frames, they should first be clustered.');
|
wolffd@0
|
58 else
|
wolffd@0
|
59 ee = ee';
|
wolffd@0
|
60 end
|
wolffd@0
|
61 end
|
wolffd@0
|
62 if isempty(ee)
|
wolffd@0
|
63 if isempty(dd)
|
wolffd@0
|
64 dt{h}{1} = 0;
|
wolffd@0
|
65 else
|
wolffd@0
|
66 dt{h}{1} = Inf;
|
wolffd@0
|
67 end
|
wolffd@0
|
68 else
|
wolffd@0
|
69 if length(dd)<length(ee)
|
wolffd@0
|
70 dd(length(ee)) = 0;
|
wolffd@0
|
71 %ee = ee(1:length(d));
|
wolffd@0
|
72 elseif length(ee)<length(dd)
|
wolffd@0
|
73 ee(length(dd)) = 0;
|
wolffd@0
|
74 %dd = dd(1:length(ee));
|
wolffd@0
|
75 end
|
wolffd@0
|
76 if length(dd) == 1
|
wolffd@0
|
77 dt{h}{1} = abs(dd-ee);
|
wolffd@0
|
78 elseif norm(dd) && norm(ee)
|
wolffd@0
|
79 dt{h}{1} = pdist([dd(:)';ee(:)'],dist);
|
wolffd@0
|
80 else
|
wolffd@0
|
81 dt{h}{1} = NaN;
|
wolffd@0
|
82 end
|
wolffd@0
|
83 end
|
wolffd@0
|
84 end
|
wolffd@0
|
85 else
|
wolffd@0
|
86 % Euclidean distance between vectors to compare data with peaks
|
wolffd@0
|
87 % (used with mirnovelty in Jacobson, 2006).
|
wolffd@0
|
88 sig = pi/4;
|
wolffd@0
|
89 dx = get(x,'Data');
|
wolffd@0
|
90 nx = length(px{1}{1}{1});
|
wolffd@0
|
91 cx = mean(px{1}{1}{1}/length(dx{1}{1}));
|
wolffd@0
|
92 dy = get(y,'Data');
|
wolffd@0
|
93 py = get(y,'PeakPos');
|
wolffd@0
|
94 dt = cell(1,length(py));
|
wolffd@0
|
95 for h = 1:length(py)
|
wolffd@0
|
96 ny = length(py{h}{1}{1});
|
wolffd@0
|
97 cy = mean(py{h}{1}{1}/length(dy{h}{1}));
|
wolffd@0
|
98 dt{h}{1} = sqrt((nx*cos(sig*cx)-ny*cos(sig*cy))^2 ...
|
wolffd@0
|
99 +(nx*sin(sig*cx)-ny*sin(sig*cy))^2);
|
wolffd@0
|
100 end
|
wolffd@0
|
101 end
|
wolffd@0
|
102 else
|
wolffd@0
|
103 % Earth Mover's Distance to compare clustered data.
|
wolffd@0
|
104 cly = get(y,'Clusters');
|
wolffd@0
|
105 dt = cell(1,length(cly));
|
wolffd@0
|
106 for h = 1:length(cly)
|
wolffd@0
|
107 cost = zeros(length(clx{1}.weight),length(cly{h}.weight));
|
wolffd@0
|
108 for i = 1:length(clx{1}.weight)
|
wolffd@0
|
109 for j = 1:length(cly{h}.weight)
|
wolffd@0
|
110 covx = clx{1}.covar(:,i);
|
wolffd@0
|
111 covy = cly{h}.covar(:,j);
|
wolffd@0
|
112 mux = clx{1}.centr(:,i);
|
wolffd@0
|
113 muy = cly{h}.centr(:,j);
|
wolffd@0
|
114 cost(i,j) = sum(covx./covy + covy./covx + ...
|
wolffd@0
|
115 (mux-muy).^2.*(1./covx + 1./covy) - 2);
|
wolffd@0
|
116 end
|
wolffd@0
|
117 end
|
wolffd@0
|
118 dt{h}{1} = emd_wrapper(cost,clx{1}.weight,cly{h}.weight);
|
wolffd@0
|
119 end
|
wolffd@0
|
120 end
|
wolffd@0
|
121 d = mirscalar(y,'Data',dt,'Title',[get(y,'Title'),' Distance'],...
|
wolffd@0
|
122 'Name',get(x,'Name'),'Name2',get(y,'Name')); |