Class Reference

class midiutil.MidiFile.MIDIFile(numTracks=1, removeDuplicates=True, deinterleave=True, adjust_origin=False, file_format=1, ticks_per_quarternote=960, eventtime_is_ticks=False)

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=False, file_format=1, ticks_per_quarternote=960, eventtime_is_ticks=False)

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 shift all the events in the tracks so that the first event takes place at time t=0. Default is False
  • file_format – The format of the multi-track file. This should either be 1 (the default, and the most widely supported format) or 2.
  • ticks_per_quarternote – The number of ticks per quarter note is what the Standard MIDI File Format Specification calls “division”. Ticks are the integer unit of time in the SMF, and in most if not all MIDI sequencers. Common values are 120, 240, 384, 480, 960. Note that all these numbers are evenly divisible by 2,3,4,6,8,12,16, and 24, except 120 does not have 16 as a divisor.
  • eventtime_is_ticks – If set True means event time and duration argument values are integer ticks instead of fractional quarter notes.

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

In a format 1 file, it would be a rare cirumstance where adjusting the origin of each track to the track’s first note makes any sense.

Example:

# Create a two-track MIDIFile

from midiutil.MidiFile import MIDIFile
midi_file = MIDIFile(1, adjust_origin=False)

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 at which the note sounds. The value can be either quarter notes [Float], or ticks [Integer]. Ticks may be specified by passing eventtime_is_ticks=True to the MIDIFile constructor. The default is quarter notes.
  • duration – the duration of the note. Like the time argument, the value can be either quarter notes [Float], or ticks [Integer].
  • 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.

addPitchWheelEvent(track, channel, time, pitchWheelValue)

Add a channel pitch wheel 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].
  • pitchWheelValue – 0 for no pitch change. [Integer, -8192-8192]
addProgramChange(tracknum, channel, time, program)

Add a MIDI program change event.

Parameters:
  • tracknum – The zero-based track number 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 tempo 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 [ASCII String]
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.

The notes_per_quarter value is also a little confusing. It specifies the number of 32nd notes in a MIDI quarter note. Usually there are 8 32nd notes in a quarter note (8/32 = 1/4), so the default value is 8. However, one can change this value if needed. Setting it to 16, for example, would cause the music to play at double speed, as there would be 16/32 (or what could be considered two quarter notes for every one MIDI quarter note.

Note that both the clocks_per_tick and the notes_per_quarter are specified in terms of quarter notes, even is the score is not a quarter-note based score (i.e., even if the denominator is not 4). So if you’re working with a time signature of, say, 6/8, one still needs to specify the clocks per quarter note.

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 not 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.)

Controller number 6 (Data Entry), in conjunction with Controller numbers 96 (Data Increment), 97 (Data Decrement), 98 (Registered Parameter Number LSB), 99 (Registered Parameter Number MSB), 100 (Non-Registered Parameter Number LSB), and 101 (Non-Registered Parameter Number MSB), extend the number of controllers available via MIDI. Parameter data is transferred by first selecting the parameter number to be edited using controllers 98 and 99 or 100 and 101, and then adjusting the data value for that parameter using controller number 6, 96, or 97.

RPN and NRPN are typically used to send parameter data to a synthesizer in order to edit sound patches or other data. Registered parameters are those which have been assigned some particular function by the MIDI Manufacturers Association (MMA) and the Japan MIDI Standards Committee (JMSC). For example, there are Registered Parameter numbers assigned to control pitch bend sensitivity and master tuning for a synthesizer. Non-Registered parameters have not been assigned specific functions, and may be used for different functions by different manufacturers.

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.