score = music21.converter.parse('filename.mid')
key = score.analyze('key')
print(key.tonic.name, key.mode)

This gives the key and the mode of a given midi file. How can I get similar information on my own? How does the function analyze work?

And it gives the mode major and minor only. But there are more modes like Dorian, Mixolydian, etc. I want more than two modes. So, I want to know how the function works so that I can add those modes too. Any help?

  • 1
    Note, from the answers: If your goal is a programming challenge, great. If your goal is simply to determine the key and mode of a given piece of music, it will be far more effective, and in fact easier, to just learn the basics of harmonic analysis. Commented Jan 26, 2023 at 17:58

1 Answer 1


If you just were spend a little bit of effort reading the documentations you’d see that music21 uses the Krumhansl-Schmuckler algorithm for key detection with the Krumhansl-Kessler weights.

Basically this algorithm assigns to each chromatic step of a key a weight, representing how often we expect to find this particular note in this key. Each key will thus shift this set of weights. The algorithm then determines for each note the total duration of this note within the piece.

The key is then determined as the one where this set of durations and the theoretical weights have the highest correlation.

So basically it tries to math the key by how often we expect certain notes vs how often we actually have them.

Having minor and major then works by having different sets of weights for minor scales and major scales, and using the one that matches best.

This can of course easily extended to work with church modes, but it will lead to quite a few problems:

  • A mode is a feature of really old music and not the same as a key, which is a feature of more modern music. This is important as many concepts of modern music do not fit well with modes. So inherently this might make little sense.
  • You’d need to come up with weights for these modes, which would require a lot of research in modal music that might in fact not produce a resonable result
  • This algorithm is not particularly stable in the first place, adding lots of additional options will increase the chance of "accidental" matches and wrong classifications. It might just work well with two keys, but with two keys and 7 modes this would probably not produce usable results.

But if you like, try to extend the code. This stuff is defined here:


Add weights for church modes and stuff, and see if you get anything usable. The code itself states that the Krumhansl-Schmuckler weights have a tendency to output the dominant as tonic, so I doubt it. But feel free to try :)

  • Wow! I wonder whether the assumption is simply "the note that happens the most is the tonic." That's pretty easy to assault; "Twinkle twinkle little star" in C contains 4 Cs but 6 Gs. The verses of REM's "The end of the world as we know it" are almost entirely made of scale degree 5... even taking chords into account rather than just melodic line, I'm skeptical. I wonder whether there could be some positive results from something that trains an AI to take a more informed view of actual practice... Commented Jan 26, 2023 at 17:57
  • 3
    There's a whole field of research on key detection that you might read before bringing out your skepticism. Yes, Twinkle twinkle contains more dominant notes than tonic, but it also contains F-naturals and a proponderance of subdominant notes which would be rare in G major. It doesn't work for every piece and there are better algorithms but harder to implement. The weights are informed by actual practice. Commented Jan 26, 2023 at 18:14
  • 1
    @AndyBonner But we are not doing that! Let’s take your example of "Ah! vous diraj-je maman": This features c, d, e, f, g, a for 8, 8, 8, 8, 12, 4 quarters. If we take the Krumhansl-Schmuckler weights for c 6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88 we get a correlation of 0.86. If we shift them for g we get a correlation of only 0.68. If we do this for all shifts we get correlations of: c → 0.86, c# → -0.5, d → 0.28 → d# → -0.1, e → -0.26, f → 0.56, f# → -0.77, g → 0.68, g# → -0.31, a → -0.03, a# → 0.2, b → -0.61. Thus we get an order of most likely to least:
    – Lazy
    Commented Jan 26, 2023 at 19:23
  • @AndyBonner c g f d a# a d# e g# c# b f# with correlations 0.86, 0.68, 0.56, 0.28, 0.2, -0.03, -0.1, -0.26, -0.31, -0.5, -0.61, -0.77. So the algorithm would be quite sure that the key is C major, with other options being G major and F major. D major and A# major would be rather unlikely, A and D# even more so, and E, G#, C#, B, F# are quite certain not to be the tonic. If we instead use the minor weights we get the order d e a g c f b f# c# a# g# d# with correlations 0.53, 0.52, 0.48, 0.44, 0.29, 0.17, -0.06, -0.34, -0.35, -0.43, -0.58, -0.67.
    – Lazy
    Commented Jan 26, 2023 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.