Daniel@0: function m = mirexport(f,varargin) Daniel@0: % mirexport(filename,...) exports statistical information related to Daniel@0: % diverse data into a text file called filename. Daniel@0: % mirexport('Workspace',...) instead directly output the statistical Daniel@0: % information in a structure array saved in the Matlab workspace. Daniel@0: % This structure contains three fields: Daniel@0: % filenames: the name of the original audio files, Daniel@0: % types: the name of the features, Daniel@0: % data: the data. Daniel@0: % The exported data should be related to the same initial audio file Daniel@0: % or the same ordered set of audio files. Daniel@0: % The data listed after the first arguments can be: Daniel@0: % - any feature computed in MIRtoolbox. Daniel@0: % What will be exported is the statistical description of the Daniel@0: % feature (using the mirstat function) Daniel@0: % - any structure array of such features. Daniel@0: % Such as the ouput of the mirstat function. Daniel@0: % - any cell array of such features. Daniel@0: % - the name of a text file. Daniel@0: % The text file is imported with the Matlab importdata command. Daniel@0: % Each line of the file should contains a fixed number of data Daniel@0: % delimited by tabulations. The first line, or 'header', Daniel@0: % indicates the name of each of these columns. Daniel@0: % The file format of the output can be either: Daniel@0: % - a text file. Daniel@0: % It follows the same text file representation as for the input Daniel@0: % text files. The first column of the matrix indicates the name Daniel@0: % of the audio files. The text file can be opened in Matlab, Daniel@0: % or in a spreadsheet program, such as Microsoft Excel, where the Daniel@0: % data matrix can be automatically reconstructed. Daniel@0: % - an attribute-relation file. Daniel@0: % It follows the ARFF standard, used in particular in the WEKA Daniel@0: % data mining environment. Daniel@0: Daniel@0: stored.data = {}; Daniel@0: stored.textdata = {}; Daniel@0: stored.name = {}; Daniel@0: narg = nargin; Daniel@0: if strcmpi(f,'Workspace') Daniel@0: format = 'Workspace'; Daniel@0: elseif length(f)>4 && strcmpi(f(end-4:end),'.arff') Daniel@0: format = 'ARFF'; Daniel@0: else Daniel@0: format = 'Matrix'; Daniel@0: end Daniel@0: v = ver('MIRtoolbox'); Daniel@0: title = ['MIRtoolbox' v.Version]; Daniel@0: class = {}; Daniel@0: if not(isempty(varargin)) && ischar(varargin{end}) && strcmp(varargin{end},'#add') Daniel@0: add = 1; Daniel@0: varargin(end) = []; Daniel@0: narg = narg-1; Daniel@0: else Daniel@0: add = 0; Daniel@0: end Daniel@0: for v = 2:narg Daniel@0: argv = varargin{v-1}; Daniel@0: if isa(argv,'mirdesign') Daniel@0: mirerror('MIREXPORT','You can only export features that have been already evaluated (using mireval).'); Daniel@0: end Daniel@0: if ischar(argv) Daniel@0: if strcmpi(argv,'Matrix') Daniel@0: format = 'Matrix'; Daniel@0: elseif strcmpi(argv,'ARFF') Daniel@0: format = 'ARFF'; Daniel@0: else Daniel@0: imported = importdata(argv,'\t',1); Daniel@0: imported.name = {}; Daniel@0: [stored class] = integrate(stored,imported); Daniel@0: end Daniel@0: elseif isstruct(argv) && isfield(argv,'data') Daniel@0: new.data = argv.data; Daniel@0: new.textdata = argv.fields; Daniel@0: new.name = {}; Daniel@0: [stored class] = integrate(stored,new); Daniel@0: else Daniel@0: new.data = argv; Daniel@0: new.textdata = ''; Daniel@0: new.name = {}; Daniel@0: [stored class] = integrate(stored,new); Daniel@0: end Daniel@0: end Daniel@0: switch format Daniel@0: case 'Matrix' Daniel@0: matrixformat(stored,f,title,add); Daniel@0: m = 1; Daniel@0: case 'ARFF' Daniel@0: classes = {}; Daniel@0: for i = 1:length(class) Daniel@0: if isempty(strcmp(class{i},classes)) || not(max(strcmp(class{i},classes))) Daniel@0: classes{end+1} = class{i}; Daniel@0: end Daniel@0: end Daniel@0: ARFFformat(stored,f,title,class,classes,add); Daniel@0: m = 1; Daniel@0: case 'Workspace' Daniel@0: m = variableformat(stored,f,title); Daniel@0: end Daniel@0: Daniel@0: Daniel@0: Daniel@0: function [stored class] = integrate(stored,new,class) Daniel@0: Daniel@0: if nargin<3 Daniel@0: class = {}; Daniel@0: end Daniel@0: Daniel@0: % Input information Daniel@0: data = new.data; Daniel@0: textdata = new.textdata; Daniel@0: if isfield(new,'name') Daniel@0: name = new.name; Daniel@0: else Daniel@0: name = {}; Daniel@0: end Daniel@0: Daniel@0: % Input information after processing Daniel@0: newdata = {}; Daniel@0: newtextdata = {}; Daniel@0: newname = {}; Daniel@0: Daniel@0: if isstruct(data) Daniel@0: if isfield(data,'Class') Daniel@0: class = data.Class; Daniel@0: data = rmfield(data,'Class'); Daniel@0: end Daniel@0: Daniel@0: if isfield(data,'FileNames') Daniel@0: name = data.FileNames; Daniel@0: data = rmfield(data,'FileNames'); Daniel@0: end Daniel@0: Daniel@0: fields = fieldnames(data); Daniel@0: nfields = length(fields); Daniel@0: Daniel@0: for w = 1:nfields Daniel@0: % Field information Daniel@0: field = fields{w}; Daniel@0: newfield.data = data.(field); Daniel@0: if 1 %not(isnumeric(newfield.data) && all(all(isnan(newfield.data)))) Daniel@0: if isempty(textdata) Daniel@0: newfield.textdata = field; Daniel@0: else Daniel@0: newfield.textdata = strcat(textdata,'_',field); Daniel@0: end Daniel@0: Daniel@0: % Processing of the field Daniel@0: [n class] = integrate({},newfield,class); Daniel@0: Daniel@0: % Concatenation of the results Daniel@0: newdata = {newdata{:} n.data{:}}; Daniel@0: newtextdata = {newtextdata{:} n.textdata{:}}; Daniel@0: newname = checkname(newname,name); Daniel@0: end Daniel@0: end Daniel@0: elseif isa(data,'mirdata') Daniel@0: newinput.data = mirstat(data); Daniel@0: if isfield(newinput.data,'FileNames') Daniel@0: newinput.data = rmfield(newinput.data,'FileNames'); Daniel@0: end Daniel@0: title = get(data,'Title'); Daniel@0: newinput.textdata = [textdata '_' title(find(not(isspace(title))))]; Daniel@0: [n class] = integrate({},newinput,class); Daniel@0: newdata = n.data; Daniel@0: newtextdata = n.textdata; Daniel@0: newname = get(data,'Name'); Daniel@0: elseif iscell(textdata) Daniel@0: % Input comes from importdata Daniel@0: nvar = size(data,2); Daniel@0: newdata = cell(1,nvar); Daniel@0: newtextdata = cell(1,nvar); Daniel@0: for i = 1:nvar Daniel@0: newdata{i} = data(:,i); Daniel@0: newtextdata{i} = textdata{i}; Daniel@0: end Daniel@0: newname = {}; Daniel@0: elseif iscell(data) Daniel@0: for i = 1:length(data) Daniel@0: if not(isempty(data{i})) Daniel@0: % Element information Daniel@0: newelement.data = data{i}; Daniel@0: newelement.textdata = [textdata num2str(i)]; Daniel@0: Daniel@0: % Processing of the element Daniel@0: [n class] = integrate({},newelement,class); Daniel@0: Daniel@0: % Concatenation of the results Daniel@0: newdata = {newdata{:} n.data{:}}; Daniel@0: newtextdata = {newtextdata{:} n.textdata{:}}; Daniel@0: newname = checkname(newname,n.name); Daniel@0: end Daniel@0: end Daniel@0: elseif size(data,4)>1 Daniel@0: % Input is vector Daniel@0: for w = 1:size(data,4) Daniel@0: % Bin information Daniel@0: bin.data = data(:,:,:,w); Daniel@0: if isempty(textdata) Daniel@0: bin.textdata = num2str(w); Daniel@0: else Daniel@0: bin.textdata = strcat(textdata,'_',num2str(w)); Daniel@0: end Daniel@0: Daniel@0: % Processing of the bin Daniel@0: [n class] = integrate({},bin,class); Daniel@0: Daniel@0: % Concatenation of the results Daniel@0: newdata = {newdata{:} n.data{:}}; Daniel@0: newtextdata = {newtextdata{:} n.textdata{:}}; Daniel@0: end Daniel@0: elseif size(data,3)>1 Daniel@0: % Input is vector Daniel@0: for w = 1:size(data,3) Daniel@0: % Bin information Daniel@0: bin.data = data(:,:,w,:); Daniel@0: if isempty(textdata) Daniel@0: bin.textdata = num2str(w); Daniel@0: else Daniel@0: bin.textdata = strcat(textdata,'_',num2str(w)); Daniel@0: end Daniel@0: Daniel@0: % Processing of the bin Daniel@0: [n class] = integrate({},bin,class); Daniel@0: Daniel@0: % Concatenation of the results Daniel@0: newdata = {newdata{:} n.data{:}}; Daniel@0: newtextdata = {newtextdata{:} n.textdata{:}}; Daniel@0: end Daniel@0: elseif size(data,1)>1 && size(data,1)<=50 Daniel@0: % Input is vector Daniel@0: for w = 1:size(data,1) Daniel@0: % Bin information Daniel@0: bin.data = data(w,:,:,:); Daniel@0: if isempty(textdata) Daniel@0: bin.textdata = num2str(w); Daniel@0: else Daniel@0: bin.textdata = strcat(textdata,'_',num2str(w)); Daniel@0: end Daniel@0: Daniel@0: % Processing of the bin Daniel@0: [n class] = integrate({},bin,class); Daniel@0: Daniel@0: % Concatenation of the results Daniel@0: newdata = {newdata{:} n.data{:}}; Daniel@0: newtextdata = {newtextdata{:} n.textdata{:}}; Daniel@0: end Daniel@0: else Daniel@0: if size(data,1)>1 Daniel@0: data = mean(data); Daniel@0: end Daniel@0: newdata = {data}; Daniel@0: newtextdata = {textdata}; Daniel@0: newname = {}; Daniel@0: end Daniel@0: if isempty(stored) Daniel@0: stored.data = newdata; Daniel@0: stored.textdata = newtextdata; Daniel@0: stored.name = newname; Daniel@0: else Daniel@0: stored.data = {stored.data{:} newdata{:}}; Daniel@0: stored.textdata = {stored.textdata{:} newtextdata{:}}; Daniel@0: if isempty(stored.name) Daniel@0: stored.name = newname; Daniel@0: else Daniel@0: stored.name = checkname(newname,stored.name); Daniel@0: end Daniel@0: end Daniel@0: Daniel@0: Daniel@0: function m = matrixformat(data,filename,title,add) Daniel@0: named = ~isempty(data.name); Daniel@0: if named Daniel@0: if not(add) Daniel@0: m(1,:) = {title,data.textdata{:}}; Daniel@0: end Daniel@0: for i = 1:length(data.name) Daniel@0: m{i+~add,1} = data.name{i}; Daniel@0: end Daniel@0: elseif not(add) Daniel@0: m(1,:) = {data.textdata{:}}; Daniel@0: end Daniel@0: for i = 1:length(data.data) Daniel@0: m((1:length(data.data{i}))+~add,i+named) = num2cell(data.data{i}); Daniel@0: end Daniel@0: if add Daniel@0: fid = fopen(filename,'at'); Daniel@0: else Daniel@0: fid = fopen(filename,'wt'); Daniel@0: end Daniel@0: for i = 1:size(m,1) Daniel@0: for j = 1:size(m,2) Daniel@0: if ischar(m{i,j}) Daniel@0: fprintf(fid,'%s\t', m{i,j}(find(not(m{i,j} == ' ')))); Daniel@0: else Daniel@0: if iscell(m{i,j}) % Problem with key strength pos to be solved Daniel@0: fprintf(fid,'%f\t', m{i,j}{1}); Daniel@0: else Daniel@0: fprintf(fid,'%f\t', m{i,j}); Daniel@0: end Daniel@0: end Daniel@0: end Daniel@0: %if i < size(m,1) Daniel@0: fprintf(fid,'\n'); Daniel@0: %end Daniel@0: end Daniel@0: fclose(fid); Daniel@0: disp(['Data exported to file ',filename,'.']); Daniel@0: Daniel@0: Daniel@0: function ARFFformat(data,filename,title,class,classes,add) Daniel@0: if add Daniel@0: fid = fopen(filename,'at'); Daniel@0: else Daniel@0: fid = fopen(filename,'wt'); Daniel@0: fprintf(fid,['%% Attribution-Relation File automatically generated using ',title,'\n\n']); Daniel@0: fprintf(fid,'@RELATION %s\n\n',title); Daniel@0: for i = 1:length(data.textdata) Daniel@0: fprintf(fid,'@ATTRIBUTE %s NUMERIC\n',data.textdata{i}); Daniel@0: end Daniel@0: if not(isempty(class)) Daniel@0: fprintf(fid,'@ATTRIBUTE class {'); Daniel@0: for i = 1:length(classes) Daniel@0: if i>1 Daniel@0: fprintf(fid,','); Daniel@0: end Daniel@0: fprintf(fid,'%s',classes{i}); Daniel@0: end Daniel@0: fprintf(fid,'}\n'); Daniel@0: end Daniel@0: fprintf(fid,'\n@DATA\n'); Daniel@0: fid2 = fopen([filename(1:end-5) '.filenames.txt'],'wt'); Daniel@0: for i = 1:length(data.name) Daniel@0: fprintf(fid2,'%s\n',data.name{i}); Daniel@0: end Daniel@0: fclose(fid2); Daniel@0: end Daniel@0: Daniel@0: try Daniel@0: data = cell2mat(data.data(:))'; Daniel@0: catch Daniel@0: error('ERROR IN MIREXPORT: Are you sure all the data to be exported relate to the same ordered list of audio files?'); Daniel@0: end Daniel@0: for i = 1:size(data,1) Daniel@0: fprintf(fid,'%d ',data(i,:)); Daniel@0: if not(isempty(class)) Daniel@0: fprintf(fid,'%s',class{i}); Daniel@0: end Daniel@0: fprintf(fid,'\n'); Daniel@0: end Daniel@0: fclose(fid); Daniel@0: disp(['Data exported to file ',filename,'.']); Daniel@0: Daniel@0: Daniel@0: function m = variableformat(data,filename,title) Daniel@0: m.types = data.textdata; Daniel@0: m.filenames = data.name; Daniel@0: for i = 1:length(data.data) Daniel@0: m.data{i} = data.data{i}; Daniel@0: end Daniel@0: Daniel@0: Daniel@0: function name = checkname(newname,name) Daniel@0: if not(isempty(newname)) && not(isempty(name)) Daniel@0: if length(newname) == length(name) Daniel@0: for i = 1:length(name) Daniel@0: if not(strcmp(name{i},newname{i})) Daniel@0: error('ERROR IN MIREXPORT: All the input are not associated to the same audio files (or the same ordering of these files.'); Daniel@0: end Daniel@0: end Daniel@0: else Daniel@0: error('ERROR IN MIREXPORT: All the input are not associated to the same audio files.'); Daniel@0: end Daniel@0: elseif isempty(name) Daniel@0: name = newname; Daniel@0: end