Mercurial > hg > camir-aes2014
view core/magnatagatune/xml_parse_mtt.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 source
function features = xml_parse_mtt(file) % features = xml_parse_mtt(file) % % parses the magnatagatune xml file to retrieve the audio % analysis results. The file isexpected to use the deprecated % EchoNest XML format % % time always travels an the horizontal axis % --- % TODO: Add Error checking to certan tags as chroma number, % loudness max etc. % --- fdata = fileread(file); try % --- % TODO: check for other than the p-code exceptions % --- data = xml_parseany(fdata); catch exception end %% ------------------------------------------------------------------------ % --- % copy general track data % --- fields = fieldnames(data.track{1}.ATTRIBUTE); for i = 1:length(fields) features.(fields{i}) = str2double(data.track{1}.ATTRIBUTE.(fields{i})); end %% ------------------------------------------------------------------------ % --- % get harmonic analysis. this is stored in segments % --- dsegments = data.track{1}.segments{1}.segment; for i = 1:numel(dsegments) % get start and duration segments(i).start = str2double(dsegments{i}.ATTRIBUTE.start); segments(i).duration = str2double(dsegments{i}.ATTRIBUTE.duration); % --- % NOTE: for the chroma and mfcc features, we assume that the classes % are always saved and parsed in correct order, thus we can afford to % refrain from saving the class number with the class % --- % assemble chroma features segments(i).pitches = zeros(12,1); for j = 1:12 segments(i).pitches(j) = str2double(... dsegments{i}.pitches{1}.pitch{j}.CONTENT); end % assemble mfcc features; segments(i).timbre = zeros(numel(dsegments{i}.timbre{1}.coeff),1); for j = 1:numel(dsegments{i}.timbre{1}.coeff) segments(i).timbre(j) = str2double(... dsegments{i}.timbre{1}.coeff{j}.CONTENT); end % get loudness measurements in dB and time segments(i).loudness = str2double(... dsegments{i}.loudness{1}.dB{1}.CONTENT); segments(i).loudness_time = str2double(... dsegments{i}.loudness{1}.dB{1}.ATTRIBUTE.time); segments(i).loudness_max = str2double(... dsegments{i}.loudness{1}.dB{2}.CONTENT); segments(i).loudness_max_time = str2double(... dsegments{i}.loudness{1}.dB{2}.ATTRIBUTE.time); end features.segments = segments; %% ------------------------------------------------------------------------ % --- % get sections % --- dsections = data.track{1}.sections{1}.section; secstart = zeros(1,numel(dsections)); secduration = zeros(1,numel(dsections)); for i = 1:numel(dsections) sections(i).start = str2double(dsections{i}.ATTRIBUTE.start); sections(i).duration = str2double(dsections{i}.ATTRIBUTE.duration); end features.sections = sections; %% ------------------------------------------------------------------------ % --- % get beat and rythm data. the metric data is structured % hierarchically, as each bar contains several beats, % which contaisn several tatums. % NOTE: Although the metrum and tempo have been evaluated and fixed % on a global scale, the number of bars and tatum vary greatly. % --- dbars = data.track{1}.meter{1}.bar; for i = 1:numel(dbars) % get bar information bars(i).confidence = str2double(dbars{i}.ATTRIBUTE.conf); for j = 1:numel(dbars{i}.beat) % get beat information bars(i).beat(j).confidence = str2double(dbars{i}.beat{j}.ATTRIBUTE.conf); for k = 1:numel(dbars{i}.beat{j}.tatum) % get tatum information if ~isempty(dbars{i}.beat{j}.tatum{k}.ATTRIBUTE) bars(i).beat(j).tatum(k).time = str2double(dbars{i}.beat{j}.tatum{k}.CONTENT); bars(i).beat(j).tatum(k).confidence = str2double(dbars{i}.beat{j}.tatum{k}.ATTRIBUTE.conf); else % save empty struct bars(i).beat(j).tatum = struct([]); end end end end features.bars = bars;