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 |