Musical key detection for digital audio, GPL v3
C++ Other
Switch branches/tags
Latest commit f7df566 Jun 11, 2017 @EvanPurkhiser EvanPurkhiser committed with Include cstring for memset definition
Permalink
Failed to load latest commit information.
ci Add alpine linux based travis test Mar 24, 2017
tests Bring Mac SDKs up to date Mar 25, 2017
.gitignore Add alpine linux based travis test Mar 24, 2017
.travis.yml Add alpine linux based travis test Mar 24, 2017
LibKeyFinder.pro vbump Mar 25, 2017
README.md Add alpine linux based travis test Mar 24, 2017
audiodata.cpp Fix down-sampling shortcut Mar 25, 2017
audiodata.h Copyright dates May 27, 2015
binode.h Copyright dates May 27, 2015
chromagram.cpp Copyright dates May 27, 2015
chromagram.h Copyright dates May 27, 2015
chromatransform.cpp Copyright dates May 27, 2015
chromatransform.h Copyright dates May 27, 2015
chromatransformfactory.cpp Copyright dates May 27, 2015
chromatransformfactory.h Copyright dates May 27, 2015
constants.cpp Tone profiles v2.1 Jul 5, 2015
constants.h Copyright dates May 27, 2015
exception.h Copyright dates May 27, 2015
fftadapter.cpp Include cstring for memset definition Jun 11, 2017
fftadapter.h Copyright dates May 27, 2015
keyclassifier.cpp Copyright dates May 27, 2015
keyclassifier.h Copyright dates May 27, 2015
keyfinder.cpp Copyright dates May 27, 2015
keyfinder.h Copyright dates May 27, 2015
lowpassfilter.cpp Style from PR#20 Apr 9, 2016
lowpassfilter.h Fixed lowpassfilter's memory leak Feb 13, 2016
lowpassfilterfactory.cpp Copyright dates May 27, 2015
lowpassfilterfactory.h Copyright dates May 27, 2015
spectrumanalyser.cpp Copyright dates May 27, 2015
spectrumanalyser.h Copyright dates May 27, 2015
temporalwindowfactory.cpp Copyright dates May 27, 2015
temporalwindowfactory.h Copyright dates May 27, 2015
toneprofiles.cpp Copyright dates May 27, 2015
toneprofiles.h Copyright dates May 27, 2015
windowfunctions.cpp Copyright dates May 27, 2015
windowfunctions.h Copyright dates May 27, 2015
workspace.cpp Copyright dates May 27, 2015
workspace.h Copyright dates May 27, 2015

README.md

libKeyFinder

Build Status

libKeyFinder can be used to estimate the musical key of digital recordings.

It is the basis of the KeyFinder GUI app, which is available as a binary download for Mac OSX and Windows at www.ibrahimshaath.co.uk/keyfinder

Examples

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

// Static because it retains useful resources for repeat use
static KeyFinder::KeyFinder k;

// Build an empty audio object
KeyFinder::AudioData a;

// 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::KeyDetectionResult r =  k.keyOfAudio(a);

// And do something with the result
doSomethingWith(r.globalKeyEstimate);

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

KeyFinder::AudioData a;
a.setFrameRate(yourAudioStream.framerate);
a.setChannels(yourAudioStream.channels);
a.addToSampleCount(yourAudioStream.packetLength);

static KeyFinder::KeyFinder k;

// the workspace holds the memory allocations for analysis of a single track
KeyFinder::Workspace w;

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::KeyDetectionResult r = k.keyOfChromagram(w);
  doSomethingWithMostRecentKeyEstimate(r.globalKeyEstimate);
}

// to squeeze every last bit of audio from the working buffer...
k.finalChromagram(w);

// and finally...
KeyFinder::KeyDetectionResult r = k.keyOfChromagram(w);

doSomethingWithFinalKeyEstimate(r.globalKeyEstimate);

Installation

First, you will need to install libKeyFinder's dependencies:

  • FFTW version 3

    OSX and homebrew: $ brew install fftw

  • Qt 5

    libKeyFinder uses qmake, which is distributed with Qt, to generate Makefiles.

    OSX and homebrew: $ brew install qt5

    Note that the qt5 homebrew formula is keg-only, meaning that it is not linked into /usr/local automatically because it conflicts with earlier versions of qt which may already be installed. To link it forcefully so that it (along with qmake and others) can be used easily, run brew link qt5 --force.

Once dependencies are installed, build libKeyFinder:

$ qmake
$ make
$ make install

Testing

After having successfully installed the library following the above instructions, run the following commands to build and run the tests:

$ cd tests/
$ qmake
$ make
$ ./tests

If all goes well, you should see something like this:

===============================================================================
All tests passed (1705510 assertions in 65 test cases)

Note that there is a known intermittent failure in the FftAdapterTest/ForwardAndBackward test. Try running the tests a handful of times to determine whether you are hitting the intermittent or have introduced a new bug.