comparison core/magnatagatune/MTTAudioFeature.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 % ---
2 % Mother of allMTT Audio Features
3 % ---
4
5 classdef MTTAudioFeature < handle
6
7 % common properties
8 properties (Dependent)
9
10 data;
11 end
12
13 properties (Hidden)
14
15 % ---
16 % TODO: get clip features by id and not by pos
17 % ---
18
19 % position in db
20 db_pos;
21 end
22
23 % do not save whole db into mat file
24 properties (Hidden, Transient)
25
26 % database
27 my_db;
28 end
29
30
31 % common methods
32 methods
33
34 % ---
35 % constructor: pointer to feature in database
36 % ---
37 function feature = MTTAudioFeature(db, varargin)
38 % feature = MTTAudioFeatureBasicSm(db, varargin)
39
40 if nargin >= 1
41 % save database handle;
42 feature.my_db = db;
43
44 if nargin >= 2
45 if isnumeric(varargin{1})
46
47 feature.db_pos = varargin{1};
48
49 % ---
50 % read parameters from data, which should not be
51 % overwritten by the manual imputs ?
52 % ---
53 feature.set_params(feature.data.info.params);
54
55 if numel(varargin) > 1
56 warning('Specified parameters cant be applied with preexisting data');
57 end
58
59 else
60
61 % set parameters for feature extraction
62 feature.set_params(varargin{:});
63 end
64 end
65
66 else
67 % ---
68 % TODO: empty constructor
69 % ---
70 end
71 end
72
73 % ---
74 % get and set methods, as the lazy matlab referencing
75 % is of no use when the feature has to be adjusted
76 % during the progess of finalising
77 % ---
78 function data = get.data(feature)
79
80 data = feature.my_db.featuredb(feature.db_pos);
81 end
82
83 function set.data(feature, data)
84
85 feature.my_db.featuredb(feature.db_pos) = data;
86 end
87
88 function id = owner_id(feature)
89 % returns associated clip(s)
90
91 for i = 1:numel(feature)
92 id(i) = feature(i).data.info.owner_id;
93 end
94 end
95
96 function out = dim(feature)
97 % returns dimension of single feature vector
98
99 out = feature(1).data.final.dim;
100 end
101
102 function label = labels(features)
103 label = [];
104 if isfield(features(1).data.final, 'vector_info')
105
106 % ---
107 % TODO: these labels should be stored at a central point,
108 % as this is a big waste of memory
109 % ---
110 label = features(1).data.final.vector_info.labels;
111 end
112 end
113
114 function out = vector(features)
115 % returns the feature vector(s)
116 % if multiple features are input, the vectors are
117 % concatenated to a single matrix of size
118 % (feature.dim x numel(features)
119
120 % finalise features if not done yet
121 if ~isfield(features(1).data, 'final') || features(1).data.final.dim == 0
122
123 features.finalise();
124 end
125
126 %shortcut for empty features
127 if features(1).data.final.dim < 1
128 out =[];
129 return
130 end
131
132 out = zeros(features(1).data.final.dim, numel(features));
133 for i = 1:numel(features)
134
135 % finalise single feature vectors
136 if ~isfield(features(i).data, 'final') || features(i).data.final.dim == 0
137
138 features(i).finalise();
139 end
140
141 out(:,i) = features(i).data.final.vector;
142 end
143 end
144
145 function out = common(feature)
146 % returns common feature values and params
147
148 out = feature(1).my_db.commondb;
149 end
150
151 % visualises all the finalised feature vectors at once
152 function a1 = visualise_vectors(features)
153
154 % Collect source description data
155 ids = zeros( numel( features, 1));
156
157 for i = 1: numel(features)
158
159 ids(i) = features(i).owner_id();
160 end
161 % clips = MTTClip(ids);
162
163 % get collective feature data
164 vec = features.vector();
165
166 % feature description data
167 labels = features(1).labels;
168
169 % plot data
170 h = figure;
171 imagesc(vec);
172 a1 = gca();
173 axis xy;
174
175 set(a1,'XTick',1:numel(features), 'XTickLabel', ids);
176
177 if ~isempty(labels)
178 set(a1,'YTick', [1:features(1).data.final.dim], 'YTickLabel', labels);
179 end
180
181 xlabel('Clip ID');
182 end
183
184
185 % ---
186 % compares the params of the feature with the
187 % provided param struct or feature
188 % ---
189 function out = eq_params(this, in)
190 % function out = eq_params(this, in)
191 %
192 % resolves if a feature with params(in) would be
193 % the same as the given feature
194
195 type = this.my_db.featuredb_type;
196
197 % ---
198 % construct dummy feature to get the params parsing right
199 % ---
200 if isstruct(in)
201
202 % call constructor for this feature
203 % type without valid db
204 in = feval(type, 0, in);
205 end
206
207 % return whether the strings are equal or not
208 out = strcmp(this.param_hash(), in.param_hash());
209 end
210
211 function unused = set_params(this, varargin)
212 % copies the parameters within the struct to the featrue instance,
213 % or
214 % uses the process_options function to set the parameters.
215 % this is used for initialisation / constructor of features
216
217 unused = {};
218 if numel(this) > 1
219
220 for i = 1:numel(this)
221 set_params(this(i), varargin{:});
222 end
223 else
224
225 if isstruct(varargin{1})
226
227 % ok, just copy the information
228 % this.my_params = varargin{1};
229
230 % ---
231 % NOTE: this is a compability script
232 % set fields succesively to keep new / nonset field names
233 % we do not add parameters!!
234 % ---
235 fields = fieldnames(varargin{1});
236 for i = 1:numel(fields)
237
238 % test whether the parameter is supported
239 if isfield(this.my_params, fields{i})
240
241 this.my_params.(fields{i}) = varargin{1}.(fields{i});
242 end
243 end
244 else
245
246 % get all parameter lines
247 fields = fieldnames(this.my_params);
248
249 outputstring = '';
250 inputstring = '';
251
252 % we collect the string for all the fields
253 for i = 1:numel(fields)
254
255 % generate left- hand side of param collection
256 outputstring = sprintf('%s this.my_params.%s',...
257 outputstring, fields{i});
258
259 % right-hand-side
260 inputstring = sprintf('%s ''%s'', this.my_params.%s',...
261 inputstring, fields{i}, fields{i});
262
263 if i < numel(fields)
264
265 % put comma behind last argument
266 inputstring = sprintf('%s,',inputstring);
267 outputstring = sprintf('%s,',outputstring);
268 end
269
270 end
271
272 % evaluate set
273 eval(sprintf('[%s, unused] = process_options(varargin, %s);', ...
274 outputstring, inputstring));
275 end
276 end
277 end %fun
278
279 % ---
280 % saveto function
281 % ---
282 function saveto(features, matfile)
283 % saves (multiple features to a .mat file)
284
285 % get clip ids
286 c = zeros(numel(features), 1);
287 for i = 1:numel(features)
288 c(i) = features(i).owner_id();
289 end
290
291 % build clips
292 clips = MTTClip(c);
293
294 % let db export the corresponding clips
295 features(1).my_db.export(matfile, clips);
296 end
297
298 % ---
299 % destructor: do we really want to remove this
300 % from the database? No, but
301 % TODO: create marker for unused objects in db, and a cleanup
302 % function
303 % ---
304 function delete(feature)
305
306 end
307 end
308
309 methods (Hidden = true)
310
311 function assign(feature, db_pos)
312 % sets the feature data link
313
314 feature.db_pos = db_pos;
315 end
316 end
317
318 methods (Static)
319
320 function ph = param_hash(type, varargin)
321 % loads the params for a feature type and adds the
322 % given parameter values to it.
323
324 % this function can be static or dynamic
325 if nargin > 1
326 % static case
327 dummy = feval(type,[], varargin{:});
328 else
329 % dynamic case
330 dummy = type;
331 end
332 ph = hash(xml_format(dummy.my_params),'MD5');
333 end
334
335 function params = inherited_params(type, varargin)
336 % loads the params for a feature type and adds the
337 % given parameter values to it.
338
339 dummy = feval(type);
340
341 params = dummy.my_params;
342
343 % basic check if the input is correct
344 if mod(numel(varargin), 2) ~= 0
345 error('number of params does not match number of values');
346 end
347
348 % add the fields to the struct
349 for i = 1:2:(numel(varargin)-1);
350
351 params.(varargin{i}) = varargin{i+1};
352 end
353 end
354 end
355 end
356
357
358
359
360
361
362