moltenform
Home
Previous: Audio
Previous: Audio
MIDI To Wav
MIDI To Wav
Next: UI Automation
Next: UI Automation

Bmidilib (a Python midi library)


Project page on GitHub

Overview

bmidilib.py, code for reading/creating midi files in Python
Ben Fisher, 2008. GPL.
Based originally on midi.py, placed into the public domain in December 2001 by Will Ware

To make a midi song, create a Builder object, and use its .note() method to add notes. By default, notes are added to the end of the song. However, the Builder object's current time can be moved backwards with the rewind() method. This is how to play many notes at once, as in a chord.

(This is an old project I wrote for fun in college.)

Bbuilder Examples

Bbuilder.py is a high-level interface for making Midi songs. Here are some demonstrations.
making a simple melody
    from bmidilib import bbuilder
    b = bbuilder.BMidiBuilder()
    b.note('c', 1) #pitch 60, duration 1 qtr note
    b.note('d', 1)
    b.note('e', 1)
    b.note('f', 1)
    b.note('g', 4)
    b.save('out.mid')

making a chord b = bbuilder.BMidiBuilder() b.note('c', 1) b.rewind() #automatically rewinds to start of last note b.note('e', 1) b.rewind() b.note('g', 1) b.save('out.mid') #doesn't "sort" the events until the end.

more options b = bbuilder.BMidiBuilder() b.tempo = 60 b.volume = 20 b.pan = 127 #out of right speaker b.setInstrument('flute') #looks up in list, until first match. b.setInstrument(73) also works b.note('c', 1, velocity=127) #velocity is the loudness of a particular note, 1-127

#ways to type same note:
b.note(61, 1)
b.note('c#', 1) #use sharps, not flats.
b.note('c#4', 1)

#octaves
b.note('c#5', 1)
b.note('c#6', 1)
b.save('out.mid')

advanced (2 tracks) tr1 = bbuilder.BMidiBuilder() tr1.setInstrument('fretless bass') tr1.note('c3', 2) tr1.note('d3', 2) tr1.note('e3', 2) tr1.rest(2) tr1.note('f3',2)

tr2 = bbuilder.BMidiBuilder()
tr2.setInstrument('ocarina')
tr2.note('e4', 2)
tr2.note('f4', 2)
tr2.note('g4', 2)
tr2.rest(2)
tr2.note('a4',2)

bbuilder.joinTracks( [tr1, tr2], 'out.mid')

advanced (inserting raw events) b = bbuilder.BMidiBuilder() b.tempo = 400 for i in range(127):

    #insert a raw instrument change event
    evt = bmidilib.BMidiEvent() #event time will be set when inserted
    evt.type='PROGRAM_CHANGE'
    evt.channel=1
    evt.data = i
    b.insertMidiEvent(evt)
    b.note('c3',0.4)
b.save('song2.mid')

Example reading

First, place the bmidilib directory in the directory containing the script.
from bmidilib import bmidilib

m = bmidilib.BMidiFile() m.open('mymidi.mid') m.read() m.close() print m #lists all of the events in a human-readable way

#loop through only the note events in 2nd track, and print out pitches and durations for note in m.tracks[1].notelist: print note.pitch, note.duration

Example writing

from bmidilib import bbuilder
b = bbuilder.BMidiBuilder()
b.note('c', 1)
b.note('d', 1)
b.note('e', 1)
b.note('f', 1)
b.note('g', 4)
b.save('out.mid')

Example writing (raw events)

# For creating midi files, bbuilder.py should be enough for everyday usage.
# this is an example in case you are trying to do something beyond bbuilder.

from bmidilib import bmidilib

file = bmidilib.BMidiFile() file.ticksPerQuarterNote = 120

tr = bmidilib.BMidiTrack() file.tracks.append(tr)

#note on event startevt = bmidilib.BMidiEvent() startevt.type = 'NOTE_ON' startevt.time = 0 startevt.channel = 1 startevt.pitch = 60 startevt.velocity = 80 tr.events.append(startevt)

#note off event (which is note_on with velocity 0) endevt = bmidilib.BMidiEvent() endevt.type = 'NOTE_ON' endevt.time = 120 endevt.channel = 1 endevt.pitch = 60 endevt.velocity = 0 tr.events.append(endevt)

evt = bmidilib.BMidiEvent() evt.type='END_OF_TRACK' evt.time = 500 evt.data = '' tr.events.append(evt)

file.open('out.mid', 'wb') file.write() file.close()

Class Hierarchy

BMidiFile
    BMidiTrack[] tracks

BMidiTrack BMidiEvent[] events BNote[] notelist Notes in a mid file consist of two events, a "NoteOn" and a later "NoteOff" The "notelist" provides a simpler view, as a single BNote object that has duration. (If you are creating a BMidiTrack yourself, you do not need to add to the notelist)

BMidiEvent Raw information about the midi event. Includes raw NoteOn and NoteOff events. Does not include "delta times" which are created automatically.

BNote Information including note, duration

- Modifying these instances will not actually modify the midi -
This is just an alternate view of information elsewhere
    So to change the pitch of a note, say, you have to have both
    note.startEvt.pitch = 60
    note.endEvt.pitch = 60
    note.pitch = 60

Bbuilder Documentation

Functions
    bbuilder.joinTracks(listTracks, outFilename)

Public Settings b.tempo b.volume b.pan

Public Methods b.note(pitch, duration) b.rest(duration) b.rewind(duration) b.setInstrument(instrument) b.save(outFilename)

Project page on GitHub

back