Skip to content

Instantly share code, notes, and snippets.

@SpotlightKid
Created July 9, 2021 20:57
Show Gist options
  • Save SpotlightKid/6562fa12db517efc70ab4ccfb16de6ae to your computer and use it in GitHub Desktop.
Save SpotlightKid/6562fa12db517efc70ab4ccfb16de6ae to your computer and use it in GitHub Desktop.
Show basic tempo and time/key signature information of a standard MIDI file using miditk-smf
import sys
from miditk.smf.reader import MidiFileReader
from miditk.smf.sequence import MidiSequence, ObjectMidiEventHandler
# This defines callbacks called while parsing the MIDI sequence
# We only need to overwrite the event handlers we want to handle specially
class MySequenceHandler(ObjectMidiEventHandler):
def __init__(self, instance=None, debug=False):
super().__init__(instance, debug)
instance.tempo_map = []
instance.time_signature_map = []
instance.key_signature_map = []
def tempo(self, value):
"""Handle tempo change events."""
bpm = 60000000.0 / value
ms_per_quarter = value / 1000.0
self._instance.tempo_map.append((self.current_time, (bpm, ms_per_quarter)))
def time_signature(self, nn, dd, cc, bb):
"""Handle time signature change events."""
self._instance.time_signature_map.append((self.current_time, (nn, dd**2)))
def key_signature(self, sf, mi):
"""Handle key signature change events."""
self._instance.key_signature_map.append((self.current_time, (sf, mi)))
def main():
filename = sys.argv[1]
seq = MidiSequence()
reader = MidiFileReader(filename, MySequenceHandler(seq, debug=True))
reader.read()
print(seq)
print("PPQN:", seq.tick_division)
print("Tempo changes:")
for time, tempo in seq.tempo_map:
print(time, tempo)
print("Time signature changes:")
for time, tempsig in seq.time_signature_map:
print(time, tempsig)
print("Key signature changes:")
for time, keysig in seq.key_signature_map:
print(time, keysig)
if __name__ == '__main__':
sys.exit(main() or 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment