Mercurial > hg > qm-dsp
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/TestGetKeyMode.cpp Thu May 23 13:29:02 2019 +0100 @@ -0,0 +1,113 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +#include "dsp/keydetection/GetKeyMode.h" + +#include <iostream> + +#include <cmath> + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN + +#include <boost/test/unit_test.hpp> + +BOOST_AUTO_TEST_SUITE(TestGetKeyMode) + +using std::cout; +using std::endl; +using std::string; +using std::vector; + +string keyName(int index, bool minor) +{ + static string namesMajor[] = { + "C", "Db", "D", "Eb", + "E", "F", "F# / Gb", "G", + "Ab", "A", "Bb", "B" + }; + + static string namesMinor[] = { + "C", "C#", "D", "Eb / D#", + "E", "F", "F#", "G", + "G#", "A", "Bb", "B" + }; + + if (index < 1 || index > 12) return ""; + + std::string name; + if (minor) name = namesMinor[index - 1] + " minor"; + else name = namesMajor[index - 1] + " major"; + return name; +} + +string midiPitchName(int midiPitch) +{ + static string names[] = { + "C", "C#", "D", "D#", + "E", "F", "F#", "G", + "G#", "A", "A#", "B" + }; + + return names[midiPitch % 12]; +} + +vector<double> generateSinusoid(double frequency, + int sampleRate, + int length) +{ + vector<double> buffer; + buffer.reserve(length); + for (int i = 0; i < length; ++i) { + buffer.push_back(sin(i * M_PI * 2.0 * frequency / sampleRate)); + } + return buffer; +} + +BOOST_AUTO_TEST_CASE(sinusoid_12tET) +{ + double concertA = 440.0; + int sampleRate = 44100; + + for (int midiPitch = 48; midiPitch < 96; ++midiPitch) { + + cout << endl; + + GetKeyMode gkm(sampleRate, concertA, 10, 10); + int blockSize = gkm.getBlockSize(); + int hopSize = gkm.getHopSize(); + cerr << "blockSize = " << blockSize + << ", hopSize = " << hopSize << endl; + + double frequency = concertA * pow(2.0, (midiPitch - 69.0) / 12.0); + cout << "midiPitch = " << midiPitch + << ", name = " << midiPitchName(midiPitch) + << ", frequency = " << frequency << endl; + + int blocks = 4; + int totalLength = blockSize * blocks; + vector<double> signal = generateSinusoid(frequency, sampleRate, + totalLength); + + int key; + + for (int offset = 0; offset + blockSize < totalLength; + offset += hopSize) { + int k = gkm.process(signal.data() + offset); + if (offset == 0) { + key = k; + } else { + BOOST_CHECK_EQUAL(key, k); + } + } + + bool minor = (key > 12); + + int tonic = key; + if (minor) tonic -= 12; + + string name = keyName(tonic, minor); + cout << "key value = " << key << ", name = " << name << endl; + } +} + +BOOST_AUTO_TEST_SUITE_END()