Tempo and key are both in the audio, and both can be measured rather than guessed. Tempo is the easy one: one free command gets it to within a fraction of a beat. Key is harder, and the usual mistake is not a wrong answer but a neighbouring one (the relative minor, or half the tempo), so whatever you use, it helps to know what those look like.
One drop gives the key, its Camelot code, the keys that mix with it, and the tempo.
For tempo, one command. On Debian or Ubuntu:
sudo apt install aubio-tools
aubio tempo beat-128-cmaj.wav
128.61 bpm
The file is a test track at 128.37 BPM. aubio read both WAV and MP3 here (on the MP3 it also printed two harmless decoder lines). aubio is in Homebrew too; the runs here used the Debian package, version 0.4.9. It has no key detection.
The key, on your own machine
There is no small command for key. The two free routes that work are a Python library and a DJ app.
Essentia (from the Music Technology Group in Barcelona, AGPL) has a key
extractor and a beat tracker. After pip install essentia, this script prints
both:
import sys
import essentia.standard as es
audio = es.MonoLoader(filename=sys.argv[1])()
bpm = es.RhythmExtractor2013(method="multifeature")(audio)[0]
key, scale, strength = es.KeyExtractor()(audio)
print(f"{bpm:.1f} BPM, {key} {scale} (strength {strength:.2f})")
$ python keytempo.py dnb-174-aminor.wav
172.3 BPM, A minor (strength 0.92)
$ python keytempo.py melody.mp3
120.1 BPM, C major (strength 0.97)
That was Essentia 2.1b6.dev1389 on Python 3.12, x86-64 Linux. On 64-bit ARM Linux, pip found no ready-made package and the build from source failed, so check it installs on your machine before you plan around it.
Mixxx is a free, open-source DJ app for Windows, macOS and Linux. It analyses the BPM and key of the tracks in its library, and its Key Detection preferences set how keys are displayed in the library. If you DJ, the app you already use (Rekordbox, Serato, Traktor) probably detects both too. We didn't test any of them here.
libkeyfinder, the open-source key detector from the KeyFinder project, is in Homebrew, but its
command-line front end keyfinder-cli is in neither Debian nor Homebrew. You
would build it yourself.
What each route said
Four test tracks with a known tempo and key, synthesised so the right answer is not a matter of opinion. The last one is Am, F, C, G over and over: the same seven notes as C major, the classic trap.
| Track (truth) | aubio tempo |
bpm (bpm-tools) |
Essentia | Our tools |
|---|---|---|---|---|
| 128.37 BPM, C major | 128.61 | 128.332 | 128.3, C major | 128.4, C major (8B) |
| 120 BPM, C major | 116.33 | 119.971 | 120.1, C major | 120.0, C major (8B) |
| 174 BPM, A minor | 174.61 | 145.895 | 172.3, A minor | 87.0 (or 173.1), A minor (8A) |
| 128 BPM, Am F C G | 128.30 | 128.170 | 127.9, C major | 128.0, C major (8B) |
Our column is the tools' own analysis code (resources/tools/shared/audio),
run under Node on the same files. bpm is from bpm-tools 0.3, fed by sox:
sox track.wav -t raw -r 44100 -e float -c 1 - | bpm
Two things stand out. Everyone got the clean 128 and 120 tracks within a beat, except aubio's 116.33 on the 12-second one: short files give the tracker little to work with. And every route disagreed somewhere on the 174 track, which is the next section.
Half tempo, double tempo
A drum pattern repeats at the beat, at twice the beat and at the bar, and the audio fits all of them. Nothing in the signal says which one a listener taps. Drum'n'bass at 174 and its half-time feel at 87 are the same recording.
So every detector has a range it prefers, and the answer depends on it:
- bpm-tools only looks between 84 and 146 BPM by default. On the 174 track it
returned 145.895, which is neither. With
bpm -m 120 -x 200it said 178.501: the right level, still 4.5 BPM out. - Our BPM Detector leans towards 120, so it reported 87.0 and showed or 173.1 next to it. With Slowest tempo set to 120 under Tempo range, it reported 174.0.
- aubio said 174.61 and Essentia 172.3, without being asked.
The tempo, the other level it could be, and a grid you can check by ear.
The fix is the same everywhere: decide which level you mean, then tell the tool. In the BPM Detector:
- Open BPM Detector and drop the track in. MP3, WAV, FLAC, M4A, OGG and Opus work, and so does the sound of a video.
- Read Tempo. If a second number appears after or, that is the half or double reading.
- Press play. The lines of the beat grid should land on the kick drum. If they land on every other kick, or twice per kick, you have the other level.
- Under Half or double, pick the number you would tap. That redraws the grid at that level; the Tempo figure stays as measured.
- To make it measure the other level instead, narrow Tempo range, for example 120 to 210 for drum'n'bass. The analysis runs again on its own.
On a phone, Settings is a button at the bottom of the screen.
Under the tempo you may see "Two readings fit. Check the grid". It is shown whenever the two levels score close together, and in our tests it also appeared on the clean 128 BPM track. Trust the grid and your ears over the note.
Major or its relative minor
C major and A minor share all seven notes. What makes a song one or the other is which chord feels like home, and a key detector only hears how much of each note there is. On the Am, F, C, G track all four chords get equal time, and every key detector here said C major. That is a fair reading of an ambiguous track, not a fault. When we changed the chords to Am, Dm, E, Am, with the G sharp that only A minor uses, Essentia and the Key Finder both said A minor.
To settle it yourself, listen to the bass under the last chord of a chorus. If it lands on C, C major; on A, A minor.
For harmonic mixing it hardly matters. A major key and its relative minor have the same Camelot number (C major is 8B, A minor is 8A), and they mix into each other.
The Key Finder has a Key profile setting: Krumhansl–Kessler or Temperley. They are two templates of how much each note is used in a key. On these four tracks both gave the same key every time, so treat a change of profile as a second opinion on a close call, not a correction.
Reading the Camelot wheel
The wheel puts the 24 keys on a clock face so that the keys which mix are next to each other. One step clockwise is a fifth up. The inner ring (A) is minor, the outer ring (B) is major, and 8B is C major.
From any code there are three safe moves, and the Key Finder shades them:
- one number down, same letter (8B to 7B, F major)
- one number up, same letter (8B to 9B, G major)
- same number, other ring (8B to 8A, A minor)
Two more, two numbers either side, change the mood on purpose. Tick Show on the wheel under Energy-shift keys to see them.
Older records and some bands aren't tuned to A = 440 Hz. A track close to half a semitone sharp sits between two keys, and can read as the one above. The Key Finder measures the tuning first and shows it in cents. On our A minor track, tuned 23 and then 47 cents sharp, it measured 21 and 49 cents and still said A minor both times.
Without a file: tap along
For a record, the radio or a rehearsal, tap the beat.
Nine taps half a second apart read as just under 120 BPM.
- Open Tap Tempo.
- Tap the pad in time, or press Space or Enter. A tempo shows from the second tap.
- Keep going for six or more taps. It uses the median of your last eight intervals, so one late tap doesn't move it, and a tap that was well off is struck through and not counted.
It tells you nothing about the key. For that you need the audio.
Which to use
- You have a terminal and only need tempo:
aubio tempo. It was within 0.7 BPM on three of the four tracks and got the 174 right. - You need the key from your own machine, for a lot of files: Essentia, if it installs, or the DJ app you already use.
- One track, a laptop you can't install on, or a phone: the Key & Camelot Finder gives key, Camelot code and tempo in one go; the BPM Detector gives the tempo with a beat grid you can check by ear. Both run in the browser and don't upload the file.
- No file at all: Tap Tempo.
Whatever gave you the number, check it: play the track against the grid or your tapping, and listen for the home chord. Then write it into the track's tags, so you only do this once.