wolffd@0
|
1 % ---
|
wolffd@0
|
2 % This is the class for magnatagatune clips
|
wolffd@0
|
3 % ---
|
wolffd@0
|
4
|
wolffd@0
|
5 classdef Clip < handle
|
wolffd@0
|
6
|
wolffd@0
|
7 % ---
|
wolffd@0
|
8 % here come the internal clip properties.
|
wolffd@0
|
9 % the database is stored as a global variable
|
wolffd@0
|
10 % ---
|
wolffd@0
|
11 properties (SetAccess = private)
|
wolffd@0
|
12
|
wolffd@0
|
13 % magnatagatune clip id
|
wolffd@0
|
14 my_id;
|
wolffd@0
|
15 end
|
wolffd@0
|
16
|
wolffd@0
|
17 % do not save whole db into mat file
|
wolffd@0
|
18 properties (Hidden, Transient)
|
wolffd@0
|
19
|
wolffd@0
|
20 my_db;
|
wolffd@0
|
21 end
|
wolffd@0
|
22
|
wolffd@0
|
23 properties (Hidden)
|
wolffd@0
|
24
|
wolffd@0
|
25 my_dbpos;
|
wolffd@0
|
26 end
|
wolffd@0
|
27
|
wolffd@0
|
28 % ---
|
wolffd@0
|
29 % here come the clip functions.
|
wolffd@0
|
30 % ---
|
wolffd@0
|
31 methods
|
wolffd@0
|
32
|
wolffd@0
|
33 % ---
|
wolffd@0
|
34 % simple constructor
|
wolffd@0
|
35 % ---
|
wolffd@0
|
36 function clip = Clip(varargin)
|
wolffd@0
|
37
|
wolffd@0
|
38 % usual or empty constructor ?
|
wolffd@0
|
39 if (nargin > 0) && isnumeric(varargin{1})
|
wolffd@0
|
40 id = varargin{1};
|
wolffd@0
|
41 db_type = varargin{2};
|
wolffd@0
|
42
|
wolffd@0
|
43 % ---
|
wolffd@0
|
44 % check for magnatagatunedatabase
|
wolffd@0
|
45 % and load it if not present
|
wolffd@0
|
46 % ---
|
wolffd@0
|
47 evalc(sprintf('global %s;',db_type));
|
wolffd@0
|
48 evalc(sprintf('thisdb = %s;',db_type));
|
wolffd@0
|
49
|
wolffd@0
|
50 if ~isempty(thisdb)% exist('clip_info_proper')
|
wolffd@0
|
51 clip.my_db = thisdb;
|
wolffd@0
|
52 else
|
wolffd@0
|
53
|
wolffd@0
|
54 error 'db not found';
|
wolffd@0
|
55 % dbload;
|
wolffd@0
|
56 end
|
wolffd@0
|
57
|
wolffd@0
|
58 % ---
|
wolffd@0
|
59 % recursive call for creating multiple clips
|
wolffd@0
|
60 % ---
|
wolffd@0
|
61 if numel(id) > 1
|
wolffd@0
|
62
|
wolffd@0
|
63 % multi-id case
|
wolffd@0
|
64
|
wolffd@0
|
65 % ---
|
wolffd@0
|
66 % @todo: use class names as db names
|
wolffd@0
|
67 % ---
|
wolffd@0
|
68 if strcmp(db_type,'db_MTTClip')
|
wolffd@0
|
69 clip = MTTClip();
|
wolffd@0
|
70 for i = 1:numel(id)
|
wolffd@0
|
71 clip(i) = MTTClip(id(i));
|
wolffd@0
|
72 end
|
wolffd@0
|
73 elseif strcmp(db_type,'db_MSDClip')
|
wolffd@0
|
74 clip = MSDClip();
|
wolffd@0
|
75 for i = 1:numel(id)
|
wolffd@0
|
76 clip(i) = MSDClip(id(i));
|
wolffd@0
|
77 end
|
wolffd@0
|
78 elseif strcmp(db_type,'db_CASIMIRClip')
|
wolffd@0
|
79 clip = CASIMIRClip();
|
wolffd@0
|
80 for i = 1:numel(id)
|
wolffd@0
|
81 clip(i) = CASIMIRClip(id(i));
|
wolffd@0
|
82 end
|
wolffd@0
|
83 end
|
wolffd@0
|
84
|
wolffd@0
|
85
|
wolffd@0
|
86 elseif ~isempty(id)
|
wolffd@0
|
87 % ---
|
wolffd@0
|
88 % actual constructor
|
wolffd@0
|
89 % ---
|
wolffd@0
|
90 clip.my_id = id;
|
wolffd@0
|
91 clip.my_dbpos = clip.dbpos();
|
wolffd@0
|
92
|
wolffd@0
|
93 if isempty(clip.my_dbpos)
|
wolffd@0
|
94 error ('Clip %d not found in DB', full(id))
|
wolffd@0
|
95 end
|
wolffd@0
|
96 end
|
wolffd@0
|
97 else
|
wolffd@0
|
98
|
wolffd@0
|
99 % ---
|
wolffd@0
|
100 % TODO: deal with empty constructor
|
wolffd@0
|
101 % ---
|
wolffd@0
|
102 end
|
wolffd@0
|
103 end
|
wolffd@0
|
104
|
wolffd@0
|
105 % ---
|
wolffd@0
|
106 % member functions
|
wolffd@0
|
107 % ---
|
wolffd@0
|
108
|
wolffd@0
|
109 % returns the id (function neccessary for
|
wolffd@0
|
110 % multi-clip environments)
|
wolffd@0
|
111 function out = id(this)
|
wolffd@0
|
112
|
wolffd@0
|
113 out = [this.my_id];
|
wolffd@0
|
114 end
|
wolffd@0
|
115
|
wolffd@0
|
116 function out = comparison_id(this)
|
wolffd@0
|
117
|
wolffd@0
|
118 out = [this(1).my_db.comparison_ids(this)];
|
wolffd@0
|
119 end
|
wolffd@0
|
120
|
wolffd@0
|
121 function out = title(this)
|
wolffd@0
|
122 % returns name strings for given genre position ids
|
wolffd@0
|
123
|
wolffd@0
|
124 out = this.my_db.clip_info_proper{this.my_dbpos,3};
|
wolffd@0
|
125 end
|
wolffd@0
|
126
|
wolffd@0
|
127 function out = album(this)
|
wolffd@0
|
128 % returns name strings for given genre position ids
|
wolffd@0
|
129
|
wolffd@0
|
130 out = this.my_db.clip_info_proper{this.my_dbpos,5};
|
wolffd@0
|
131 end
|
wolffd@0
|
132
|
wolffd@0
|
133 function out = artist(this)
|
wolffd@0
|
134 % returns name strings for given genre position ids
|
wolffd@0
|
135
|
wolffd@0
|
136 out = this(1).my_db.artistdb.annots(this.id);
|
wolffd@0
|
137 out = out{1};
|
wolffd@0
|
138 end
|
wolffd@0
|
139
|
wolffd@0
|
140 function out = artist_id(this)
|
wolffd@0
|
141 % returns name strings for given genre position ids
|
wolffd@0
|
142
|
wolffd@0
|
143 out = this(1).my_db.artistdb.annotids_for_owner(this.id);
|
wolffd@0
|
144 end
|
wolffd@0
|
145
|
wolffd@0
|
146 function my_tag_ids = tag_ids(this)
|
wolffd@0
|
147 % returns clip tag posids for given clip id
|
wolffd@0
|
148
|
wolffd@0
|
149 my_tag_ids = this.my_db.tagdb.annotids_for_owner(this.id);
|
wolffd@0
|
150 end
|
wolffd@0
|
151
|
wolffd@0
|
152 function out = tags(this)
|
wolffd@0
|
153 % returns name strings for given genre position ids
|
wolffd@0
|
154
|
wolffd@0
|
155 out = this.my_db.tagdb.annots(this.id);
|
wolffd@0
|
156 end
|
wolffd@0
|
157
|
wolffd@0
|
158
|
wolffd@0
|
159 % this is for ocompability with
|
wolffd@0
|
160 function out = raw_annots(this)
|
wolffd@0
|
161
|
wolffd@0
|
162 out = this.my_db.clip_info_proper(this.my_dbpos,:);
|
wolffd@0
|
163 end
|
wolffd@0
|
164
|
wolffd@0
|
165 function [out] = isrc(this)
|
wolffd@0
|
166 % returns name strings for given genre position ids
|
wolffd@0
|
167 out = this(1).my_db.clip_info_proper{this.my_dbpos,11};
|
wolffd@0
|
168 end
|
wolffd@0
|
169
|
wolffd@0
|
170 function [out] = artist_mbid(this)
|
wolffd@0
|
171 % returns name strings for given genre position ids
|
wolffd@0
|
172 out = this(1).my_db.clip_info_proper{this.my_dbpos,12};
|
wolffd@0
|
173 end
|
wolffd@0
|
174
|
wolffd@0
|
175 function [out] = mbtags(this)
|
wolffd@0
|
176 % returns nmusicbrainz tags for the artist related to this clip
|
wolffd@0
|
177
|
wolffd@0
|
178 [out, score] = this(1).my_db.mbtagdb.annots(this(1).artist_id());
|
wolffd@0
|
179 end
|
wolffd@0
|
180
|
wolffd@0
|
181 % @todo: generalise mg tags
|
wolffd@0
|
182 function [out, score] = mbtag_ids(this)
|
wolffd@0
|
183
|
wolffd@0
|
184 [out, score] = this(1).my_db.mbtagdb.annotids_for_owner(this(1).artist_id());
|
wolffd@0
|
185 end
|
wolffd@0
|
186
|
wolffd@0
|
187
|
wolffd@0
|
188 function len = play(clips, plen)
|
wolffd@0
|
189 % len = play(clips)
|
wolffd@0
|
190 %
|
wolffd@0
|
191 % plays magnatune clip given by clip id, and
|
wolffd@0
|
192 % returns full playback length
|
wolffd@0
|
193
|
wolffd@0
|
194 if nargin <2
|
wolffd@0
|
195 plen = 0; %seconds play
|
wolffd@0
|
196 end
|
wolffd@0
|
197
|
wolffd@0
|
198 len = 0;
|
wolffd@0
|
199 for i = 1:numel(clips)
|
wolffd@0
|
200
|
wolffd@0
|
201 % get sample rate
|
wolffd@0
|
202 [null,sr] = mp3read(clips(i).mp3file_full(),0);
|
wolffd@0
|
203
|
wolffd@0
|
204 if plen > 0
|
wolffd@0
|
205
|
wolffd@0
|
206 % read mp3 file
|
wolffd@0
|
207 [src,sr,NBITS,OPTS] = mp3read(clips(i).mp3file_full(), plen*sr);
|
wolffd@0
|
208 else
|
wolffd@0
|
209 % read full mp3 file
|
wolffd@0
|
210 [src,sr,NBITS,OPTS] = mp3read(clips(i).mp3file_full());
|
wolffd@0
|
211 end
|
wolffd@0
|
212
|
wolffd@0
|
213 % ---
|
wolffd@0
|
214 % NOTE: sound() seems to pause the system when trying to
|
wolffd@0
|
215 % play a clip while still playing another one
|
wolffd@0
|
216 % ---
|
wolffd@0
|
217 sound(src,sr);
|
wolffd@0
|
218
|
wolffd@0
|
219 fprintf('\n--- now playing ---\n');
|
wolffd@0
|
220 clips(i).print();
|
wolffd@0
|
221
|
wolffd@0
|
222 % add clip lengths
|
wolffd@0
|
223 len = len + length(src) / sr;
|
wolffd@0
|
224 end
|
wolffd@0
|
225 end
|
wolffd@0
|
226
|
wolffd@0
|
227 function skip(clips)
|
wolffd@0
|
228 % skips through given clips
|
wolffd@0
|
229
|
wolffd@0
|
230 clips.play(5);
|
wolffd@0
|
231 end
|
wolffd@0
|
232
|
wolffd@0
|
233 function out = dbpos(this)
|
wolffd@0
|
234 % returns matrix position for given clip id
|
wolffd@0
|
235
|
wolffd@0
|
236 out = find(this.my_db.annots_ids == this.id, 1 ,'first');
|
wolffd@0
|
237 end
|
wolffd@0
|
238
|
wolffd@0
|
239 % ---
|
wolffd@0
|
240 % Generic Features
|
wolffd@0
|
241 % ---
|
wolffd@0
|
242 function feature = features(clip, type, varargin)
|
wolffd@0
|
243 % feature = features(clip, type, varargin)
|
wolffd@0
|
244 %
|
wolffd@0
|
245 % returns the features of type "type" for given clips and
|
wolffd@0
|
246 % parameters
|
wolffd@0
|
247 % e.g. feature = clip.features('MTTAudioFeatureRAW')
|
wolffd@0
|
248
|
wolffd@0
|
249 db_name = MTTAudioFeatureDBgen.db_name(type);
|
wolffd@0
|
250
|
wolffd@0
|
251 % global database
|
wolffd@0
|
252 eval( sprintf( 'global %s;', db_name));
|
wolffd@0
|
253
|
wolffd@0
|
254 % create database if neccesary
|
wolffd@0
|
255 if eval(sprintf('isempty(%s);', db_name));
|
wolffd@0
|
256
|
wolffd@0
|
257 eval(sprintf('%s = MTTAudioFeatureDBgen(''%s'');', db_name, type));
|
wolffd@0
|
258 end
|
wolffd@0
|
259
|
wolffd@0
|
260 % retrieve features from db
|
wolffd@0
|
261 feature = eval(sprintf('%s.get_features(clip, varargin{:});', db_name));
|
wolffd@0
|
262 end
|
wolffd@0
|
263
|
wolffd@0
|
264 % ---
|
wolffd@0
|
265 % Audio Features Section
|
wolffd@0
|
266 % ---
|
wolffd@0
|
267 function features = audio_features_raw(clip)
|
wolffd@0
|
268 % get the features from the global database
|
wolffd@0
|
269
|
wolffd@0
|
270 features = clip.features('MTTAudioFeatureRAW');
|
wolffd@0
|
271 end
|
wolffd@0
|
272
|
wolffd@0
|
273 function features = audio_features_basicsm(clip, varargin)
|
wolffd@0
|
274 % get the features from the global database
|
wolffd@0
|
275
|
wolffd@0
|
276 features = clip.features('MTTAudioFeatureBasicSm', varargin{:});
|
wolffd@0
|
277 end
|
wolffd@0
|
278
|
wolffd@0
|
279 function features = genre_features_basic(clip, varargin)
|
wolffd@0
|
280 % get the features from the global database
|
wolffd@0
|
281
|
wolffd@0
|
282 features = clip.features('MTTTagFeatureGenreBasic', varargin{:});
|
wolffd@0
|
283
|
wolffd@0
|
284 end
|
wolffd@0
|
285
|
wolffd@0
|
286 function features = mixed_features_genrebasicsm(clip, varargin)
|
wolffd@0
|
287 % get the features from the global database
|
wolffd@0
|
288
|
wolffd@0
|
289 features = clip.features('MTTMixedFeatureGenreBasicSm', varargin{:});
|
wolffd@0
|
290 end
|
wolffd@0
|
291
|
wolffd@0
|
292 function features = mixed_features_genrebasicsm_pca(clip, varargin)
|
wolffd@0
|
293 % get the features from the global database
|
wolffd@0
|
294
|
wolffd@0
|
295 features = clip.features('MTTMixedFeatureGenreBasicSmPCA', varargin{:});
|
wolffd@0
|
296 end
|
wolffd@0
|
297
|
wolffd@0
|
298 function features = random_features(clip, varargin)
|
wolffd@0
|
299 % get the features from the global database
|
wolffd@0
|
300
|
wolffd@0
|
301 features = clip.features('MTTRandomFeature', varargin{:});
|
wolffd@0
|
302 end
|
wolffd@0
|
303
|
wolffd@0
|
304 end
|
wolffd@0
|
305
|
wolffd@0
|
306 % ---
|
wolffd@0
|
307 % static methods
|
wolffd@0
|
308 % ---
|
wolffd@0
|
309 methods(Static = true)
|
wolffd@0
|
310
|
wolffd@0
|
311 end
|
wolffd@0
|
312 end |