wolffd@0: function r = mirfeatures(x,varargin) wolffd@0: % f = mirfeatures(x) computes a large set of features from one or several wolffd@0: % audio files. x can be either the name of an audio file, or the wolffd@0: % 'Folder' keyword. wolffd@0: % mirfeatures(...,'Stat') returns the statistics of the features instead wolffd@0: % of the complete features themselves. wolffd@0: % mirfeatures(...,'Segment',t) segments the audio sequence at the wolffd@0: % temporal positions indicated in the array t (in s.), and analyzes wolffd@0: % each segment separately. wolffd@0: wolffd@0: %(not available yet) wolffd@0: % mirfeatures(...,'Filterbank',nc) computes the analysis on each channel wolffd@0: % of a filterbank decomposition. wolffd@0: % Default value: nc = 5 wolffd@0: % mirfeatures(...,'Frame',...) wolffd@0: % mirfeatures(...,'Normal') wolffd@0: % mirfeatures(...,'Sampling',s) wolffd@0: % miraudio options (Extract, ...) wolffd@0: wolffd@0: [stat,nchan,segm,feat] = scanargin(varargin); wolffd@0: wolffd@0: if isa(x,'miraudio') || isa(x,'mirdesign') wolffd@0: a = miraudio(x,'Normal'); % normalize with respect to RMS energy wolffd@0: % in order to consider timbre independently of wolffd@0: % energy wolffd@0: else wolffd@0: a = miraudio('Design','Normal'); wolffd@0: end wolffd@0: wolffd@0: if not(isempty(segm)) wolffd@0: a = mirsegment(a,segm); wolffd@0: end wolffd@0: wolffd@0: wolffd@0: wolffd@0: % DYNAMICS wolffd@0: % -------- wolffd@0: wolffd@0: r.dynamics.rms = mirrms(a,'Frame'); wolffd@0: % Perceived dynamics: spectral slope? wolffd@0: wolffd@0: % RHYTHM wolffd@0: % ------ wolffd@0: wolffd@0: r.fluctuation = mirstruct; wolffd@0: r.fluctuation.tmp.f = mirfluctuation(a,'Summary'); wolffd@0: r.fluctuation.peak = mirpeaks(r.fluctuation.tmp.f,'Total',1);%only one? wolffd@0: r.fluctuation.centroid = mircentroid(r.fluctuation.tmp.f); wolffd@0: wolffd@0: r.rhythm = mirstruct; wolffd@0: r.rhythm.tmp.onsets = mironsets(a); wolffd@0: wolffd@0: %r.rhythm.eventdensity = ... wolffd@0: wolffd@0: r.rhythm.tempo = mirtempo(r.rhythm.tmp.onsets,'Frame'); wolffd@0: %r.rhythm.pulseclarity = mirpulseclarity(r.tmp.onsets,'Frame'); wolffd@0: % Should use the second output of mirtempo. wolffd@0: wolffd@0: attacks = mironsets(r.rhythm.tmp.onsets,'Attacks'); wolffd@0: r.rhythm.attack.time = mirattacktime(attacks); wolffd@0: r.rhythm.attack.slope = mirattackslope(attacks); wolffd@0: wolffd@0: % TIMBRE wolffd@0: % ------ wolffd@0: wolffd@0: f = mirframe(a,.05,.5); wolffd@0: r.spectral = mirstruct; wolffd@0: r.spectral.tmp.s = mirspectrum(f); wolffd@0: %pitch = mirpitch(a,'Frame',.05,.5); wolffd@0: wolffd@0: r.spectral.centroid = mircentroid(r.spectral.tmp.s); wolffd@0: r.spectral.brightness = mirbrightness(r.spectral.tmp.s); wolffd@0: r.spectral.spread = mirspread(r.spectral.tmp.s); wolffd@0: r.spectral.skewness = mirskewness(r.spectral.tmp.s); wolffd@0: r.spectral.kurtosis = mirkurtosis(r.spectral.tmp.s); wolffd@0: r.spectral.rolloff95 = mirrolloff(r.spectral.tmp.s,95); wolffd@0: r.spectral.rolloff85 = mirrolloff(r.spectral.tmp.s,85); wolffd@0: r.spectral.spectentropy = mirentropy(r.spectral.tmp.s); wolffd@0: r.spectral.flatness = mirflatness(r.spectral.tmp.s); wolffd@0: wolffd@0: r.spectral.roughness = mirroughness(r.spectral.tmp.s); wolffd@0: r.spectral.irregularity = mirregularity(r.spectral.tmp.s); wolffd@0: %r.spectral.inharmonicity = mirinharmonicity(r.spectral.tmp.s,'f0',pitch); wolffd@0: wolffd@0: r.spectral.mfcc = mirmfcc(r.spectral.tmp.s); wolffd@0: r.spectral.dmfcc = mirmfcc(r.spectral.mfcc,'Delta'); wolffd@0: r.spectral.ddmfcc = mirmfcc(r.spectral.dmfcc,'Delta'); wolffd@0: wolffd@0: r.timbre.zerocross = mirzerocross(f); wolffd@0: r.timbre.lowenergy = mirlowenergy(f); wolffd@0: r.timbre.spectralflux = mirflux(f); wolffd@0: wolffd@0: % PITCH wolffd@0: % ----- wolffd@0: wolffd@0: r.tonal = mirstruct; wolffd@0: r.tonal.tmp.chromagram = mirchromagram(a,'Frame','Wrap',0,'Pitch',0); wolffd@0: r.tonal.chromagram.peak=mirpeaks(r.tonal.tmp.chromagram,'Total',1); wolffd@0: r.tonal.chromagram.centroid=mircentroid(r.tonal.tmp.chromagram); wolffd@0: wolffd@0: % TONALITY/HARMONY wolffd@0: % ---------------- wolffd@0: wolffd@0: keystrengths = mirkeystrength(r.tonal.tmp.chromagram); wolffd@0: [k r.tonal.keyclarity] = mirkey(keystrengths,'Total',1); wolffd@0: %r.tonal.keyclarity = k{2}; wolffd@0: r.tonal.mode = mirmode(keystrengths); wolffd@0: r.tonal.hcdf = mirhcdf(r.tonal.tmp.chromagram); wolffd@0: wolffd@0: if stat wolffd@0: r = mirstat(r); wolffd@0: % SHOULD COMPUTE STAT OF CURVES FROM FRAMED_DECOMPOSED HIGH FEATURES wolffd@0: end wolffd@0: wolffd@0: if not(isa(x,'miraudio')) && not(isa(x,'mirdesign')) wolffd@0: r = mireval(r,x); wolffd@0: end wolffd@0: wolffd@0: wolffd@0: function [stat,nchan,segm,feat] = scanargin(v) wolffd@0: stat = 0; wolffd@0: nchan = 1; wolffd@0: segm = []; wolffd@0: feat = {}; wolffd@0: i = 1; wolffd@0: while i <= length(v) wolffd@0: arg = v{i}; wolffd@0: if ischar(arg) && strcmpi(arg,'Filterbank') wolffd@0: i = i+1; wolffd@0: if i <= length(v) wolffd@0: nchan = v{i}; wolffd@0: else wolffd@0: nchan = 10; wolffd@0: end wolffd@0: elseif ischar(arg) && strcmpi(arg,'Stat') wolffd@0: i = i+1; wolffd@0: if i <= length(v) wolffd@0: stat = v{i}; wolffd@0: else wolffd@0: stat = 1; wolffd@0: end wolffd@0: elseif ischar(arg) && strcmpi(arg,'Segment') wolffd@0: i = i+1; wolffd@0: if i <= length(v) wolffd@0: segm = v{i}; wolffd@0: else wolffd@0: segm = 1; wolffd@0: end wolffd@0: else wolffd@0: feat{end+1} = arg; wolffd@0: end wolffd@0: i = i+1; wolffd@0: end