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()