Mercurial > hg > qm-dsp
comparison tests/TestGetKeyMode.cpp @ 451:3f913390bcf2
(Incomplete) unit tests for chroma and key estimation
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 23 May 2019 13:29:02 +0100 |
parents | |
children | dd132354ea02 |
comparison
equal
deleted
inserted
replaced
446:4852840b8a3c | 451:3f913390bcf2 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #include "dsp/keydetection/GetKeyMode.h" | |
4 | |
5 #include <iostream> | |
6 | |
7 #include <cmath> | |
8 | |
9 #define BOOST_TEST_DYN_LINK | |
10 #define BOOST_TEST_MAIN | |
11 | |
12 #include <boost/test/unit_test.hpp> | |
13 | |
14 BOOST_AUTO_TEST_SUITE(TestGetKeyMode) | |
15 | |
16 using std::cout; | |
17 using std::endl; | |
18 using std::string; | |
19 using std::vector; | |
20 | |
21 string keyName(int index, bool minor) | |
22 { | |
23 static string namesMajor[] = { | |
24 "C", "Db", "D", "Eb", | |
25 "E", "F", "F# / Gb", "G", | |
26 "Ab", "A", "Bb", "B" | |
27 }; | |
28 | |
29 static string namesMinor[] = { | |
30 "C", "C#", "D", "Eb / D#", | |
31 "E", "F", "F#", "G", | |
32 "G#", "A", "Bb", "B" | |
33 }; | |
34 | |
35 if (index < 1 || index > 12) return ""; | |
36 | |
37 std::string name; | |
38 if (minor) name = namesMinor[index - 1] + " minor"; | |
39 else name = namesMajor[index - 1] + " major"; | |
40 return name; | |
41 } | |
42 | |
43 string midiPitchName(int midiPitch) | |
44 { | |
45 static string names[] = { | |
46 "C", "C#", "D", "D#", | |
47 "E", "F", "F#", "G", | |
48 "G#", "A", "A#", "B" | |
49 }; | |
50 | |
51 return names[midiPitch % 12]; | |
52 } | |
53 | |
54 vector<double> generateSinusoid(double frequency, | |
55 int sampleRate, | |
56 int length) | |
57 { | |
58 vector<double> buffer; | |
59 buffer.reserve(length); | |
60 for (int i = 0; i < length; ++i) { | |
61 buffer.push_back(sin(i * M_PI * 2.0 * frequency / sampleRate)); | |
62 } | |
63 return buffer; | |
64 } | |
65 | |
66 BOOST_AUTO_TEST_CASE(sinusoid_12tET) | |
67 { | |
68 double concertA = 440.0; | |
69 int sampleRate = 44100; | |
70 | |
71 for (int midiPitch = 48; midiPitch < 96; ++midiPitch) { | |
72 | |
73 cout << endl; | |
74 | |
75 GetKeyMode gkm(sampleRate, concertA, 10, 10); | |
76 int blockSize = gkm.getBlockSize(); | |
77 int hopSize = gkm.getHopSize(); | |
78 cerr << "blockSize = " << blockSize | |
79 << ", hopSize = " << hopSize << endl; | |
80 | |
81 double frequency = concertA * pow(2.0, (midiPitch - 69.0) / 12.0); | |
82 cout << "midiPitch = " << midiPitch | |
83 << ", name = " << midiPitchName(midiPitch) | |
84 << ", frequency = " << frequency << endl; | |
85 | |
86 int blocks = 4; | |
87 int totalLength = blockSize * blocks; | |
88 vector<double> signal = generateSinusoid(frequency, sampleRate, | |
89 totalLength); | |
90 | |
91 int key; | |
92 | |
93 for (int offset = 0; offset + blockSize < totalLength; | |
94 offset += hopSize) { | |
95 int k = gkm.process(signal.data() + offset); | |
96 if (offset == 0) { | |
97 key = k; | |
98 } else { | |
99 BOOST_CHECK_EQUAL(key, k); | |
100 } | |
101 } | |
102 | |
103 bool minor = (key > 12); | |
104 | |
105 int tonic = key; | |
106 if (minor) tonic -= 12; | |
107 | |
108 string name = keyName(tonic, minor); | |
109 cout << "key value = " << key << ", name = " << name << endl; | |
110 } | |
111 } | |
112 | |
113 BOOST_AUTO_TEST_SUITE_END() |