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