Find the most likely key/scale (currently Major/Minor only) from either:
- a dropped/uploaded
.mid/.midifile, or - a set of notes you pick manually (click the piano), including a computer-keyboard “piano mode”.
Live site: https://midi.hakono.me/
- You can upload a
.mid/.midifile, or build a note set by selecting notes on the piano (mouse/touch/keyboard). - It reduces notes to pitch classes (C…B) and estimates the most likely tonic + mode.
- It shows a ranked list of candidate Major/Minor keys, with a best guess highlighted.
This is meant for quick “what key is this in?” checks for melodies, chord progressions, or any small set of notes.
Everything runs client-side.
- Parse MIDI using the Tone.js MIDI parser (vendored as
Midi.js). - Build
noteWeights:pitchClass -> weight.- For MIDI upload: weight is total note duration across the whole file.
- For manual note selection: weights are neutral (all selected notes count equally).
- Score all 24 candidates (12 roots × Major/Minor):
- add points for notes that are inside the scale
- boost “important” degrees (tonic, dominant, subdominant, the mode-defining third)
- the boost values are tuned with
tune.jsto maximize accuracy on a small(!) labeled set of 640 chord progressions.
- the boost values are tuned with
- subtract a penalty for notes outside the scale (and an extra penalty for the “wrong” third)
- Sort by score and display the top result.
The “match %” shown in the UI means “how much of the input is inside the key” (by duration for MIDI, or by count for manual selection). It’s a descriptive metric, not a calibrated probability.
- Major/Minor only. No modes, harmonic/melodic minor, blues scales, etc.
- Relative major/minor can flip (same pitch set). The weighted scoring tries to pick a tonic.
- Key changes/modulation: it assumes one key for the whole file.
- MIDI with lots of chromatic passing tones, borrowed chords, or dense percussion can confuse it (it currently doesn’t ignore drums).
On a small labeled set (older internal test run), it reached about ~88% top-1 accuracy. More testing should be done.
This is a static site.
- Main UI:
index.html,script.js - Detection logic:
scaleDetector.js - MIDI parser:
Midi.js(from https://unpkg.com/@tonejs/midi@2.0.28/build/Midi.js)
Because the app uses ES modules (<script type="module">), you’ll usually want a local server (not file://). For example:
python -m http.serverThen open http://localhost:8000/.
test.htmlis an internal evaluator (and optional in-browser grid search tuner).- Filenames must contain key + mode, e.g.
C_Major.midorG#Minor_MyChords.mid.
- Filenames must contain key + mode, e.g.
tune.jsis a Node script used to grid-search the scoring multipliers offline.
- Allow connecting external MIDI keyboards as an input source (support Web MIDI API).