| wolffd@0 | 1 function r = mirfeatures(x,varargin) | 
| wolffd@0 | 2 %   f = mirfeatures(x) computes a large set of features from one or several | 
| wolffd@0 | 3 %       audio files. x can be either the name of an audio file, or the | 
| wolffd@0 | 4 %       'Folder' keyword. | 
| wolffd@0 | 5 %   mirfeatures(...,'Stat') returns the statistics of the features instead | 
| wolffd@0 | 6 %       of the complete features themselves. | 
| wolffd@0 | 7 %   mirfeatures(...,'Segment',t) segments the audio sequence at the | 
| wolffd@0 | 8 %       temporal positions indicated in the array t (in s.), and analyzes | 
| wolffd@0 | 9 %       each segment separately. | 
| wolffd@0 | 10 | 
| wolffd@0 | 11 %(not available yet) | 
| wolffd@0 | 12 %   mirfeatures(...,'Filterbank',nc) computes the analysis on each channel | 
| wolffd@0 | 13 %       of a filterbank decomposition. | 
| wolffd@0 | 14 %       Default value: nc = 5 | 
| wolffd@0 | 15 %   mirfeatures(...,'Frame',...) | 
| wolffd@0 | 16 %   mirfeatures(...,'Normal') | 
| wolffd@0 | 17 %   mirfeatures(...,'Sampling',s) | 
| wolffd@0 | 18 %   miraudio options (Extract, ...) | 
| wolffd@0 | 19 | 
| wolffd@0 | 20 [stat,nchan,segm,feat] = scanargin(varargin); | 
| wolffd@0 | 21 | 
| wolffd@0 | 22 if isa(x,'miraudio') || isa(x,'mirdesign') | 
| wolffd@0 | 23     a = miraudio(x,'Normal'); % normalize with respect to RMS energy | 
| wolffd@0 | 24                               % in order to consider timbre independently of | 
| wolffd@0 | 25                              % energy | 
| wolffd@0 | 26 else | 
| wolffd@0 | 27     a = miraudio('Design','Normal'); | 
| wolffd@0 | 28 end | 
| wolffd@0 | 29 | 
| wolffd@0 | 30 if not(isempty(segm)) | 
| wolffd@0 | 31     a = mirsegment(a,segm); | 
| wolffd@0 | 32 end | 
| wolffd@0 | 33 | 
| wolffd@0 | 34 | 
| wolffd@0 | 35 | 
| wolffd@0 | 36 % DYNAMICS | 
| wolffd@0 | 37 % -------- | 
| wolffd@0 | 38 | 
| wolffd@0 | 39 r.dynamics.rms = mirrms(a,'Frame'); | 
| wolffd@0 | 40 % Perceived dynamics: spectral slope? | 
| wolffd@0 | 41 | 
| wolffd@0 | 42 % RHYTHM | 
| wolffd@0 | 43 % ------ | 
| wolffd@0 | 44 | 
| wolffd@0 | 45 r.fluctuation = mirstruct; | 
| wolffd@0 | 46 r.fluctuation.tmp.f = mirfluctuation(a,'Summary'); | 
| wolffd@0 | 47 r.fluctuation.peak = mirpeaks(r.fluctuation.tmp.f,'Total',1);%only one? | 
| wolffd@0 | 48 r.fluctuation.centroid = mircentroid(r.fluctuation.tmp.f); | 
| wolffd@0 | 49 | 
| wolffd@0 | 50 r.rhythm = mirstruct; | 
| wolffd@0 | 51 r.rhythm.tmp.onsets = mironsets(a); | 
| wolffd@0 | 52 | 
| wolffd@0 | 53 %r.rhythm.eventdensity = ... | 
| wolffd@0 | 54 | 
| wolffd@0 | 55 r.rhythm.tempo = mirtempo(r.rhythm.tmp.onsets,'Frame'); | 
| wolffd@0 | 56 %r.rhythm.pulseclarity = mirpulseclarity(r.tmp.onsets,'Frame'); | 
| wolffd@0 | 57     % Should use the second output of mirtempo. | 
| wolffd@0 | 58 | 
| wolffd@0 | 59 attacks = mironsets(r.rhythm.tmp.onsets,'Attacks'); | 
| wolffd@0 | 60 r.rhythm.attack.time = mirattacktime(attacks); | 
| wolffd@0 | 61 r.rhythm.attack.slope = mirattackslope(attacks); | 
| wolffd@0 | 62 | 
| wolffd@0 | 63 % TIMBRE | 
| wolffd@0 | 64 % ------ | 
| wolffd@0 | 65 | 
| wolffd@0 | 66 f = mirframe(a,.05,.5); | 
| wolffd@0 | 67 r.spectral = mirstruct; | 
| wolffd@0 | 68 r.spectral.tmp.s = mirspectrum(f); | 
| wolffd@0 | 69 %pitch = mirpitch(a,'Frame',.05,.5); | 
| wolffd@0 | 70 | 
| wolffd@0 | 71 r.spectral.centroid = mircentroid(r.spectral.tmp.s); | 
| wolffd@0 | 72 r.spectral.brightness = mirbrightness(r.spectral.tmp.s); | 
| wolffd@0 | 73 r.spectral.spread = mirspread(r.spectral.tmp.s); | 
| wolffd@0 | 74 r.spectral.skewness = mirskewness(r.spectral.tmp.s); | 
| wolffd@0 | 75 r.spectral.kurtosis = mirkurtosis(r.spectral.tmp.s); | 
| wolffd@0 | 76 r.spectral.rolloff95 = mirrolloff(r.spectral.tmp.s,95); | 
| wolffd@0 | 77 r.spectral.rolloff85 = mirrolloff(r.spectral.tmp.s,85); | 
| wolffd@0 | 78 r.spectral.spectentropy = mirentropy(r.spectral.tmp.s); | 
| wolffd@0 | 79 r.spectral.flatness = mirflatness(r.spectral.tmp.s); | 
| wolffd@0 | 80 | 
| wolffd@0 | 81 r.spectral.roughness = mirroughness(r.spectral.tmp.s); | 
| wolffd@0 | 82 r.spectral.irregularity = mirregularity(r.spectral.tmp.s); | 
| wolffd@0 | 83 %r.spectral.inharmonicity = mirinharmonicity(r.spectral.tmp.s,'f0',pitch); | 
| wolffd@0 | 84 | 
| wolffd@0 | 85 r.spectral.mfcc = mirmfcc(r.spectral.tmp.s); | 
| wolffd@0 | 86 r.spectral.dmfcc = mirmfcc(r.spectral.mfcc,'Delta'); | 
| wolffd@0 | 87 r.spectral.ddmfcc = mirmfcc(r.spectral.dmfcc,'Delta'); | 
| wolffd@0 | 88 | 
| wolffd@0 | 89 r.timbre.zerocross = mirzerocross(f); | 
| wolffd@0 | 90 r.timbre.lowenergy = mirlowenergy(f); | 
| wolffd@0 | 91 r.timbre.spectralflux = mirflux(f); | 
| wolffd@0 | 92 | 
| wolffd@0 | 93 % PITCH | 
| wolffd@0 | 94 % ----- | 
| wolffd@0 | 95 | 
| wolffd@0 | 96 r.tonal = mirstruct; | 
| wolffd@0 | 97 r.tonal.tmp.chromagram = mirchromagram(a,'Frame','Wrap',0,'Pitch',0); | 
| wolffd@0 | 98 r.tonal.chromagram.peak=mirpeaks(r.tonal.tmp.chromagram,'Total',1); | 
| wolffd@0 | 99 r.tonal.chromagram.centroid=mircentroid(r.tonal.tmp.chromagram); | 
| wolffd@0 | 100 | 
| wolffd@0 | 101 % TONALITY/HARMONY | 
| wolffd@0 | 102 % ---------------- | 
| wolffd@0 | 103 | 
| wolffd@0 | 104 keystrengths = mirkeystrength(r.tonal.tmp.chromagram); | 
| wolffd@0 | 105 [k r.tonal.keyclarity] = mirkey(keystrengths,'Total',1); | 
| wolffd@0 | 106 %r.tonal.keyclarity = k{2}; | 
| wolffd@0 | 107 r.tonal.mode = mirmode(keystrengths); | 
| wolffd@0 | 108 r.tonal.hcdf = mirhcdf(r.tonal.tmp.chromagram); | 
| wolffd@0 | 109 | 
| wolffd@0 | 110 if stat | 
| wolffd@0 | 111     r = mirstat(r); | 
| wolffd@0 | 112     % SHOULD COMPUTE STAT OF CURVES FROM FRAMED_DECOMPOSED HIGH FEATURES | 
| wolffd@0 | 113 end | 
| wolffd@0 | 114 | 
| wolffd@0 | 115 if not(isa(x,'miraudio')) && not(isa(x,'mirdesign')) | 
| wolffd@0 | 116     r = mireval(r,x); | 
| wolffd@0 | 117 end | 
| wolffd@0 | 118 | 
| wolffd@0 | 119 | 
| wolffd@0 | 120 function [stat,nchan,segm,feat] = scanargin(v) | 
| wolffd@0 | 121 stat = 0; | 
| wolffd@0 | 122 nchan = 1; | 
| wolffd@0 | 123 segm = []; | 
| wolffd@0 | 124 feat = {}; | 
| wolffd@0 | 125 i = 1; | 
| wolffd@0 | 126 while i <= length(v) | 
| wolffd@0 | 127     arg = v{i}; | 
| wolffd@0 | 128     if ischar(arg) && strcmpi(arg,'Filterbank') | 
| wolffd@0 | 129         i = i+1; | 
| wolffd@0 | 130         if i <= length(v) | 
| wolffd@0 | 131             nchan = v{i}; | 
| wolffd@0 | 132         else | 
| wolffd@0 | 133             nchan = 10; | 
| wolffd@0 | 134         end | 
| wolffd@0 | 135     elseif ischar(arg) && strcmpi(arg,'Stat') | 
| wolffd@0 | 136         i = i+1; | 
| wolffd@0 | 137         if i <= length(v) | 
| wolffd@0 | 138             stat = v{i}; | 
| wolffd@0 | 139         else | 
| wolffd@0 | 140             stat = 1; | 
| wolffd@0 | 141         end | 
| wolffd@0 | 142     elseif ischar(arg) && strcmpi(arg,'Segment') | 
| wolffd@0 | 143         i = i+1; | 
| wolffd@0 | 144         if i <= length(v) | 
| wolffd@0 | 145             segm = v{i}; | 
| wolffd@0 | 146         else | 
| wolffd@0 | 147             segm = 1; | 
| wolffd@0 | 148         end | 
| wolffd@0 | 149     else | 
| wolffd@0 | 150         feat{end+1} = arg; | 
| wolffd@0 | 151     end | 
| wolffd@0 | 152     i = i+1; | 
| wolffd@0 | 153 end |