How can I write a MIDI file with Python?

Question:

I am writing a script to convert a picture into MIDI notes based on the RGBA values of the individual pixels. However, I cannot seem to get the last step working, which is to actually output the notes to a file.

I have tried using the MIDIUtil library, however its documentation is not the greatest and I can’t seem to figure it out.

If anyone could tell me how to sequence the notes (so that they don’t all begin at the beginning) it would be greatly appreciated.

Asked By: pstap92

||

Answers:

Looking at the sample, something like

from midiutil.MidiFile import MIDIFile

# create your MIDI object
mf = MIDIFile(1)     # only 1 track
track = 0   # the only track

time = 0    # start at the beginning
mf.addTrackName(track, time, "Sample Track")
mf.addTempo(track, time, 120)

# add some notes
channel = 0
volume = 100

pitch = 60           # C4 (middle C)
time = 0             # start on beat 0
duration = 1         # 1 beat long
mf.addNote(track, channel, pitch, time, duration, volume)

pitch = 64           # E4
time = 2             # start on beat 2
duration = 1         # 1 beat long
mf.addNote(track, channel, pitch, time, duration, volume)

pitch = 67           # G4
time = 4             # start on beat 4
duration = 1         # 1 beat long
mf.addNote(track, channel, pitch, time, duration, volume)

# write it to disk
with open("output.mid", 'wb') as outf:
    mf.writeFile(outf)
Answered By: Hugh Bothwell

I know this is an old post, but I’m the author of the library, and I wanted to mention that python 2 and 3 support have now been unified and with the demise of Google Code the code is now hosted on GitHub and can be installed via pip, ie:

pip install MIDIUtil

Documentation is available at Read The Docs.

(Tried to comment but I lacked the experience points.)

The end-of-track message is created automatically when the file is written to disk.

Answered By: Mark Wirt

For any one looking at this in 2023, also take a look at Computil package which makes generating midi files very easy:

# import the module
>>> import cu

# initialize the module
>>> cu.rt.init()

# create a single note
>>> c4 = cu.note(knum=60)

# and put it in a list and send it to the processor to play it
>>> cu.proc([c4])

# the full signature of the note function has the parameters:
# knum: the midi key number
# onset: is the ongoing time expressed in seconds, with respect to the process start time 0 (default is 0, which means now)
# dur: the duration of the note
# chnl: the midi channel to play the note on
# vel: the dynamic of the note

# now create a A minor chord with a duration of 2 seconds, 
# and play it 1 second after the processor starts
>>> a_min = cu.chord(knums=(69, 72, 76), onset=1, dur=2)

# and send it to the processor to play it
>>> cu.proc([a_min])

# now let us give the processor a list of notes/chords to play:
# the chromatic scale starting from the middle c upwards.
>>> voice = [cu.note(knum=60 + i, onset=i, dur=0.1) for i in range(12)]
>>> cu.proc([voice])

# playing polyphony is as easy as passing multiple lists of note/chords
# to the processor:
>>> voice1 = [cu.note(knum=60 + i, onset=i, dur=0.5) for i in range(12)]
>>> voice2 = [cu.note(knum=48 + i, onset=i + 0.5, dur=0.5) for i in range(12)]
>>> voice3 = [cu.chord(knums=[60+i, 60+i+4, 60+i+7], onset=i + 0.2, dur=0.5) for i in range(12)]

>>> cu.proc([voice1, voice2, voice3])

# If you want to write a midi file to the disk instead of playing it back
# pass a path string as the second argument to the processor
>>> cu.proc([voice1, voice2, voice3], "/tmp/my-polyphony.mid")
Answered By: Student
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.