comparison DrumTimingLoader_OF/chromagramm/ChordDetect.cpp @ 0:82352cfc0b23

Added files from ISMIR groove drum timing work
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 01 Oct 2012 22:24:32 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:82352cfc0b23
1 /*
2 * ChordDetect.cpp
3 * ChordDetect
4 *
5 * Created by Adam Stark on 28/04/2008.
6 * Copyright 2008 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10 #include "ChordDetect.h"
11 #include <iostream>
12 #include <math.h>
13 using namespace std;
14
15 ChordDetect :: ChordDetect()
16 {
17
18 bias = 1.06;
19
20 makeprofiles();
21
22 }
23
24 //--------------------------------------------------------------------------------------
25 // destructor
26 ChordDetect :: ~ChordDetect()
27 {
28
29 }
30
31
32 //--------------------------------------------------------------------------------------
33 // main function to be called with 8192 sample frame at 11025 Hz
34 void ChordDetect :: C_Detect(float c[],float c_low[])
35 {
36 for (int i = 0;i < 12;i++)
37 {
38 chroma[i] = c[i];
39 chroma_low[i] = c_low[i];
40 }
41
42 calculateweightings();
43
44 classifychromagram();
45
46 //cout << root << " " << quality << " " << intervals << endl;
47 }
48
49 //--------------------------------------------------------------------------------------
50 // analyse the chromagram and assign it a root note, chord type and any features
51 void ChordDetect :: classifychromagram()
52 {
53 int i;
54 int j;
55 int fifth;
56 int chordindex;
57
58 // remove some of the 5th note energy from chromagram
59 for (i = 0;i < 12;i++)
60 {
61 fifth = (i+7) % 12;
62 chroma[fifth] = chroma[fifth] - (0.1*chroma[i]);
63
64 if (chroma[fifth] < 0)
65 {
66 chroma[fifth] = 0;
67 }
68
69 }
70
71
72 // major chords
73 for (j=0;j < 12;j++)
74 {
75 chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
76 }
77
78 // minor chords
79 for (j=12;j < 24;j++)
80 {
81 chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
82 }
83
84 // diminished 5th chords
85 for (j=24;j < 36;j++)
86 {
87 chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
88 }
89
90 // augmented 5th chords
91 for (j=36;j < 48;j++)
92 {
93 chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
94
95 chord[j] = chord[j] / weight_aug[j-36];
96 }
97
98 // sus2 chords
99 for (j=48;j < 60;j++)
100 {
101 chord[j] = calcchordvalue(chroma,profiles[j],1,3);
102
103 chord[j] = chord[j] / weight_sus[j-48];
104 }
105
106 // sus4 chords
107 for (j=60;j < 72;j++)
108 {
109 chord[j] = calcchordvalue(chroma,profiles[j],1,3);
110
111 chord[j] = chord[j] / weight_sus[j-60];
112 }
113
114 // major 7th chords
115 for (j=72;j < 84;j++)
116 {
117 chord[j] = calcchordvalue(chroma,profiles[j],1,4);
118 }
119
120 // minor 7th chords
121 for (j=84;j < 96;j++)
122 {
123 chord[j] = calcchordvalue(chroma,profiles[j],bias,4);
124 }
125
126 // dominant 7th chords
127 for (j=96;j < 108;j++)
128 {
129 chord[j] = calcchordvalue(chroma,profiles[j],bias,4);
130 }
131
132 chordindex = minindex(chord,108);
133
134 // major
135 if (chordindex < 12)
136 {
137 root = chordindex;
138 quality = 1;
139 intervals = 0;
140 }
141
142 // minor
143 if ((chordindex >= 12) && (chordindex < 24))
144 {
145 root = chordindex-12;
146 quality = 0;
147 intervals = 0;
148 }
149
150 // diminished 5th
151 if ((chordindex >= 24) && (chordindex < 36))
152 {
153 root = chordindex-24;
154 quality = 4;
155 intervals = 0;
156 }
157
158 // augmented 5th
159 if ((chordindex >= 36) && (chordindex < 48))
160 {
161 root = chordindex-36;
162 quality = 6;
163 intervals = 0;
164 }
165
166 // sus2
167 if ((chordindex >= 48) && (chordindex < 60))
168 {
169 root = chordindex-48;
170 quality = 2;
171 intervals = 2;
172 }
173
174 // sus4
175 if ((chordindex >= 60) && (chordindex < 72))
176 {
177 root = chordindex-60;
178 quality = 2;
179 intervals = 4;
180 }
181
182 // major 7th
183 if ((chordindex >= 72) && (chordindex < 84))
184 {
185 root = chordindex-72;
186 quality = 1;
187 intervals = 7;
188 }
189
190 // minor 7th
191 if ((chordindex >= 84) && (chordindex < 96))
192 {
193 root = chordindex-84;
194 quality = 0;
195 intervals = 7;
196 }
197
198 // dominant 7th
199 if ((chordindex >= 96) && (chordindex < 108))
200 {
201 root = chordindex-96;
202 quality = 2;
203 intervals = 7;
204 }
205 }
206
207 //--------------------------------------------------------------------------------------
208 // calculate weightings to help distinguish between sus2/sus4 and aug chords
209 void ChordDetect :: calculateweightings()
210 {
211 int i;
212 float maxval = 0;
213 int fifth;
214 int augfifth;
215
216 maxval = max(chroma_low,12);
217
218 // normalise chroma low
219 for (i = 0;i < 12;i++)
220 {
221 chroma_low[i] = chroma_low[i] / maxval;
222 }
223
224 // make weight for sus chords
225 for (i = 0;i < 12;i++)
226 {
227 fifth = i+7;
228 augfifth = i+8;
229
230 if (fifth >= 12)
231 {
232 fifth = fifth-12;
233 }
234
235 if (augfifth >= 12)
236 {
237 augfifth = augfifth-12;
238 }
239
240 weight_sus[i] = chroma_low[i] + (chroma_low[fifth]/2);
241 weight_aug[i] = chroma_low[i] + (chroma_low[augfifth]/2);
242 }
243
244 maxval = max(weight_sus,12);
245 // normalise weight_sus
246 for (i = 0;i < 12;i++)
247 {
248 weight_sus[i] = weight_sus[i] / maxval;
249 }
250
251 maxval = max(weight_aug,12);
252 // normalise weight_aug
253 for (i = 0;i < 12;i++)
254 {
255 weight_aug[i] = weight_aug[i] / maxval;
256 }
257
258
259 }
260
261
262 //--------------------------------------------------------------------------------------
263 // return delta value indicating how similar the chroma is to the chord template - lower value = more similar
264 float ChordDetect :: calcchordvalue(float c[],float T[],float biasval, float N)
265 {
266 float sum = 0;
267 float delta;
268
269 for (int i=0;i < 12;i++)
270 {
271 sum = sum + ((1-T[i])*(pow(c[i],2)));
272 }
273
274 delta = sqrt(sum) / ((12 - N)*biasval);
275
276 return delta;
277 }
278
279
280 //--------------------------------------------------------------------------------------
281 // returns max value of an array
282 float ChordDetect :: max(float array[],int length)
283 {
284 float max = 0;
285
286 for (int i=0;i < length;i++)
287 {
288 if (array[i] > max)
289 {
290 max = array[i];
291 }
292 }
293
294 return max;
295 }
296
297 //--------------------------------------------------------------------------------------
298 // returns index of minimum value of array
299 int ChordDetect :: minindex(float array[],int length)
300 {
301 float min = 10000;
302 int minindex = 0;
303 int i;
304
305 for (i = 0;i < length;i++)
306 {
307 if (array[i] < min)
308 {
309 min = array[i];
310 minindex = i;
311 }
312 }
313
314 return minindex;
315 }
316
317 //--------------------------------------------------------------------------------------
318 // calculates bit mask chord profiles
319 void ChordDetect :: makeprofiles()
320 {
321 int i;
322 int t;
323 int j = 0;
324 int root;
325 int third;
326 int fifth;
327 int seventh;
328
329 float v1 = 1;
330 float v2 = 1;
331 float v3 = 1;
332
333 // set profiles matrix to all zeros
334 for (j = 0;j < 108;j++)
335 {
336 for (t = 0;t < 12;t++)
337 {
338 profiles[j][t] = 0;
339 }
340 }
341
342 // reset j to zero to begin creating profiles
343 j = 0;
344
345 // major chords
346 for (i = 0;i < 12;i++)
347 {
348 root = i % 12;
349 third = (i+4) % 12;
350 fifth = (i+7) % 12;
351
352 profiles[j][root] = v1;
353 profiles[j][third] = v2;
354 profiles[j][fifth] = v3;
355
356 j++;
357 }
358
359 // minor chords
360 for (i = 0;i < 12;i++)
361 {
362 root = i % 12;
363 third = (i+3) % 12;
364 fifth = (i+7) % 12;
365
366 profiles[j][root] = v1;
367 profiles[j][third] = v2;
368 profiles[j][fifth] = v3;
369
370 j++;
371 }
372
373 // diminished chords
374 for (i = 0;i < 12;i++)
375 {
376 root = i % 12;
377 third = (i+3) % 12;
378 fifth = (i+6) % 12;
379
380 profiles[j][root] = v1;
381 profiles[j][third] = v2;
382 profiles[j][fifth] = v3;
383
384 j++;
385 }
386
387 // augmented chords
388 for (i = 0;i < 12;i++)
389 {
390 root = i % 12;
391 third = (i+4) % 12;
392 fifth = (i+8) % 12;
393
394 profiles[j][root] = v1;
395 profiles[j][third] = v2;
396 profiles[j][fifth] = v3;
397
398 j++;
399 }
400
401 // sus2 chords
402 for (i = 0;i < 12;i++)
403 {
404 root = i % 12;
405 third = (i+2) % 12;
406 fifth = (i+7) % 12;
407
408 profiles[j][root] = v1;
409 profiles[j][third] = v2;
410 profiles[j][fifth] = v3;
411
412 j++;
413 }
414
415 // sus4 chords
416 for (i = 0;i < 12;i++)
417 {
418 root = i % 12;
419 third = (i+5) % 12;
420 fifth = (i+7) % 12;
421
422 profiles[j][root] = v1;
423 profiles[j][third] = v2;
424 profiles[j][fifth] = v3;
425
426 j++;
427 }
428
429 // major 7th chords
430 for (i = 0;i < 12;i++)
431 {
432 root = i % 12;
433 third = (i+4) % 12;
434 fifth = (i+7) % 12;
435 seventh = (i+11) % 12;
436
437 profiles[j][root] = v1;
438 profiles[j][third] = v2;
439 profiles[j][fifth] = v3;
440 profiles[j][seventh] = v3;
441
442 j++;
443 }
444
445 // minor 7th chords
446 for (i = 0;i < 12;i++)
447 {
448 root = i % 12;
449 third = (i+3) % 12;
450 fifth = (i+7) % 12;
451 seventh = (i+10) % 12;
452
453 profiles[j][root] = v1;
454 profiles[j][third] = v2;
455 profiles[j][fifth] = v3;
456 profiles[j][seventh] = v3;
457
458 j++;
459 }
460
461 // dominant 7th chords
462 for (i = 0;i < 12;i++)
463 {
464 root = i % 12;
465 third = (i+4) % 12;
466 fifth = (i+7) % 12;
467 seventh = (i+10) % 12;
468
469 profiles[j][root] = v1;
470 profiles[j][third] = v2;
471 profiles[j][fifth] = v3;
472 profiles[j][seventh] = v3;
473
474 j++;
475 }
476 }