Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/magnatagatune/MTTAudioFeature.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,362 @@ +% --- +% Mother of allMTT Audio Features +% --- + +classdef MTTAudioFeature < handle + + % common properties + properties (Dependent) + + data; + end + + properties (Hidden) + + % --- + % TODO: get clip features by id and not by pos + % --- + + % position in db + db_pos; + end + + % do not save whole db into mat file + properties (Hidden, Transient) + + % database + my_db; + end + + + % common methods + methods + + % --- + % constructor: pointer to feature in database + % --- + function feature = MTTAudioFeature(db, varargin) + % feature = MTTAudioFeatureBasicSm(db, varargin) + + if nargin >= 1 + % save database handle; + feature.my_db = db; + + if nargin >= 2 + if isnumeric(varargin{1}) + + feature.db_pos = varargin{1}; + + % --- + % read parameters from data, which should not be + % overwritten by the manual imputs ? + % --- + feature.set_params(feature.data.info.params); + + if numel(varargin) > 1 + warning('Specified parameters cant be applied with preexisting data'); + end + + else + + % set parameters for feature extraction + feature.set_params(varargin{:}); + end + end + + else + % --- + % TODO: empty constructor + % --- + end + end + + % --- + % get and set methods, as the lazy matlab referencing + % is of no use when the feature has to be adjusted + % during the progess of finalising + % --- + function data = get.data(feature) + + data = feature.my_db.featuredb(feature.db_pos); + end + + function set.data(feature, data) + + feature.my_db.featuredb(feature.db_pos) = data; + end + + function id = owner_id(feature) + % returns associated clip(s) + + for i = 1:numel(feature) + id(i) = feature(i).data.info.owner_id; + end + end + + function out = dim(feature) + % returns dimension of single feature vector + + out = feature(1).data.final.dim; + end + + function label = labels(features) + label = []; + if isfield(features(1).data.final, 'vector_info') + + % --- + % TODO: these labels should be stored at a central point, + % as this is a big waste of memory + % --- + label = features(1).data.final.vector_info.labels; + end + end + + function out = vector(features) + % returns the feature vector(s) + % if multiple features are input, the vectors are + % concatenated to a single matrix of size + % (feature.dim x numel(features) + + % finalise features if not done yet + if ~isfield(features(1).data, 'final') || features(1).data.final.dim == 0 + + features.finalise(); + end + + %shortcut for empty features + if features(1).data.final.dim < 1 + out =[]; + return + end + + out = zeros(features(1).data.final.dim, numel(features)); + for i = 1:numel(features) + + % finalise single feature vectors + if ~isfield(features(i).data, 'final') || features(i).data.final.dim == 0 + + features(i).finalise(); + end + + out(:,i) = features(i).data.final.vector; + end + end + + function out = common(feature) + % returns common feature values and params + + out = feature(1).my_db.commondb; + end + + % visualises all the finalised feature vectors at once + function a1 = visualise_vectors(features) + + % Collect source description data + ids = zeros( numel( features, 1)); + + for i = 1: numel(features) + + ids(i) = features(i).owner_id(); + end +% clips = MTTClip(ids); + + % get collective feature data + vec = features.vector(); + + % feature description data + labels = features(1).labels; + + % plot data + h = figure; + imagesc(vec); + a1 = gca(); + axis xy; + + set(a1,'XTick',1:numel(features), 'XTickLabel', ids); + + if ~isempty(labels) + set(a1,'YTick', [1:features(1).data.final.dim], 'YTickLabel', labels); + end + + xlabel('Clip ID'); + end + + + % --- + % compares the params of the feature with the + % provided param struct or feature + % --- + function out = eq_params(this, in) + % function out = eq_params(this, in) + % + % resolves if a feature with params(in) would be + % the same as the given feature + + type = this.my_db.featuredb_type; + + % --- + % construct dummy feature to get the params parsing right + % --- + if isstruct(in) + + % call constructor for this feature + % type without valid db + in = feval(type, 0, in); + end + + % return whether the strings are equal or not + out = strcmp(this.param_hash(), in.param_hash()); + end + + function unused = set_params(this, varargin) + % copies the parameters within the struct to the featrue instance, + % or + % uses the process_options function to set the parameters. + % this is used for initialisation / constructor of features + + unused = {}; + if numel(this) > 1 + + for i = 1:numel(this) + set_params(this(i), varargin{:}); + end + else + + if isstruct(varargin{1}) + + % ok, just copy the information + % this.my_params = varargin{1}; + + % --- + % NOTE: this is a compability script + % set fields succesively to keep new / nonset field names + % we do not add parameters!! + % --- + fields = fieldnames(varargin{1}); + for i = 1:numel(fields) + + % test whether the parameter is supported + if isfield(this.my_params, fields{i}) + + this.my_params.(fields{i}) = varargin{1}.(fields{i}); + end + end + else + + % get all parameter lines + fields = fieldnames(this.my_params); + + outputstring = ''; + inputstring = ''; + + % we collect the string for all the fields + for i = 1:numel(fields) + + % generate left- hand side of param collection + outputstring = sprintf('%s this.my_params.%s',... + outputstring, fields{i}); + + % right-hand-side + inputstring = sprintf('%s ''%s'', this.my_params.%s',... + inputstring, fields{i}, fields{i}); + + if i < numel(fields) + + % put comma behind last argument + inputstring = sprintf('%s,',inputstring); + outputstring = sprintf('%s,',outputstring); + end + + end + + % evaluate set + eval(sprintf('[%s, unused] = process_options(varargin, %s);', ... + outputstring, inputstring)); + end + end + end %fun + + % --- + % saveto function + % --- + function saveto(features, matfile) + % saves (multiple features to a .mat file) + + % get clip ids + c = zeros(numel(features), 1); + for i = 1:numel(features) + c(i) = features(i).owner_id(); + end + + % build clips + clips = MTTClip(c); + + % let db export the corresponding clips + features(1).my_db.export(matfile, clips); + end + + % --- + % destructor: do we really want to remove this + % from the database? No, but + % TODO: create marker for unused objects in db, and a cleanup + % function + % --- + function delete(feature) + + end + end + + methods (Hidden = true) + + function assign(feature, db_pos) + % sets the feature data link + + feature.db_pos = db_pos; + end + end + + methods (Static) + + function ph = param_hash(type, varargin) + % loads the params for a feature type and adds the + % given parameter values to it. + + % this function can be static or dynamic + if nargin > 1 + % static case + dummy = feval(type,[], varargin{:}); + else + % dynamic case + dummy = type; + end + ph = hash(xml_format(dummy.my_params),'MD5'); + end + + function params = inherited_params(type, varargin) + % loads the params for a feature type and adds the + % given parameter values to it. + + dummy = feval(type); + + params = dummy.my_params; + + % basic check if the input is correct + if mod(numel(varargin), 2) ~= 0 + error('number of params does not match number of values'); + end + + % add the fields to the struct + for i = 1:2:(numel(varargin)-1); + + params.(varargin{i}) = varargin{i+1}; + end + end + end +end + + + + + + + \ No newline at end of file