wolffd@0
|
1 % ---
|
wolffd@0
|
2 % The DistMeasureMahal class states a wrapper for
|
wolffd@0
|
3 % special Mahalanobis similarity distance, and is compatible with the
|
wolffd@0
|
4 % DistMeasure class
|
wolffd@0
|
5 % ---
|
wolffd@0
|
6 classdef DistMeasureNNet < handle
|
wolffd@0
|
7
|
wolffd@0
|
8 properties (SetAccess = private)
|
wolffd@0
|
9
|
wolffd@0
|
10 net;
|
wolffd@0
|
11
|
wolffd@0
|
12 featX;
|
wolffd@0
|
13
|
wolffd@0
|
14 ids;
|
wolffd@0
|
15 ret_ids;
|
wolffd@0
|
16 end
|
wolffd@0
|
17
|
wolffd@0
|
18 methods
|
wolffd@0
|
19
|
wolffd@0
|
20 % ---
|
wolffd@0
|
21 % constructor
|
wolffd@0
|
22 % ---
|
wolffd@0
|
23 function m = DistMeasureNNet(clips, net, featX)
|
wolffd@0
|
24
|
wolffd@0
|
25 if size(featX, 2) ~= numel(clips)
|
wolffd@0
|
26 error 'wrong input format'
|
wolffd@0
|
27 end
|
wolffd@0
|
28
|
wolffd@0
|
29 % fill index and generate matrix;
|
wolffd@0
|
30 m.ids = [clips.id];
|
wolffd@0
|
31
|
wolffd@0
|
32 % reverse index
|
wolffd@0
|
33 m.ret_ids = sparse(numel(m.ids),1);
|
wolffd@0
|
34 m.ret_ids(m.ids) = 1:numel(m.ids);
|
wolffd@0
|
35
|
wolffd@0
|
36 % ---
|
wolffd@0
|
37 % save neural net and lazy-copy features
|
wolffd@0
|
38 % ---
|
wolffd@0
|
39 m.net = net;
|
wolffd@0
|
40
|
wolffd@0
|
41 m.featX = featX;
|
wolffd@0
|
42
|
wolffd@0
|
43 end
|
wolffd@0
|
44
|
wolffd@0
|
45
|
wolffd@0
|
46 % ---
|
wolffd@0
|
47 % this function returns the
|
wolffd@0
|
48 % similarity of two clip indices
|
wolffd@0
|
49 % ---
|
wolffd@0
|
50 function out = mat(m, idxa, idxb)
|
wolffd@0
|
51
|
wolffd@0
|
52 if nargin == 1
|
wolffd@0
|
53 idxa = 1:numel(m.ids);
|
wolffd@0
|
54 idxb = 1:numel(m.ids);
|
wolffd@0
|
55 end
|
wolffd@0
|
56
|
wolffd@0
|
57 % cycle through all index combinations
|
wolffd@0
|
58 out = zeros(numel(idxa), numel(idxb));
|
wolffd@0
|
59 for i = 1:numel(idxa)
|
wolffd@0
|
60 for j = 1:numel(idxb)
|
wolffd@0
|
61
|
wolffd@0
|
62 % calculate distance vector
|
wolffd@0
|
63 deltas = m.featX(:,idxa(i)) - m.featX(:,idxb(j));
|
wolffd@0
|
64
|
wolffd@0
|
65 % return distance from net
|
wolffd@0
|
66 out(i,j) = m.net.calcValue(deltas);
|
wolffd@0
|
67 end
|
wolffd@0
|
68 end
|
wolffd@0
|
69
|
wolffd@0
|
70 end
|
wolffd@0
|
71
|
wolffd@0
|
72 % ---
|
wolffd@0
|
73 % returns the distance for the two input clips
|
wolffd@0
|
74 % ---
|
wolffd@0
|
75 function out = distance(m, clipa, clipb)
|
wolffd@0
|
76 posa = m.get_clip_pos(clipa);
|
wolffd@0
|
77 posb = m.get_clip_pos(clipb);
|
wolffd@0
|
78
|
wolffd@0
|
79 out = m.mat(posa, posb);
|
wolffd@0
|
80 end
|
wolffd@0
|
81
|
wolffd@0
|
82 % ---
|
wolffd@0
|
83 % returns a list of n (default = 10) clips most
|
wolffd@0
|
84 % similar to the input
|
wolffd@0
|
85 % ---
|
wolffd@0
|
86 function [clips, dist] = get_nearest(m, clip, n)
|
wolffd@0
|
87 % list = get_nearest(m, clip, n)
|
wolffd@0
|
88 %
|
wolffd@0
|
89 % returns a list of n (default = 10) clips most
|
wolffd@0
|
90 % similar to the input
|
wolffd@0
|
91
|
wolffd@0
|
92 % default number of results
|
wolffd@0
|
93 if nargin == 2
|
wolffd@0
|
94
|
wolffd@0
|
95 n = 10;
|
wolffd@0
|
96 end
|
wolffd@0
|
97
|
wolffd@0
|
98 % return all clips in case n = 0
|
wolffd@0
|
99 if n == 0; n = numel(m.ids); end
|
wolffd@0
|
100
|
wolffd@0
|
101 % get clip positions
|
wolffd@0
|
102 pos = m.get_clip_pos(clip);
|
wolffd@0
|
103
|
wolffd@0
|
104 % sort according to distance
|
wolffd@0
|
105 [sc, idx] = sort( m.mat(pos, 1:numel(m.ids)), 'ascend');
|
wolffd@0
|
106
|
wolffd@0
|
107 % we only output relevant data
|
wolffd@0
|
108 idx = idx(sc < inf);
|
wolffd@0
|
109
|
wolffd@0
|
110 if numel(idx) > 0
|
wolffd@0
|
111 % create clips form best ids
|
wolffd@0
|
112 clips = MTTClip( m.ids( idx(1:min(n, end))));
|
wolffd@0
|
113 dist = m.mat(pos, idx(1:min(n, end)));
|
wolffd@0
|
114
|
wolffd@0
|
115 else
|
wolffd@0
|
116 clips = [];
|
wolffd@0
|
117 dist = [];
|
wolffd@0
|
118 end
|
wolffd@0
|
119 end
|
wolffd@0
|
120
|
wolffd@0
|
121
|
wolffd@0
|
122
|
wolffd@0
|
123 function [clips, dist] = present_nearest(m, clip, n)
|
wolffd@0
|
124 % plays and shows the n best hits for a given clip
|
wolffd@0
|
125
|
wolffd@0
|
126 % default number of results
|
wolffd@0
|
127 if nargin == 2
|
wolffd@0
|
128
|
wolffd@0
|
129 n = 3;
|
wolffd@0
|
130 end
|
wolffd@0
|
131
|
wolffd@0
|
132 % get best list
|
wolffd@0
|
133 [clips, dist] = get_nearest(m, clip, n);
|
wolffd@0
|
134
|
wolffd@0
|
135 clip.audio_features_basicsm.visualise();
|
wolffd@0
|
136 for i = 1:numel(clips)
|
wolffd@0
|
137 fprintf('\n\n\n- Rank %d, distance: %1.4f \n\n',i, dist(i));
|
wolffd@0
|
138
|
wolffd@0
|
139 clips(i).audio_features_basicsm.visualise();
|
wolffd@0
|
140 h = gcf();
|
wolffd@0
|
141 t = clips(i).play(20);
|
wolffd@0
|
142 pause(t);
|
wolffd@0
|
143 close(h);
|
wolffd@0
|
144 end
|
wolffd@0
|
145 end
|
wolffd@0
|
146
|
wolffd@0
|
147 function a = visualise(m)
|
wolffd@0
|
148
|
wolffd@0
|
149 figure;
|
wolffd@0
|
150
|
wolffd@0
|
151 % plot data
|
wolffd@0
|
152
|
wolffd@0
|
153 imagesc(m.mat);
|
wolffd@0
|
154
|
wolffd@0
|
155 a = gca;
|
wolffd@0
|
156 set(a,'YTick',[1:numel(m.ids)], 'YTickLabel',m.ids);
|
wolffd@0
|
157 set(a,'XTick',[1:numel(m.ids)], 'XTickLabel', m.ids);
|
wolffd@0
|
158
|
wolffd@0
|
159 axis xy;
|
wolffd@0
|
160 colormap(hot);
|
wolffd@0
|
161 end
|
wolffd@0
|
162
|
wolffd@0
|
163 % end methods
|
wolffd@0
|
164 end
|
wolffd@0
|
165
|
wolffd@0
|
166 % ---
|
wolffd@0
|
167 % private methods
|
wolffd@0
|
168 % ---
|
wolffd@0
|
169 methods(Access = private)
|
wolffd@0
|
170
|
wolffd@0
|
171 function out = get_clip_pos(m, clip)
|
wolffd@0
|
172 % returns position in mat for given clip
|
wolffd@0
|
173
|
wolffd@0
|
174 out = m.ret_ids(clip.id);
|
wolffd@0
|
175 end
|
wolffd@0
|
176
|
wolffd@0
|
177 end
|
wolffd@0
|
178
|
wolffd@0
|
179 end |