libKeyFinder
A small C++11 library for estimating the musical key of digital audio.
KeyFinder library

Introduction

libkeyfinder is a small C++11 library for estimating the musical key of digital audio. It is published under the GNU General Public License (GPL) version 3 or later.

It was written by Ibrahim Shaath who wrote it in 2011 as part of a master's thesis in computer science. A GUI application to use it is available for macOS and Windows, however that is no longer maintained and does not build on contemporary Linux distributions.

In 2020, Ibrahim handed over maintenance of libkeyfinder to the Mixxx DJ software team who incorporated it into Mixxx as of Mixxx 2.3. If you want to discuss anything related to libkeyfinder with us, please get in touch on the Mixxx Zulip chat. Contributions are welcome by opening pull requests and issues on GitHub.

Basic Example

For the most basic use case, do something like this:

// Static because it retains useful resources for repeat use
// Build an empty audio object
// Prepare the object for your audio stream
a.setFrameRate(yourAudioStream.framerate);
a.setChannels(yourAudioStream.channels);
a.addToSampleCount(yourAudioStream.length);
// Copy your audio into the object
for (int i = 0; i < yourAudioStream.length; i++) {
a.setSample(i, yourAudioStream[i]);
}
// Run the analysis
KeyFinder::key_t key = k.keyOfAudio(a);
// And do something with the result
doSomethingWith(key);
Definition: audiodata.h:29
Definition: keyfinder.h:33

Progressive Estimation Example

Alternatively, you can transform a stream of audio into a chromatic representation, and make progressive estimates of the key:

a.setFrameRate(yourAudioStream.framerate);
a.setChannels(yourAudioStream.channels);
a.addToSampleCount(yourAudioStream.packetLength);
// the workspace holds the memory allocations for analysis of a single track
while (someType yourPacket = newAudioPacket()) {
for (int i = 0; i < yourPacket.length; i++) {
a.setSample(i, yourPacket[i]);
}
k.progressiveChromagram(a, w);
// if you want to grab progressive key estimates...
KeyFinder::key_t key = k.keyOfChromagram(w);
doSomethingWithMostRecentKeyEstimate(key);
}
// if you only want a single key estimate, or to squeeze
// every last bit of audio from the working buffer after
// progressive estimates...
k.finalChromagram(w);
// and finally...
KeyFinder::key key = k.keyOfChromagram(w);
doSomethingWithFinalKeyEstimate(key);
Definition: workspace.h:32