Closed Wall3rHM2 closed 5 years ago
First, you need to know the tick resolution from Pattern.resolution
, which is the resolution per beat (the smallest fraction of a beat in which events can happen). It is better to convert all the pattern to absolute ticks, as they are relative by default, using Pattern.make_ticks_abs()
. Then you have to iter through all events in all tracks to map all tempo events SetTempoEvent
s and then interpolate those changes.
It's not that easy if there are tempo changes in the file.
If you are lucky and only have one tempo event (or none, which means tempo is default, 120bpm) it's not that hard, as you can compute everything by dividing 60 by bpm and resolution just once; here's a simple example:
notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
#uncomment this if you want absolute time
#pattern.make_ticks_abs()
tickLength = None
for track in pattern:
for event in track:
if isinstance(event, midi.SetTempoEvent):
tickLength = 60. / event.bpm / pattern.resolution
break
else:
continue
break
else:
tickLength = .5 / pattern.resolution
def getSeconds(tick):
return tickLength * tick
for track in pattern:
for event in track:
if isinstance(event, midi.NoteEvent):
octave, note = divmod(event.pitch, 12)
print('Note {}{} plays at {:.02f} seconds'.format(
notes[note], octave, getSeconds(event.tick)))
Also, have a look at this: #62
Thank you very much, there was before an related issue in the original python-midi but i couldn't get help.
Can someone help me get a note at the time its suposed to play in reading a file? e.g: After 2 secs a C note plays then after 1 sec, a G note.