madmom.io.midi

This module contains MIDI functionality.

madmom.io.midi.tick2second(tick, ticks_per_beat=480, tempo=500000)[source]

Convert absolute time in ticks to seconds.

Returns absolute time in seconds for a chosen MIDI file time resolution (ticks/pulses per quarter note, also called PPQN) and tempo (microseconds per quarter note).

madmom.io.midi.second2tick(second, ticks_per_beat=480, tempo=500000)[source]

Convert absolute time in seconds to ticks.

Returns absolute time in ticks for a chosen MIDI file time resolution (ticks/pulses per quarter note, also called PPQN) and tempo (microseconds per quarter note).

madmom.io.midi.bpm2tempo(bpm, time_signature=(4, 4))[source]

Convert BPM (beats per minute) to MIDI file tempo (microseconds per quarter note).

Depending on the chosen time signature a bar contains a different number of beats. These beats are multiples/fractions of a quarter note, thus the returned BPM depend on the time signature.

madmom.io.midi.tempo2bpm(tempo, time_signature=(4, 4))[source]

Convert MIDI file tempo (microseconds per quarter note) to BPM (beats per minute).

Depending on the chosen time signature a bar contains a different number of beats. These beats are multiples/fractions of a quarter note, thus the returned tempo depends on the time signature.

madmom.io.midi.tick2beat(tick, ticks_per_beat=480, time_signature=(4, 4))[source]

Convert ticks to beats.

Returns beats for a chosen MIDI file time resolution (ticks/pulses per quarter note, also called PPQN) and time signature.

madmom.io.midi.beat2tick(beat, ticks_per_beat=480, time_signature=(4, 4))[source]

Convert beats to ticks.

Returns ticks for a chosen MIDI file time resolution (ticks/pulses per quarter note, also called PPQN) and time signature.

class madmom.io.midi.MIDIFile(filename=None, file_format=0, ticks_per_beat=480, unit='seconds', timing='absolute', **kwargs)[source]

MIDI File.

Parameters:
filename : str

MIDI file name.

file_format : int, optional

MIDI file format (0, 1, 2).

ticks_per_beat : int, optional

Resolution (i.e. ticks per quarter note) of the MIDI file.

unit : str, optional

Unit of all MIDI messages, can be one of the following:

  • ‘ticks’, ‘t’: use native MIDI ticks as unit,
  • ‘seconds’, ‘s’: use seconds as unit,
  • ‘beats’, ‘b’ : use beats as unit.
timing : str, optional

Timing of all MIDI messages, can be one of the following:

  • ‘absolute’, ‘abs’, ‘a’: use absolute timing.
  • ‘relative’, ‘rel’, ‘r’: use relative timing, i.e. delta to

previous message.

Examples

Create a MIDI file from an array with notes. The format of the note array is: ‘onset time’, ‘pitch’, ‘duration’, ‘velocity’, ‘channel’. The last column can be omitted, assuming channel 0.

>>> notes = np.array([[0, 50, 1, 60], [0.5, 62, 0.5, 90]])
>>> m = MIDIFile.from_notes(notes)
>>> m  
<madmom.io.midi.MIDIFile object at 0x...>

The notes can be accessed as a numpy array in various formats (default is seconds):

>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit ='ticks'
>>> m.notes
array([[  0.,  50., 960.,  60.,   0.],
       [480.,  62., 480.,  90.,   0.]])
>>> m.unit = 'seconds'
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit = 'beats'
>>> m.notes
array([[ 0., 50.,  2., 60.,  0.],
       [ 1., 62.,  1., 90.,  0.]])
>>> m = MIDIFile.from_notes(notes, tempo=60)
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit = 'ticks'
>>> m.notes
array([[  0.,  50., 480.,  60.,   0.],
       [240.,  62., 240.,  90.,   0.]])
>>> m.unit = 'beats'
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m = MIDIFile.from_notes(notes, time_signature=(2, 2))
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit = 'ticks'
>>> m.notes
array([[   0.,   50., 1920.,   60.,    0.],
       [ 960.,   62.,  960.,   90.,    0.]])
>>> m.unit = 'beats'
>>> m.notes
array([[ 0., 50.,  2., 60.,  0.],
       [ 1., 62.,  1., 90.,  0.]])
>>> m = MIDIFile.from_notes(notes, tempo=60, time_signature=(2, 2))
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit = 'ticks'
>>> m.notes
array([[  0.,  50., 960.,  60.,   0.],
       [480.,  62., 480.,  90.,   0.]])
>>> m.unit = 'beats'
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m = MIDIFile.from_notes(notes, tempo=240, time_signature=(3, 8))
>>> m.notes
array([[ 0. , 50. ,  1. , 60. ,  0. ],
       [ 0.5, 62. ,  0.5, 90. ,  0. ]])
>>> m.unit = 'ticks'
>>> m.notes
array([[  0.,  50., 960.,  60.,   0.],
       [480.,  62., 480.,  90.,   0.]])
>>> m.unit = 'beats'
>>> m.notes
array([[ 0., 50.,  4., 60.,  0.],
       [ 2., 62.,  2., 90.,  0.]])
tempi

Tempi (mircoseconds per quarter note) of the MIDI file.

Returns:
tempi : numpy array

Array with tempi (time, tempo).

Notes

The time will be given in the unit set by unit.

time_signatures

Time signatures of the MIDI file.

Returns:
time_signatures : numpy array

Array with time signatures (time, numerator, denominator).

Notes

The time will be given in the unit set by unit.

notes

Notes of the MIDI file.

Returns:
notes : numpy array

Array with notes (onset time, pitch, duration, velocity, channel).

classmethod from_notes(notes, unit='seconds', tempo=500000, time_signature=(4, 4), ticks_per_beat=480)[source]

Create a MIDIFile from the given notes.

Parameters:
notes : numpy array

Array with notes, one per row. The columns are defined as: (onset time, pitch, duration, velocity, [channel]).

unit : str, optional

Unit of notes, can be one of the following:

  • ‘seconds’, ‘s’: use seconds as unit,
  • ‘ticks’, ‘t’: use native MIDI ticks as unit,
  • ‘beats’, ‘b’ : use beats as unit.
tempo : float, optional

Tempo of the MIDI track, given in bpm or microseconds per quarter note. The unit is determined automatically by the value:

  • tempo <= 1000: bpm
  • tempo > 1000: microseconds per quarter note
time_signature : tuple, optional

Time signature of the track, e.g. (4, 4) for 4/4.

ticks_per_beat : int, optional

Resolution (i.e. ticks per quarter note) of the MIDI file.

Returns:
:class:`MIDIFile` instance

MIDIFile instance with all notes collected in one track.

Notes

All note events (including the generated tempo and time signature events) are written into a single track (i.e. MIDI file format 0).

save(filename)[source]

Save to MIDI file.

Parameters:
filename : str or open file handle

The MIDI file name.

madmom.io.midi.load_midi(filename)[source]

Load notes from a MIDI file.

Parameters:
filename: str

MIDI file.

Returns:
numpy array

Notes (‘onset time’ ‘note number’ ‘duration’ ‘velocity’ ‘channel’)

madmom.io.midi.write_midi(notes, filename, duration=0.6, velocity=100)[source]

Write notes to a MIDI file.

Parameters:
notes : numpy array, shape (num_notes, 2)

Notes, one per row (column definition see notes).

filename : str

Output MIDI file.

duration : float, optional

Note duration if not defined by notes.

velocity : int, optional

Note velocity if not defined by notes.

Returns:
numpy array

Notes (including note length, velocity and channel).

Notes

The note columns format must be (duration, velocity and channel optional):

‘onset time’ ‘note number’ [‘duration’ [‘velocity’ [‘channel’]]]