Class Reference

class midiutil.MidiFile.MIDIFile(numTracks=1, removeDuplicates=True, deinterleave=True, adjust_origin=None, file_format=1)

A class that encapsulates a full, well-formed MIDI file object.

This is a container object that contains a header (MIDIHeader), one or more tracks (class:MIDITrack), and the data associated with a proper and well-formed MIDI file.

__init__(numTracks=1, removeDuplicates=True, deinterleave=True, adjust_origin=None, file_format=1)

Initialize the MIDIFile class

Parameters:
  • numTracks – The number of tracks the file contains. Integer, one or greater
  • removeDuplicates – If set to True remove duplicate events before writing to disk
  • deinterleave – If set to True deinterleave the notes in the stream
  • adjust_origin – If set to True (of left at the default of None) shift all the events in the tracks so that the first event takes place at time t=0
  • file_format – The format of the multi-track file. This should either be 1 (the default, and the most widely supported format) or 2.

Note that the default for adjust_origin will change in a future release, so one should probably explicitly set it.

Example:

# Create a two-track MIDIFile

from midiutil.MidiFile import MIDIFile
midi_file = MIDIFile(2)

In previous versions of this code the file written was format 2 (which can be thought of as a collection of independent tracks) but was identified as format 1. In this version one can specify either format 1 or 2.

In format 1 files there is a separate tempo track which contains tempo and time signature data, but contains no note data. If one creates a single track format 1 file the actual file has two tracks – one for tempo data and one for note data. In the track indexing the tempo track can be ignored. In other words track 0 is the note track (the second track in the file). However, tempo and time signature data will be written to the first, tempo track. This is done to try and preserve as much interoperability with previous versions as possible.

In a format 2 file all tracks are indexed and the track parameter is interpreted literally.

addControllerEvent(track, channel, time, controller_number, parameter)

Add a channel control event

Parameters:
  • track – The track to which the event is added.
  • channel – the MIDI channel to assign to the event. [Integer, 0-15]
  • time – The time (in beats) at which the event is placed [Float].
  • controller_number – The controller ID of the event.
  • parameter – The event’s parameter, the meaning of which varies by event type.
addCopyright(track, time, notice)

Add a copyright notice to the MIDIFile object

Parameters:
  • track – The track to which the notice is added.
  • time – The time (in beats) at which notice event is placed. In general this sould be time t=0
  • notice – The copyright notice [String]
addKeySignature(track, time, accidentals, accidental_type, mode, insertion_order=0)

Add a Key Signature to a track

Parameters:
  • track – The track to which this should be added
  • time – The time at which the signature should be placed
  • accidentals – The number of accidentals in the key signature
  • accidental_type – The type of accidental
  • mode – The mode of the scale

The easiest way to use this function is to make sure that the symbolic constants for accidental_type and mode are imported. By doing this:

from midiutil.MidiFile import *

one gets the following constants defined:

  • SHARPS
  • FLATS
  • MAJOR
  • MINOR

So, for example, if one wanted to create a key signature for a minor scale with three sharps:

MyMIDI.addKeySignature(0, 0, 3, SHARPS, MINOR)
addNote(track, channel, pitch, time, duration, volume, annotation=None)

Add notes to the MIDIFile object

Parameters:
  • track – The track to which the note is added.
  • channel – the MIDI channel to assign to the note. [Integer, 0-15]
  • pitch – the MIDI pitch number [Integer, 0-127].
  • time – the time (in beats) at which the note sounds [Float].
  • duration – the duration of the note (in beats) [Float].
  • volume – the volume (velocity) of the note. [Integer, 0-127].
  • annotation – Arbitrary data to attach to the note.

The annotation parameter attaches arbitrary data to the note. This is not used in the code, but can be useful anyway. As an example, I have created a project that uses MIDIFile to write csound orchestra files directly from the class EventList.

addProgramChange(track, channel, time, program)

Add a MIDI program change event.

Parameters:
  • track – The track to which program change event is added.
  • channel – the MIDI channel to assign to the event. [Integer, 0-15]
  • time – The time (in beats) at which the program change event is placed [Float].
  • program – the program number. [Integer, 0-127].
addSysEx(track, time, manID, payload)

Add a System Exclusive event.

Parameters:
  • track – The track to which the event should be written
  • time – The time of the event.
  • manID – The manufacturer ID for the event
  • payload – The payload for the event. This should be a binary-packed value, and will vary for each type and function.

Note: This is a low-level MIDI function, so care must be used in constructing the payload. It is recommended that higher-level helper functions be written to wrap this function and construct the payload if a developer finds him or herself using the function heavily.

addTempo(track, time, tempo)

Add notes to the MIDIFile object

Parameters:
  • track – The track to which the tempo event is added. Note that in a format 1 file this parameter is ignored and the temp is written to the tempo track
  • time – The time (in beats) at which tempo event is placed
  • tempo – The tempo, in Beats per Minute. [Integer]
addText(track, time, text)

Add a text event

Parameters:
  • track – The track to which the notice is added.
  • time – The time (in beats) at which text event is placed.
  • text – The text to adde [SASCII tring]
addTimeSignature(track, time, numerator, denominator, clocks_per_tick, notes_per_quarter=8)

Add a time signature event.

Parameters:
  • track – The track to which the signature is assigned. Note that in a format 1 file this parameter is ignored and the event is written to the tempo track
  • time – The time (in beats) at which the event is placed. In general this should probably be time 0 (the beginning of the track).
  • numerator – The numerator of the time signature. [Int]
  • denominator – The denominator of the time signature, expressed as a power of two (see below). [Int]
  • clocks_per_tick – The number of MIDI clock ticks per metronome click (see below).
  • notes_per_quarter – The number of annotated 32nd notes in a MIDI quarter note. This is almost always 8 (the default), but some sequencers allow this value to be changed. Unless you know that your sequencing software supports it, this should be left at its default value.

The data format for this event is a little obscure.

The denominator should be specified as a power of 2, with a half note being one, a quarter note being two, and eight note being three, etc. Thus, for example, a 4/4 time signature would have a numerator of 4 and a denominator of 2. A 7/8 time signature would be a numerator of 7 and a denominator of 3.

The clocks_per_tick argument specifies the number of clock ticks per metronome click. By definition there are 24 ticks in a quarter note, so a metronome click per quarter note would be 24. A click every third eighth note would be 3 * 12 = 36.

addTrackName(track, time, trackName)

Name a track.

Parameters:
  • track – The track to which the name is assigned.
  • time – The time (in beats) at which the track name event is placed. In general this should probably be time 0 (the beginning of the track).
  • trackName – The name to assign to the track [String]
addUniversalSysEx(track, time, code, subcode, payload, sysExChannel=127, realTime=False)

Add a Univeral System Exclusive event.

Parameters:
  • track – The track to which the event should be written
  • time – The time of the event, in beats.
  • code – The event code. [Integer]
  • subcode – The event sub-code [Integer]
  • payload – The payload for the event. This should be a binary-packed value, and will vary for each type and function.
  • sysExChannel – The SysEx channel.
  • realTime – Sets the real-time flag. Defaults to non-real-time.
  • manID – The manufacturer ID for the event

Note: This is a low-level MIDI function, so care must be used in constructing the payload. It is recommended that higher-level helper functions be written to wrap this function and construct the payload if a developer finds him or herself using the function heavily. As an example of such a helper function, see the changeNoteTuning() function, which uses the event to create a real-time note tuning update.

changeNoteTuning(track, tunings, sysExChannel=127, realTime=True, tuningProgam=0)

Add a real-time MIDI tuning standard update to a track.

Parameters:
  • track – The track to which the tuning is applied.
  • tunings – A list to tuples representing the tuning. See below for an explanation.
  • sysExChannel – The SysEx channel of the event. This is mapped to “manufacturer ID” in the event which is written. Unless there is a specific reason for changing it, it should be left at its default value.
  • realTime – Speicifes if the Universal SysEx event should be flagged as real-time or non-real-time. As with the sysExChannel argument, this should in general be left at it’s default value.
  • tuningProgram – The tuning program number.

This function specifically implements the “real time single note tuning change” (although the name is misleading, as multiple notes can be included in each event). It should be noted that not all hardware or software implements the MIDI tuning standard, and that which does often does not implement it in its entirety.

The tunings argument is a list of tuples, in (note number, frequency) format. As an example, if one wanted to change the frequency on MIDI note 69 to 500 (it is normally 440 Hz), one could do it thus:

from midiutil.MidiFile import MIDIFile
MyMIDI = MIDIFile(1)
tuning = [(69, 500)]
MyMIDI.changeNoteTuning(0, tuning, tuningProgam=0)
changeTuningBank(track, channel, time, bank, time_order=False)

Change the tuning bank for a selected track

Parameters:
  • track – The track to which the data should be written
  • channel – The channel for the event
  • time – The time of the event
  • bank – The tuning bank (0-127)
  • time_order – Preserve the ordering of the component events by ordering in time. See makeRPNCall() for a discussion of when this may be necessary

Note that this is a convenience function, as the same functionality is available from directly sequencing controller events.

The specified tuning should already have been written to the stream with changeNoteTuning.

changeTuningProgram(track, channel, time, program, time_order=False)

Change the tuning program for a selected track

Parameters:
  • track – The track to which the data should be written
  • channel – The channel for the event
  • time – The time of the event
  • program – The tuning program number (0-127)
  • time_order – Preserve the ordering of the component events by ordering in time. See makeRPNCall() for a discussion of when this may be necessary

Note that this is a convenience function, as the same functionality is available from directly sequencing controller events.

The specified tuning should already have been written to the stream with changeNoteTuning.

makeNRPNCall(track, channel, time, controller_msb, controller_lsb, data_msb, data_lsb, time_order=False)

Perform a Non-Registered Parameter Number Call

Parameters:
  • track – The track to which this applies
  • channel – The channel to which this applies
  • time – The time of the event
  • controller_msb – The Most significant byte of thecontroller. In common usage this will usually be 0
  • controller_lsb – The least significant byte for the controller message. For example, for a fine-tunning change this would be 01.
  • data_msb – The most significant byte of the controller’s parameter.
  • data_lsb – The least significant byte of the controller’s parameter. If none is needed this should be set to None
  • time_order – Order the control events in time (see below)

The time_order parameter is something of a work-around for sequencers that do not preserve the order of events from the MIDI files they import. Within this code care is taken to preserve the order of events as specified, but some sequencers seem to transmit events occurring at the same time in an arbitrary order. By setting this parameter to True something of a work-around is performed: each successive event (of which there are three or four for this event type) is placed in the time stream a small delta from the preceding one. Thus, for example, the controllers are set before the data bytes in this call.

makeRPNCall(track, channel, time, controller_msb, controller_lsb, data_msb, data_lsb, time_order=False)

Perform a Registered Parameter Number Call

Parameters:
  • track – The track to which this applies
  • channel – The channel to which this applies
  • time – The time of the event
  • controller_msb – The Most significant byte of the controller. In common usage this will usually be 0
  • controller_lsb – The Least significant Byte for the controller message. For example, for a fine-tuning change this would be 01.
  • data_msb – The Most Significant Byte of the controller’s parameter.
  • data_lsb – The Least Significant Byte of the controller’s parameter. If non needed this should be set to None
  • time_order – Order the control events in time (see below)

As an example, if one were to change a channel’s tuning program:

makeRPNCall(track, channel, time, 0, 3, 0, program)

(Note, however, that there is a convenience function, changeTuningProgram, that does this for you.)

The time_order parameter is something of a work-around for sequencers that do not preserve the order of events from the MIDI files they import. Within this code care is taken to preserve the order of events as specified, but some sequencers seem to transmit events occurring at the same time in an arbitrary order. By setting this parameter to True something of a work-around is performed: each successive event (of which there are three or four for this event type) is placed in the time stream a small delta from the preceding one. Thus, for example, the controllers are set before the data bytes in this call.

writeFile(fileHandle)

Write the MIDI File.

Parameters:fileHandle – A file handle that has been opened for binary writing.