diff core/magnatagatune/MTTTagFeatureGenreBasic.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/MTTTagFeatureGenreBasic.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,218 @@
+classdef MTTTagFeatureGenreBasic < MTTAudioFeature & handle
+    
+ 
+    properties(Constant = true)
+        
+        my_revision = str2double(substr('$Rev: 99 $',  5, -1));
+    end
+       
+    % ---
+    % here come the internal clip properties.
+    % the database is stored as a global variable
+    % ---
+    properties
+        
+       my_params = struct(...
+            ... % ---
+            ... % these are GenreBasic parameters
+            ... % ---
+            'pct_genres', 1, ... % 1/100 percentile genre tags used
+            'empty_genres', 0 ... % allow empty genres to persist
+            );
+    end
+    
+    methods
+        
+        % ---
+        % constructor: pointer to feature in database
+        % ---
+        function feature = MTTTagFeatureGenreBasic(varargin)
+
+            feature = feature@MTTAudioFeature(varargin{:});
+        end
+ 
+        function data = extract(feature, clip)
+        % process tag information and build the tag vector
+            
+            % ---
+            % get total number of tags. 
+            %
+            % NOTE: the highest tag id should match the size of the 
+            % tagdb lexicon
+            % ---
+%             num_tags = clip.my_db.genredb.size();
+            
+            if feature.my_params.pct_genres ~= 0
+                % no tags, f.e. for parameter experiments in
+                % higher level features
+                [tagids, score] = clip.my_db.genredb.annotids_for_owner(clip.id);
+
+                % save lexicon
+                data.lexicon = clip.my_db.genredb.lexicon;
+
+                % save to data structure
+                data.tags.ids = tagids;
+                data.tags.scores = score;
+            end
+            
+            % save info data
+            data.info.type = 'MTTTagFeatureGenreBasic';
+            data.info.owner = clip;
+            data.info.owner_id = clip.id;
+            data.info.creatorrev = feature.my_revision;
+            
+            % save parameters
+            data.info.params = feature.my_params;
+            
+            data.final.vector = [];
+            data.final.vector_info = struct(); 
+            data.final.dim = 0;
+        end
+        
+        
+        % ---
+        % NOTE: the following transforms are just stated fro 
+        % future use by now 
+        % ---
+        function define_global_transform(features)
+            % ---
+            % compute the relevant tags, and save
+            % them in the commom place
+            % ---
+            
+            % compute extreme cases
+            if features(1).my_params.pct_genres == 1 && features(1).my_params.empty_genres
+                % all tags allowed
+                
+                common.rel_dimensions.tags.ids = 1:numel(features(1).data.lexicon);
+                common.rel_dimensions.tags.id_pos = 1:numel(features(1).data.lexicon);
+                
+                % set common feature values
+                features(1).my_db.set_common(common);
+                return;
+                
+            elseif features(1).my_params.pct_genres == 0 
+                % no tags, f.e. for parameter experiments in
+                % higher level features
+                
+                common.rel_dimensions.tags.ids = [];
+                common.rel_dimensions.tags.id_pos = [];
+                
+                % set common feature values
+                features(1).my_db.set_common(common);
+                return;
+            end
+            
+            
+            allids = sparse(numel(features), numel(features(1).data.lexicon));
+            for i = 1:numel(features)
+                
+                allids(i,features(i).data.tags.ids) = ...
+                    allids(i,features(i).data.tags.ids) + features(i).data.tags.scores;
+            end
+            
+            % ---
+            % get usage of tags and filter not-used tags
+            % ---
+            tagsum = sum(allids, 1);
+            nonzero = tagsum > 0;
+            
+            % ---
+            % NOTE: We remove the empty genres, then
+            % sort by weight / number of appearance and cut off
+            ids = find(nonzero);
+            [null, idx] = sort(tagsum(ids),'descend');
+            ids = ids(idx);
+            
+            % cutoff
+            num_tags = ceil( features(1).my_params.pct_genres * numel(ids));
+            valid_ids = ids(1:min(end, num_tags));
+            
+            % ---
+            % NOTE: make sure that the positions for the tags
+            % stay correctly assigned / consistent
+            % ---
+            id_pos = sparse(size(valid_ids));
+            id_pos(valid_ids) = 1:num_tags; 
+            
+            % save to common data structure
+            common.rel_dimensions.tags.ids = valid_ids;
+            common.rel_dimensions.tags.id_pos = id_pos;
+     
+            % set common feature values
+            features(1).my_db.set_common(common);
+        end
+        
+        function finalise(features)
+          
+            for i = 1:numel(features)
+                
+                 % check for neccesary parameters
+                if isempty(features(i).my_db.commondb)
+
+                    error('Define the global transformation first')
+                    return;
+                end
+                
+                if features(i).my_params.pct_genres == 0
+                    vector_info.labels = {};
+
+                    % save into feature struct
+                    features(i).data.final.dim = 0;
+                    features(i).data.final.vector = [];
+                    features(i).data.final.vector_info = vector_info;
+                    return;
+                end
+                % get valid tag ids
+                valid_ids = features(i).common.rel_dimensions.tags.ids;
+                num_tags = numel(valid_ids);
+                
+                % ---
+                % get vector positions for contined ids,
+                % and sort out the non_allowed id's
+                % ---
+                id_pos = features(i).common.rel_dimensions.tags.id_pos;
+                
+                [has_ids, has_pos] = intersect(features(i).data.tags.ids, valid_ids);
+                
+                score = features(i).data.tags.scores;
+                
+                % create feature vector
+                vector = zeros(num_tags,1);     
+                vector(id_pos(has_ids)) = score(has_pos);
+                
+                % ---
+                % NOTE: this labelling costs to much space
+                % ---
+                vector_info.labels = features(i).data.lexicon(valid_ids);
+
+                % save into feature struct
+                features(i).data.final.dim = num_tags;
+                features(i).data.final.vector = vector;
+                features(i).data.final.vector_info = vector_info;
+            end
+        end
+        
+        function [a1] = visualise(feature)
+            
+            % get tag descriptions form first clip
+            tags = MTTClip(feature(1).owner_id()).my_db.genres;
+            
+            % works for multiple feature instances
+             for i = 1:numel(feature)
+                  
+                clip = MTTClip(feature(i).owner_id());
+                
+                % plot feature data
+                h = bar(feature(i).data.final.vector);
+                a1 = gca;
+                
+                set(a1,'XTick', 1:feature(i).data.final.dim,...
+                    'XTickLabel', tags);
+                title(sprintf('clip %d: %s by %s, genres', ...
+                    clip.id, clip.title(),clip.artist()));
+             end
+        end
+
+    end
+end
\ No newline at end of file