Skip to content

Instantly share code, notes, and snippets.

@udf
Last active February 5, 2017 19:00
Show Gist options
  • Save udf/1feea5cf54744a605eaeb18a2179d039 to your computer and use it in GitHub Desktop.
Save udf/1feea5cf54744a605eaeb18a2179d039 to your computer and use it in GitHub Desktop.
Code to "flip" a midi file as in this video: https://www.youtube.com/watch?v=4IAZY7JdSHU
# midi library is from here: https://github.com/vishnubob/python-midi
import midi
import sys
import os
if len(sys.argv) != 2:
print "Usage: {0} <midifile>".format(sys.argv[0])
sys.exit(2)
midifile = sys.argv[1]
p = midi.read_midifile(midifile)
highest_note = 0
lowest_note = 127
# loop through each track
for x in xrange(0,len(p)):
# find the highest and lowest note
for y in xrange(0,len(p[x])):
if p[x][y].name == "Note Off" or p[x][y].name == "Note On":
if p[x][y].data[0] > highest_note:
highest_note = p[x][y].data[0]
if p[x][y].data[0] < lowest_note:
lowest_note = p[x][y].data[0]
# The current highest note will be the new minimum, so we need to shift (high-low)/12 octaves
shift = int(round((highest_note - lowest_note)/12.0)*12)
for x in xrange(0,len(p)):
# flip all the notes and move them down shift notes (so the range is closest to the original range)
# idk if this is how music should work but it seems to work well enough
for y in xrange(0,len(p[x])):
if p[x][y].name == "Note Off" or p[x][y].name == "Note On":
p[x][y].data[0] = highest_note + highest_note - p[x][y].data[0] - shift
fn, fe = os.path.splitext(sys.argv[1])
midi.write_midifile(fn + "_flipped" + fe, p)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment