Mercurial > hg > camir-aes2014
view core/magnatagatune/MTTAudioFeatureDBgen.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 source
classdef MTTAudioFeatureDBgen < handle % --- % the database is stored as a global variable % --- properties (Hidden) % feature databases featuredb; commondb; feature_type; feature_params; % unfortunately we just can have one clip type at a time clip_type; end properties (Hidden) % --- % We use a "db_magnaaudiofeat_xxx" class pointer for all the loaded features, % which is supposed to work like a cache. % my_dbpos links to the position of this feature in the db. % --- % database hash featuredb_hash; end % --- % member functions % --- methods % constructor function db = MTTAudioFeatureDBgen(type, matfile) if nargin >= 1 % --- % we test for correct type by % using an call to the empty arg constructor function % --- try feval(type); catch err fprintf('%s\n', err.message); error('The specified class does not provide an constructor') end db.feature_type = type; if nargin >=2 && ~isempty(dir(matfile)) % import database if filename given db.import(matfile); end end % try to load a standard db from mat file? end % --- % database retrieval. % this should return a handle to a feature class pointing in this % global feature database. % % parameters can be passed via the varargin parameter % --- function features = get_features(db, clip, varargin) % --- % TODO: error checking and processing % --- % --- % prepare for multiple clips % --- if numel(clip) > 1 % iterate for all the found clips features = feval(db.feature_type); for i = 1:numel(clip) features(i) = get_features(db, clip(i), varargin{:}); end else % --- % single feature extraction % --- pos = db.get_clip_pos(clip); if ~pos % assign new database position pos = db.get_next_pos(); % call feature constructor features = feval(db.feature_type, db, varargin{:}); % extract / load feature data cprint(2 ,'Extracting %s for clip %d \n', db.feature_type, clip.id()); if isempty( db.featuredb) db.featuredb = features.extract(clip); else db.featuredb(pos) = features.extract(clip); end % --- % NOTE: % IF WE ARE SURE THAT EVERYTHING HAS WORKED OUT FINE: % assign new database position in cache % --- db.set_pos(pos, clip); % --- % NOTE: feature objects are directly linked to DB % positions % --- features.assign(pos); else % just return the cached link features = feval(db.feature_type, db, pos); end % --- % finalise features if possible (commondb not empty) % --- if ~isempty(db.commondb) && isempty(features.data.final) && ... ismethod(features,'finalise') % call finalise features.finalise(); end % set clip type of the db db.clip_type = class(clip(1)); % get last params db.feature_params = features(1).my_params; end end function set_common(db, common) % sets the common database to input if isempty(db.commondb) cprint(2, 'Setting common feature values\n'); else cprint(1, 'Common feature values changed'); end db.commondb = common; end function export(db, matfile, clips) % saves featuredb to matlab data file global globalvars; % save revision for later version and compability control info.creatorrev = globalvars.camir.revision; cprint(2, 'Exporting %s database to %s ...\n', db.feature_type, matfile); if nargin == 3 % --- % TODO: create new hash % --- for i = 1:numel(clips) pos(i) = db.get_clip_pos(clips(i)); if pos(i) == 0 error('Corrupted database'); end end % get specific data set featuredb = db.featuredb(pos); featuredb_hash = db.featuredb_hash(pos); else featuredb = db.featuredb; featuredb_hash = db.featuredb_hash; end commondb = db.commondb; feature_type = db.feature_type; % --- % save clip type as well % NOTE: this only works if all clips have the same type (e.g. % CASIMIRClip or MTTclip % --- clip_type = class(clips(1)); save(matfile, 'featuredb', 'commondb', 'feature_type', 'featuredb_hash', 'clip_type'); end function [features, clips] = import(db, matfile, type) % gets featuredb from matlab data file cprint(2, 'importing features from %s', matfile) load(matfile,'-MAT'); if ~strcmp(feature_type, db.feature_type) error('feature type of db to import does not match'); end % --- % TODO / FIXME: check parameter hash before importing % --- % if db.size() > 0 % % % get a feature param from the db; % last_pos = db.get_last_pos; % dummyparams = db.featuredb(last_pos).info.params; % % % --- % % construct a dummy feature and compare parameters to % % the params in the database % % --- % dummyclip = MTTClip(db.featuredb_hash(last_pos)); % dummyfeat = db.get_features(dummyclip, dummyparams); % % if ~dummybsm.eq_params(fparams(i)) % % db_magnaaudiofeat_basicsm.reset; % end % % end if exist('clip_type','var') clips = feval(clip_type,featuredb_hash); db.clip_type = clip_type; else clips = MTTClip(featuredb_hash); db.clip_type = 'MTTClip'; end % --- % import features individually into db % --- for i = 1:numel(clips) % test if database already contains clip if ~db.get_clip_pos(clips(i)); % get position for this database pos = db.get_next_pos(); % copy values if ~isempty(db.featuredb) db.featuredb(pos) = featuredb(i); elseif pos == 1; db.featuredb = featuredb(i); else error ('Corrupted database'); end % update hash db.set_pos(pos, clips(i)); end end % Set common features db.set_common(commondb); if nargout > 0 % retrieve features; features = get_features(db, clips); end end function [matfile] = load(db, featuretype, fparams, clips) % this is the new implementation of MTTAudiofeature_load % get filename matfile = MTTAudioFeatureDBgen.get_db_filename(featuretype, fparams,clips); % does it exist? if exist(matfile,'file') == 2 import(db, matfile); else matfile= []; end end function [matfile] = save(db) % this is the new implementation of MTTAudiofeature_load % get clips clips = feval(db.clip_type,db.featuredb_hash); % get filename matfile = MTTAudioFeatureDBgen.get_db_filename(db.feature_type, db.feature_params ,clips); % does it exist? if exist(matfile,'file') == 2 warning 'overwriting feature file for this config' end % save params in xml xml_save(sprintf('%s.xml', substr(matfile, 0, -4)),db.feature_params); %export features export(db, matfile, clips); end function remove_features(db, clip) % weakly deletes clip features from db clear_pos(clip); end function delete(db) % --- % probably not anything to do here, as we want to % keep the db! % see static method destroy % --- end function reset(db) % --- % deletes all the cached data and destroys the % global feature database % --- db.commondb = []; db.featuredb = []; db.featuredb_hash = []; end function out = size(db) % returns the number of features saved in this db out = sum(db.featuredb_hash > 0); end function memory(db) % returns size of whole db in bytes % --- % TODO: Make this work % --- fprintf(' \n This db contains feature sets for %d clips\n ',numel(db.featuredb_hash)) % get local copies of data featuredb = db.featuredb; featuredb_hash = db.featuredb_hash; commondb = db.commondb; whos('featuredb', 'featuredb_hash', 'commondb') end end % --- % private functions % --- methods (Hidden) % --- % Hash functions % --- function out = get_clip_pos(db, clip) % should become database hashing function out = find(db.featuredb_hash == clip.id); if isempty(out) out = 0; end end function out = get_next_pos(db) % return index for the new clip features out = numel(db.featuredb_hash) + 1; end function last_pos = get_last_pos(db) % return index the last valid db entry last_pos = find(db.featuredb_hash > 0, 1, 'last'); end function set_pos(db, pos, clip) % set index for the new clip features db.featuredb_hash(pos) = clip.id; end function clear_pos(db, clip) % remove index of the clip features db.featuredb_hash(get_clip_pos(db, clip)) = 0; end end methods (Static) % --- % this resets all feature dbs except the one exluded in the % 'exclude', {''} cell % --- function reset_feature_dbs(varargin) [exclude] = process_options(varargin,'exclude',{}); % --- % resets all feature dbs except raw features % --- vars = whos ('*','global','-regexp', '^db_*'); % --- % check if each is class of DBgen. % if not in exclude variable, reset % --- for i = 1:numel(vars) % import global variable eval(sprintf('global %s',vars(i).name)); if strcmp(eval(sprintf('class(%s)',vars(i).name)), 'MTTAudioFeatureDBgen') ... && isempty(strcellfind(exclude, vars(i).name)) eval(sprintf('%s.reset',vars(i).name)); end end end function feature_type = import_type(matfile) % function feature_type = import_type(matfile) % % returns the type of the saved feature db. load(matfile, 'feature_type', '-MAT'); end function db_nameo = db_name(type) % returns the standard global var name for a db of given type switch type case 'MTTAudioFeatureRAW' db_nameo = 'db_magnaaudiofeat'; case 'MTTAudioFeatureBasicSm' db_nameo = 'db_magnaaudiofeat_basicsm'; case 'MTTTagFeatureGenreBasic' db_nameo = 'db_magnatagfeat_genrebasic'; case 'MTTMixedFeatureGenreBasicSm' db_nameo = 'db_magnamixedfeat_genrebasicsm'; otherwise db_nameo = sprintf('db_%s', type); end end function matfile = get_db_filename(featuretype, fparams,clips) % get the paramhash paramhash = MTTAudioFeatureDBgen.param_hash(featuretype, fparams); % add the clip hash bit cliphash = MTTAudioFeatureDBgen.clip_hash(clips); % determine the filename matfile = sprintf('f%s.%s.mat', paramhash,cliphash); end 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 ch = clip_hash(clips) % returns the hash of a number of clips ch = hash([class(clips(1)) mat2str(sort(clips.id))],'MD5'); end end end