Mercurial > hg > camir-aes2014
comparison core/magnatagatune/MTTMixedFeatureStober11.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 classdef MTTMixedFeatureStober11 < MTTAudioFeature & handle | |
2 % --- | |
3 % This Class contains | |
4 % features are extracted | |
5 % as described in Slaney 08 - LEARNING A METRIC FOR MUSIC SIMILARITY | |
6 % | |
7 % The usual workflow for these features constist of three steps | |
8 % 1. extract: extracts the basic single-file dependent features | |
9 % 2. define_global_transform: calculates the global feature | |
10 % transformation parameters | |
11 % 3. finalise: applies the common transformations to a specific feature | |
12 % --- | |
13 | |
14 properties(Constant = true) | |
15 | |
16 % svn hook | |
17 my_revision = str2double(substr('$Rev$', 5, -1)); | |
18 end | |
19 | |
20 properties | |
21 % --- | |
22 % Set default parameters | |
23 % --- | |
24 my_params = struct(... | |
25 'stob_lowaudio', 1, ... | |
26 'stob_highaudio', 1, ... % | |
27 'stob_tags', 1, ... % | |
28 'stob_norm', 1 ... | |
29 ); | |
30 end | |
31 | |
32 % --- | |
33 % member functions | |
34 % --- | |
35 methods | |
36 | |
37 % --- | |
38 % constructor: pointer to feature in database | |
39 % --- | |
40 function feature = MTTMixedFeatureStober11(varargin) | |
41 | |
42 feature = feature@MTTAudioFeature(varargin{:}); | |
43 | |
44 end | |
45 % --- | |
46 % extract feature data from raw audio features | |
47 % --- | |
48 function data = extract(feature, clip) | |
49 % --- | |
50 % get features. this includes possible | |
51 % local normalisations | |
52 % --- | |
53 | |
54 global globalvars; | |
55 global stobbase; | |
56 | |
57 if isempty(stobbase); | |
58 stobbase = load('features_stober'); | |
59 end | |
60 | |
61 % --- | |
62 % NOTE: we define feature sets which are included / | |
63 % excluded according to the specified parameters | |
64 % --- | |
65 | |
66 lowAudio = {'pitchMean', 'pitchSdev', 'timbreMean', 'timbreSdev'}; | |
67 | |
68 % highAudio features more or less correspond to slaney 08 features | |
69 hiAudio = {'energy','key','loudness','timeSignature',... | |
70 'danceability', 'mode', 'tempo'}; | |
71 | |
72 metadat = {'tags'}; | |
73 | |
74 allowedFeat = {}; | |
75 | |
76 % Select the features to keep | |
77 if feature(1).my_params.stob_lowaudio | |
78 allowedFeat = {allowedFeat{:}, lowAudio{:}}; | |
79 end | |
80 if feature(1).my_params.stob_highaudio | |
81 allowedFeat = {allowedFeat{:}, hiAudio{:}}; | |
82 end | |
83 if feature(1).my_params.stob_tags | |
84 allowedFeat = {allowedFeat{:}, metadat{:}}; | |
85 end | |
86 | |
87 % get the actual clip id | |
88 idx = find(stobbase.clipIds == clip.id); | |
89 | |
90 % --- | |
91 % NOTE: we just copy everything in a big matrix and then | |
92 % normalise the data later | |
93 % --- | |
94 data.vector_info = {}; | |
95 data.stobraw = []; | |
96 fields = fieldnames(stobbase); | |
97 for i = 1:numel(fields) | |
98 | |
99 % skip clip ID field | |
100 if strcmp(fields{i},'clipIds'); | |
101 continue; | |
102 end | |
103 | |
104 % skip unwanted features | |
105 if isempty(strcellfind(allowedFeat, fields{i})) | |
106 continue; | |
107 end | |
108 | |
109 % --- | |
110 % TODO: special case for tag features, including | |
111 % the tag names | |
112 % --- | |
113 | |
114 % put field info into right position | |
115 data.vector_info{numel(data.stobraw)+1} = fields{i}; | |
116 | |
117 % add data to feature | |
118 if size(stobbase.(fields{i}),1) == 1 | |
119 data.stobraw(end+1) = stobbase.(fields{i})(idx); | |
120 else | |
121 % concatenate vector | |
122 tmpdat = stobbase.(fields{i})(idx,:); | |
123 data.stobraw(end+1:end+numel(tmpdat)) = tmpdat; | |
124 end | |
125 end | |
126 % padd further info struct | |
127 data.vector_info(end+1:numel(data.stobraw)) =... | |
128 cell(numel(data.stobraw) - numel(data.vector_info) , 1); | |
129 | |
130 % --- | |
131 % prepare field for final features | |
132 % --- | |
133 data.final.vector = []; | |
134 data.final.vector_info = struct(); | |
135 data.final.dim = 0; | |
136 | |
137 % save info data | |
138 data.info.type = 'MTTMixedFeatureStober11'; | |
139 data.info.owner_id = clip.id; | |
140 data.info.creatorrev = feature.my_revision; | |
141 | |
142 % save parameters | |
143 data.info.params = feature.my_params; | |
144 end | |
145 | |
146 function define_global_transform(features) | |
147 % calculate and set normalization factors from the group of | |
148 % input features. These features will be set for the full database | |
149 | |
150 final = zeros(numel(features(1).data.stobraw), numel(features)); | |
151 for i = 1:numel(features) | |
152 if ~isempty(features(i).data.stobraw) | |
153 final(:,i) = features(i).data.stobraw'; | |
154 end | |
155 end | |
156 | |
157 if features(1).my_params.stob_norm | |
158 if numel(features) == 1 | |
159 error ('Insert feature array for this method, or set normalisation to 0'); | |
160 end | |
161 | |
162 % --- | |
163 % here, we only need to define the post-normalisation | |
164 % --- | |
165 [final, pstd] = mapminmax(final,0,1); | |
166 common.stobstats.post_norm = pstd; | |
167 | |
168 % --- | |
169 % NOTE: whitening as in slaney?? | |
170 % Would make reading the | |
171 % mahal matrices really hard | |
172 % --- | |
173 | |
174 features(1).my_db.set_common(common); | |
175 | |
176 else | |
177 | |
178 features(1).my_db.set_common([1]); | |
179 end | |
180 | |
181 % save the normalised features straight away! | |
182 features.finalise(final); | |
183 end | |
184 | |
185 | |
186 function finalise(features, final) | |
187 % applies a final transformation and | |
188 % collects the information of this feature within a single vector | |
189 % see info for types in specific dimensions | |
190 % check if features have been finalised already | |
191 | |
192 % --- | |
193 % set feature labelling | |
194 % --- | |
195 | |
196 info = {}; | |
197 | |
198 % --- | |
199 % construct resulting feature vector out of features | |
200 % --- | |
201 if nargin == 2 && isempty(final) | |
202 | |
203 % the final vector etc already are set to zero; | |
204 return; | |
205 | |
206 elseif nargin == 2 && (numel(features) == size(final, 2)) | |
207 % the features have already been preassembled | |
208 | |
209 for i = 1:numel(features) | |
210 | |
211 % check for neccesary parameters | |
212 if isempty(features(i).my_db.commondb) | |
213 | |
214 error('Define the global transformation first') | |
215 return; | |
216 end | |
217 | |
218 features(i).data.final.vector = final(:,i); | |
219 features(i).data.final.dim = size(final,1); | |
220 | |
221 % fill up info struct and append to feature | |
222 features(i).data.final.vector_info.labels = ... | |
223 features(i).data.vector_info; | |
224 end | |
225 else | |
226 % --- | |
227 % if features have been added after gettin gnormalisation | |
228 % parameters, ther should be still an option to include | |
229 % them | |
230 % --- | |
231 | |
232 for i = 1:numel(features) | |
233 | |
234 % check for neccesary parameters | |
235 if isempty(features(i).my_db.commondb) | |
236 | |
237 error('Define the global transformation first') | |
238 return; | |
239 end | |
240 | |
241 final = features(i).data.stobraw'; | |
242 | |
243 if features(1).my_params.stob_norm == 1 | |
244 | |
245 [final] = mapminmax('apply', final, features(1).common.stobstats.post_norm); | |
246 end | |
247 | |
248 features(i).data.final.vector = final; | |
249 features(i).data.final.dim = size(final,1); | |
250 | |
251 % fill up info struct and append to feature | |
252 features(i).data.final.vector_info.labels = ... | |
253 features(i).data.vector_info; | |
254 end | |
255 | |
256 end | |
257 | |
258 % --- | |
259 % TODO: Maybe delete more basic features again at this point? | |
260 % --- | |
261 end | |
262 | |
263 % --- | |
264 % destructor: do we really want to remove this | |
265 % from the database? No, but | |
266 % TODO: create marker for unused objects in db, and a cleanup | |
267 % function | |
268 % --- | |
269 function delete(feature) | |
270 | |
271 end | |
272 end | |
273 end |