Created
October 27, 2023 14:15
-
-
Save xavriley/c9cdd7bb910246a730a3dab6109237ef to your computer and use it in GitHub Desktop.
Add downbeats to midi using PrettyMIDI for use in Logic X
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pretty_midi as pm | |
import json | |
def get_syncpoint_downbeat_times(syncpoints): | |
downbeat_times = [] | |
for syncpoint in syncpoints: | |
if len(syncpoint) == 2 or syncpoint[2] == 0: | |
downbeat_times.append(syncpoint[1]) | |
return downbeat_times | |
def main(midi_file_path, syncpoints_file_path): | |
syncpoints = json.load(open(syncpoints_file_path)) | |
downbeat_times = get_syncpoint_downbeat_times(syncpoints) | |
midi_data = pm.PrettyMIDI(midi_file_path) | |
# resolution - 1024 for music21, 220 for Logic Pro X | |
output_midi = pm.PrettyMIDI(initial_tempo=120, resolution=1024) | |
guitar = pm.Instrument(program=25) | |
output_midi.instruments.append(guitar) | |
output_midi.time_signature_changes.append(pm.TimeSignature(4, 4, 0)) | |
first_db = syncpoints[0][1] | |
if first_db != 0: | |
# this would be the proper way to do it, but it blows up the tick resolution | |
# and the MIDI file won't save | |
# output_midi._tick_scales.append((0, (60/(first_db / 4))*output_midi.resolution)) | |
# output_midi._update_tick_to_time(int(pm.MAX_TICK)) | |
# so instead we just force the first downbeat to be at 0 | |
downbeat_times[0] = 0 | |
for (db, n_db) in zip(downbeat_times, downbeat_times[1:]): | |
if not n_db: | |
n_db = midi_data.get_end_time() | |
new_tempo = 60.0 / ((n_db - db) / 4) | |
output_midi._tick_scales.append( | |
(output_midi.time_to_tick(db), | |
60 / (new_tempo * output_midi.resolution))) | |
output_midi._update_tick_to_time(int(pm.MAX_TICK)) | |
# output_midi.time_signature_changes.append(pm.TimeSignature(4, 4, db)) | |
for instrument in midi_data.instruments: | |
for note in instrument.notes: | |
guitar.notes.append(note) | |
output_midi.write('mona-lisa-output.mid') | |
print("foo") | |
if __name__ == '__main__': | |
midi_file_path = 'mona-lisa-transcribed.mid' | |
syncpoints_file_path = 'mona-lisa-syncpoints.json' | |
main(midi_file_path, syncpoints_file_path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment