Search code examples
pythonmidimusic21

Identifying time signature with music21


I'm trying to determine the time signature of a midi file in Python using music21. I can obtain the time signature of this sample midi for instance with:

import music21

path = 'ambrosia.midi'
score = music21.converter.parse(path)
time_signature = score.parts[0].timeSignature.ratioString

However, when I pass this midi instead, score.parts[0].timeSignature is None. Do others know the proper way to obtain the time signature with music21?


Solution

  • music21 v.7.1 started making measures in parts parsed from MIDI files. For that reason, the .timeSignature property is not very useful when called on a Part (example from docs: "This property is not recursive, so a Part will not have the time signature of the measure within it"). The fact that this used to work for MIDI files was inconsistent with the rest of the system.

    If you just want the first time signature, perform a recursive search:

    Old syntax (still works): myPart.recurse().getElementsByClass(music21.meter.TimeSignature)[0]

    New shortcut syntax (v7): myPart[music21.meter.TimeSignature][0]

    Equivalently, you can use strings such as 'TimeSignature' in the getter instead of class names.

    You could also index into the first measure and access the .timeSignature property there: myPart['Measure'][0].timeSignature.