wolffd@0
|
1 function m = mirexport(f,varargin)
|
wolffd@0
|
2 % mirexport(filename,...) exports statistical information related to
|
wolffd@0
|
3 % diverse data into a text file called filename.
|
wolffd@0
|
4 % mirexport('Workspace',...) instead directly output the statistical
|
wolffd@0
|
5 % information in a structure array saved in the Matlab workspace.
|
wolffd@0
|
6 % This structure contains three fields:
|
wolffd@0
|
7 % filenames: the name of the original audio files,
|
wolffd@0
|
8 % types: the name of the features,
|
wolffd@0
|
9 % data: the data.
|
wolffd@0
|
10 % The exported data should be related to the same initial audio file
|
wolffd@0
|
11 % or the same ordered set of audio files.
|
wolffd@0
|
12 % The data listed after the first arguments can be:
|
wolffd@0
|
13 % - any feature computed in MIRtoolbox.
|
wolffd@0
|
14 % What will be exported is the statistical description of the
|
wolffd@0
|
15 % feature (using the mirstat function)
|
wolffd@0
|
16 % - any structure array of such features.
|
wolffd@0
|
17 % Such as the ouput of the mirstat function.
|
wolffd@0
|
18 % - any cell array of such features.
|
wolffd@0
|
19 % - the name of a text file.
|
wolffd@0
|
20 % The text file is imported with the Matlab importdata command.
|
wolffd@0
|
21 % Each line of the file should contains a fixed number of data
|
wolffd@0
|
22 % delimited by tabulations. The first line, or 'header',
|
wolffd@0
|
23 % indicates the name of each of these columns.
|
wolffd@0
|
24 % The file format of the output can be either:
|
wolffd@0
|
25 % - a text file.
|
wolffd@0
|
26 % It follows the same text file representation as for the input
|
wolffd@0
|
27 % text files. The first column of the matrix indicates the name
|
wolffd@0
|
28 % of the audio files. The text file can be opened in Matlab,
|
wolffd@0
|
29 % or in a spreadsheet program, such as Microsoft Excel, where the
|
wolffd@0
|
30 % data matrix can be automatically reconstructed.
|
wolffd@0
|
31 % - an attribute-relation file.
|
wolffd@0
|
32 % It follows the ARFF standard, used in particular in the WEKA
|
wolffd@0
|
33 % data mining environment.
|
wolffd@0
|
34
|
wolffd@0
|
35 stored.data = {};
|
wolffd@0
|
36 stored.textdata = {};
|
wolffd@0
|
37 stored.name = {};
|
wolffd@0
|
38 narg = nargin;
|
wolffd@0
|
39 if strcmpi(f,'Workspace')
|
wolffd@0
|
40 format = 'Workspace';
|
wolffd@0
|
41 elseif length(f)>4 && strcmpi(f(end-4:end),'.arff')
|
wolffd@0
|
42 format = 'ARFF';
|
wolffd@0
|
43 else
|
wolffd@0
|
44 format = 'Matrix';
|
wolffd@0
|
45 end
|
wolffd@0
|
46 v = ver('MIRtoolbox');
|
wolffd@0
|
47 title = ['MIRtoolbox' v.Version];
|
wolffd@0
|
48 class = {};
|
wolffd@0
|
49 if not(isempty(varargin)) && ischar(varargin{end}) && strcmp(varargin{end},'#add')
|
wolffd@0
|
50 add = 1;
|
wolffd@0
|
51 varargin(end) = [];
|
wolffd@0
|
52 narg = narg-1;
|
wolffd@0
|
53 else
|
wolffd@0
|
54 add = 0;
|
wolffd@0
|
55 end
|
wolffd@0
|
56 for v = 2:narg
|
wolffd@0
|
57 argv = varargin{v-1};
|
wolffd@0
|
58 if isa(argv,'mirdesign')
|
wolffd@0
|
59 mirerror('MIREXPORT','You can only export features that have been already evaluated (using mireval).');
|
wolffd@0
|
60 end
|
wolffd@0
|
61 if ischar(argv)
|
wolffd@0
|
62 if strcmpi(argv,'Matrix')
|
wolffd@0
|
63 format = 'Matrix';
|
wolffd@0
|
64 elseif strcmpi(argv,'ARFF')
|
wolffd@0
|
65 format = 'ARFF';
|
wolffd@0
|
66 else
|
wolffd@0
|
67 imported = importdata(argv,'\t',1);
|
wolffd@0
|
68 imported.name = {};
|
wolffd@0
|
69 [stored class] = integrate(stored,imported);
|
wolffd@0
|
70 end
|
wolffd@0
|
71 elseif isstruct(argv) && isfield(argv,'data')
|
wolffd@0
|
72 new.data = argv.data;
|
wolffd@0
|
73 new.textdata = argv.fields;
|
wolffd@0
|
74 new.name = {};
|
wolffd@0
|
75 [stored class] = integrate(stored,new);
|
wolffd@0
|
76 else
|
wolffd@0
|
77 new.data = argv;
|
wolffd@0
|
78 new.textdata = '';
|
wolffd@0
|
79 new.name = {};
|
wolffd@0
|
80 [stored class] = integrate(stored,new);
|
wolffd@0
|
81 end
|
wolffd@0
|
82 end
|
wolffd@0
|
83 switch format
|
wolffd@0
|
84 case 'Matrix'
|
wolffd@0
|
85 matrixformat(stored,f,title,add);
|
wolffd@0
|
86 m = 1;
|
wolffd@0
|
87 case 'ARFF'
|
wolffd@0
|
88 classes = {};
|
wolffd@0
|
89 for i = 1:length(class)
|
wolffd@0
|
90 if isempty(strcmp(class{i},classes)) || not(max(strcmp(class{i},classes)))
|
wolffd@0
|
91 classes{end+1} = class{i};
|
wolffd@0
|
92 end
|
wolffd@0
|
93 end
|
wolffd@0
|
94 ARFFformat(stored,f,title,class,classes,add);
|
wolffd@0
|
95 m = 1;
|
wolffd@0
|
96 case 'Workspace'
|
wolffd@0
|
97 m = variableformat(stored,f,title);
|
wolffd@0
|
98 end
|
wolffd@0
|
99
|
wolffd@0
|
100
|
wolffd@0
|
101
|
wolffd@0
|
102 function [stored class] = integrate(stored,new,class)
|
wolffd@0
|
103
|
wolffd@0
|
104 if nargin<3
|
wolffd@0
|
105 class = {};
|
wolffd@0
|
106 end
|
wolffd@0
|
107
|
wolffd@0
|
108 % Input information
|
wolffd@0
|
109 data = new.data;
|
wolffd@0
|
110 textdata = new.textdata;
|
wolffd@0
|
111 if isfield(new,'name')
|
wolffd@0
|
112 name = new.name;
|
wolffd@0
|
113 else
|
wolffd@0
|
114 name = {};
|
wolffd@0
|
115 end
|
wolffd@0
|
116
|
wolffd@0
|
117 % Input information after processing
|
wolffd@0
|
118 newdata = {};
|
wolffd@0
|
119 newtextdata = {};
|
wolffd@0
|
120 newname = {};
|
wolffd@0
|
121
|
wolffd@0
|
122 if isstruct(data)
|
wolffd@0
|
123 if isfield(data,'Class')
|
wolffd@0
|
124 class = data.Class;
|
wolffd@0
|
125 data = rmfield(data,'Class');
|
wolffd@0
|
126 end
|
wolffd@0
|
127
|
wolffd@0
|
128 if isfield(data,'FileNames')
|
wolffd@0
|
129 name = data.FileNames;
|
wolffd@0
|
130 data = rmfield(data,'FileNames');
|
wolffd@0
|
131 end
|
wolffd@0
|
132
|
wolffd@0
|
133 fields = fieldnames(data);
|
wolffd@0
|
134 nfields = length(fields);
|
wolffd@0
|
135
|
wolffd@0
|
136 for w = 1:nfields
|
wolffd@0
|
137 % Field information
|
wolffd@0
|
138 field = fields{w};
|
wolffd@0
|
139 newfield.data = data.(field);
|
wolffd@0
|
140 if 1 %not(isnumeric(newfield.data) && all(all(isnan(newfield.data))))
|
wolffd@0
|
141 if isempty(textdata)
|
wolffd@0
|
142 newfield.textdata = field;
|
wolffd@0
|
143 else
|
wolffd@0
|
144 newfield.textdata = strcat(textdata,'_',field);
|
wolffd@0
|
145 end
|
wolffd@0
|
146
|
wolffd@0
|
147 % Processing of the field
|
wolffd@0
|
148 [n class] = integrate({},newfield,class);
|
wolffd@0
|
149
|
wolffd@0
|
150 % Concatenation of the results
|
wolffd@0
|
151 newdata = {newdata{:} n.data{:}};
|
wolffd@0
|
152 newtextdata = {newtextdata{:} n.textdata{:}};
|
wolffd@0
|
153 newname = checkname(newname,name);
|
wolffd@0
|
154 end
|
wolffd@0
|
155 end
|
wolffd@0
|
156 elseif isa(data,'mirdata')
|
wolffd@0
|
157 newinput.data = mirstat(data);
|
wolffd@0
|
158 if isfield(newinput.data,'FileNames')
|
wolffd@0
|
159 newinput.data = rmfield(newinput.data,'FileNames');
|
wolffd@0
|
160 end
|
wolffd@0
|
161 title = get(data,'Title');
|
wolffd@0
|
162 newinput.textdata = [textdata '_' title(find(not(isspace(title))))];
|
wolffd@0
|
163 [n class] = integrate({},newinput,class);
|
wolffd@0
|
164 newdata = n.data;
|
wolffd@0
|
165 newtextdata = n.textdata;
|
wolffd@0
|
166 newname = get(data,'Name');
|
wolffd@0
|
167 elseif iscell(textdata)
|
wolffd@0
|
168 % Input comes from importdata
|
wolffd@0
|
169 nvar = size(data,2);
|
wolffd@0
|
170 newdata = cell(1,nvar);
|
wolffd@0
|
171 newtextdata = cell(1,nvar);
|
wolffd@0
|
172 for i = 1:nvar
|
wolffd@0
|
173 newdata{i} = data(:,i);
|
wolffd@0
|
174 newtextdata{i} = textdata{i};
|
wolffd@0
|
175 end
|
wolffd@0
|
176 newname = {};
|
wolffd@0
|
177 elseif iscell(data)
|
wolffd@0
|
178 for i = 1:length(data)
|
wolffd@0
|
179 if not(isempty(data{i}))
|
wolffd@0
|
180 % Element information
|
wolffd@0
|
181 newelement.data = data{i};
|
wolffd@0
|
182 newelement.textdata = [textdata num2str(i)];
|
wolffd@0
|
183
|
wolffd@0
|
184 % Processing of the element
|
wolffd@0
|
185 [n class] = integrate({},newelement,class);
|
wolffd@0
|
186
|
wolffd@0
|
187 % Concatenation of the results
|
wolffd@0
|
188 newdata = {newdata{:} n.data{:}};
|
wolffd@0
|
189 newtextdata = {newtextdata{:} n.textdata{:}};
|
wolffd@0
|
190 newname = checkname(newname,n.name);
|
wolffd@0
|
191 end
|
wolffd@0
|
192 end
|
wolffd@0
|
193 elseif size(data,4)>1
|
wolffd@0
|
194 % Input is vector
|
wolffd@0
|
195 for w = 1:size(data,4)
|
wolffd@0
|
196 % Bin information
|
wolffd@0
|
197 bin.data = data(:,:,:,w);
|
wolffd@0
|
198 if isempty(textdata)
|
wolffd@0
|
199 bin.textdata = num2str(w);
|
wolffd@0
|
200 else
|
wolffd@0
|
201 bin.textdata = strcat(textdata,'_',num2str(w));
|
wolffd@0
|
202 end
|
wolffd@0
|
203
|
wolffd@0
|
204 % Processing of the bin
|
wolffd@0
|
205 [n class] = integrate({},bin,class);
|
wolffd@0
|
206
|
wolffd@0
|
207 % Concatenation of the results
|
wolffd@0
|
208 newdata = {newdata{:} n.data{:}};
|
wolffd@0
|
209 newtextdata = {newtextdata{:} n.textdata{:}};
|
wolffd@0
|
210 end
|
wolffd@0
|
211 elseif size(data,3)>1
|
wolffd@0
|
212 % Input is vector
|
wolffd@0
|
213 for w = 1:size(data,3)
|
wolffd@0
|
214 % Bin information
|
wolffd@0
|
215 bin.data = data(:,:,w,:);
|
wolffd@0
|
216 if isempty(textdata)
|
wolffd@0
|
217 bin.textdata = num2str(w);
|
wolffd@0
|
218 else
|
wolffd@0
|
219 bin.textdata = strcat(textdata,'_',num2str(w));
|
wolffd@0
|
220 end
|
wolffd@0
|
221
|
wolffd@0
|
222 % Processing of the bin
|
wolffd@0
|
223 [n class] = integrate({},bin,class);
|
wolffd@0
|
224
|
wolffd@0
|
225 % Concatenation of the results
|
wolffd@0
|
226 newdata = {newdata{:} n.data{:}};
|
wolffd@0
|
227 newtextdata = {newtextdata{:} n.textdata{:}};
|
wolffd@0
|
228 end
|
wolffd@0
|
229 elseif size(data,1)>1 && size(data,1)<=50
|
wolffd@0
|
230 % Input is vector
|
wolffd@0
|
231 for w = 1:size(data,1)
|
wolffd@0
|
232 % Bin information
|
wolffd@0
|
233 bin.data = data(w,:,:,:);
|
wolffd@0
|
234 if isempty(textdata)
|
wolffd@0
|
235 bin.textdata = num2str(w);
|
wolffd@0
|
236 else
|
wolffd@0
|
237 bin.textdata = strcat(textdata,'_',num2str(w));
|
wolffd@0
|
238 end
|
wolffd@0
|
239
|
wolffd@0
|
240 % Processing of the bin
|
wolffd@0
|
241 [n class] = integrate({},bin,class);
|
wolffd@0
|
242
|
wolffd@0
|
243 % Concatenation of the results
|
wolffd@0
|
244 newdata = {newdata{:} n.data{:}};
|
wolffd@0
|
245 newtextdata = {newtextdata{:} n.textdata{:}};
|
wolffd@0
|
246 end
|
wolffd@0
|
247 else
|
wolffd@0
|
248 if size(data,1)>1
|
wolffd@0
|
249 data = mean(data);
|
wolffd@0
|
250 end
|
wolffd@0
|
251 newdata = {data};
|
wolffd@0
|
252 newtextdata = {textdata};
|
wolffd@0
|
253 newname = {};
|
wolffd@0
|
254 end
|
wolffd@0
|
255 if isempty(stored)
|
wolffd@0
|
256 stored.data = newdata;
|
wolffd@0
|
257 stored.textdata = newtextdata;
|
wolffd@0
|
258 stored.name = newname;
|
wolffd@0
|
259 else
|
wolffd@0
|
260 stored.data = {stored.data{:} newdata{:}};
|
wolffd@0
|
261 stored.textdata = {stored.textdata{:} newtextdata{:}};
|
wolffd@0
|
262 if isempty(stored.name)
|
wolffd@0
|
263 stored.name = newname;
|
wolffd@0
|
264 else
|
wolffd@0
|
265 stored.name = checkname(newname,stored.name);
|
wolffd@0
|
266 end
|
wolffd@0
|
267 end
|
wolffd@0
|
268
|
wolffd@0
|
269
|
wolffd@0
|
270 function m = matrixformat(data,filename,title,add)
|
wolffd@0
|
271 named = ~isempty(data.name);
|
wolffd@0
|
272 if named
|
wolffd@0
|
273 if not(add)
|
wolffd@0
|
274 m(1,:) = {title,data.textdata{:}};
|
wolffd@0
|
275 end
|
wolffd@0
|
276 for i = 1:length(data.name)
|
wolffd@0
|
277 m{i+~add,1} = data.name{i};
|
wolffd@0
|
278 end
|
wolffd@0
|
279 elseif not(add)
|
wolffd@0
|
280 m(1,:) = {data.textdata{:}};
|
wolffd@0
|
281 end
|
wolffd@0
|
282 for i = 1:length(data.data)
|
wolffd@0
|
283 m((1:length(data.data{i}))+~add,i+named) = num2cell(data.data{i});
|
wolffd@0
|
284 end
|
wolffd@0
|
285 if add
|
wolffd@0
|
286 fid = fopen(filename,'at');
|
wolffd@0
|
287 else
|
wolffd@0
|
288 fid = fopen(filename,'wt');
|
wolffd@0
|
289 end
|
wolffd@0
|
290 for i = 1:size(m,1)
|
wolffd@0
|
291 for j = 1:size(m,2)
|
wolffd@0
|
292 if ischar(m{i,j})
|
wolffd@0
|
293 fprintf(fid,'%s\t', m{i,j}(find(not(m{i,j} == ' '))));
|
wolffd@0
|
294 else
|
wolffd@0
|
295 if iscell(m{i,j}) % Problem with key strength pos to be solved
|
wolffd@0
|
296 fprintf(fid,'%f\t', m{i,j}{1});
|
wolffd@0
|
297 else
|
wolffd@0
|
298 fprintf(fid,'%f\t', m{i,j});
|
wolffd@0
|
299 end
|
wolffd@0
|
300 end
|
wolffd@0
|
301 end
|
wolffd@0
|
302 %if i < size(m,1)
|
wolffd@0
|
303 fprintf(fid,'\n');
|
wolffd@0
|
304 %end
|
wolffd@0
|
305 end
|
wolffd@0
|
306 fclose(fid);
|
wolffd@0
|
307 disp(['Data exported to file ',filename,'.']);
|
wolffd@0
|
308
|
wolffd@0
|
309
|
wolffd@0
|
310 function ARFFformat(data,filename,title,class,classes,add)
|
wolffd@0
|
311 if add
|
wolffd@0
|
312 fid = fopen(filename,'at');
|
wolffd@0
|
313 else
|
wolffd@0
|
314 fid = fopen(filename,'wt');
|
wolffd@0
|
315 fprintf(fid,['%% Attribution-Relation File automatically generated using ',title,'\n\n']);
|
wolffd@0
|
316 fprintf(fid,'@RELATION %s\n\n',title);
|
wolffd@0
|
317 for i = 1:length(data.textdata)
|
wolffd@0
|
318 fprintf(fid,'@ATTRIBUTE %s NUMERIC\n',data.textdata{i});
|
wolffd@0
|
319 end
|
wolffd@0
|
320 if not(isempty(class))
|
wolffd@0
|
321 fprintf(fid,'@ATTRIBUTE class {');
|
wolffd@0
|
322 for i = 1:length(classes)
|
wolffd@0
|
323 if i>1
|
wolffd@0
|
324 fprintf(fid,',');
|
wolffd@0
|
325 end
|
wolffd@0
|
326 fprintf(fid,'%s',classes{i});
|
wolffd@0
|
327 end
|
wolffd@0
|
328 fprintf(fid,'}\n');
|
wolffd@0
|
329 end
|
wolffd@0
|
330 fprintf(fid,'\n@DATA\n');
|
wolffd@0
|
331 fid2 = fopen([filename(1:end-5) '.filenames.txt'],'wt');
|
wolffd@0
|
332 for i = 1:length(data.name)
|
wolffd@0
|
333 fprintf(fid2,'%s\n',data.name{i});
|
wolffd@0
|
334 end
|
wolffd@0
|
335 fclose(fid2);
|
wolffd@0
|
336 end
|
wolffd@0
|
337
|
wolffd@0
|
338 try
|
wolffd@0
|
339 data = cell2mat(data.data(:))';
|
wolffd@0
|
340 catch
|
wolffd@0
|
341 error('ERROR IN MIREXPORT: Are you sure all the data to be exported relate to the same ordered list of audio files?');
|
wolffd@0
|
342 end
|
wolffd@0
|
343 for i = 1:size(data,1)
|
wolffd@0
|
344 fprintf(fid,'%d ',data(i,:));
|
wolffd@0
|
345 if not(isempty(class))
|
wolffd@0
|
346 fprintf(fid,'%s',class{i});
|
wolffd@0
|
347 end
|
wolffd@0
|
348 fprintf(fid,'\n');
|
wolffd@0
|
349 end
|
wolffd@0
|
350 fclose(fid);
|
wolffd@0
|
351 disp(['Data exported to file ',filename,'.']);
|
wolffd@0
|
352
|
wolffd@0
|
353
|
wolffd@0
|
354 function m = variableformat(data,filename,title)
|
wolffd@0
|
355 m.types = data.textdata;
|
wolffd@0
|
356 m.filenames = data.name;
|
wolffd@0
|
357 for i = 1:length(data.data)
|
wolffd@0
|
358 m.data{i} = data.data{i};
|
wolffd@0
|
359 end
|
wolffd@0
|
360
|
wolffd@0
|
361
|
wolffd@0
|
362 function name = checkname(newname,name)
|
wolffd@0
|
363 if not(isempty(newname)) && not(isempty(name))
|
wolffd@0
|
364 if length(newname) == length(name)
|
wolffd@0
|
365 for i = 1:length(name)
|
wolffd@0
|
366 if not(strcmp(name{i},newname{i}))
|
wolffd@0
|
367 error('ERROR IN MIREXPORT: All the input are not associated to the same audio files (or the same ordering of these files.');
|
wolffd@0
|
368 end
|
wolffd@0
|
369 end
|
wolffd@0
|
370 else
|
wolffd@0
|
371 error('ERROR IN MIREXPORT: All the input are not associated to the same audio files.');
|
wolffd@0
|
372 end
|
wolffd@0
|
373 elseif isempty(name)
|
wolffd@0
|
374 name = newname;
|
wolffd@0
|
375 end |