MidiScore object

class maidi.MidiScore(bars, tracks, track_keys, tempo, tpq=24, **kwargs)

Bases: object

The main object to handle midi scores. It allows to manipulate midi scores in a numpy-like way by splitting it into two dimensions : tracks and bars.

warning :: All midi notes with velocity < 2 are ignored when writing midi files, they are considered as fake notes. This behaviour will be removed in the future

warning:: This class should not be directly instantiated, use from_midi() or from_base64() instead

Usage

Load a midi file and write it to a new file

>>> from maidi import MidiScore
>>> score = MidiScore.from_midi("path/to/midi.mid")
>>> score.write("path/to/output.mid")

Add a track and assign the content of the track to be the same as the first track

>>> from maidi import MidiScore, instrument
>>> score = MidiScore.from_midi("path/to/midi.mid")
>>> score = score.add_instrument(instrument.ACOUSTIC_GUITAR)
>>> score[-1, :] = score[0, :]

Concatenate two scores horizontally

>>> from maidi import MidiScore
>>> score1 = MidiScore.from_midi("path/to/midi1.mid")
>>> score2 = MidiScore.from_midi("path/to/midi2.mid")
>>> score = score1.concatenate(score2, axis=1)
>>> score.nb_bars == score1.nb_bars + score2.nb_bars
True
__init__(bars, tracks, track_keys, tempo, tpq=24, **kwargs)

Create a new MidiScore object, you usually never directly call the constructor. See from_midi() or from_base64() to create a new MidiScore object

Parameters:
  • bars (list of list) – List of bars in the score

  • tracks (dict) – Dictionary of tracks in the score

  • track_keys (list) – List of track keys

  • tempo (int) – Tempo of the score

  • tpq (int) – Ticks per quarter note

  • kwargs (dict) – Additional arguments

add_note(pitch, time, duration, velocity, track_index, bar_index)

Add a note to the score

Parameters:
  • pitch – int, pitch of the note

  • velocity – int, velocity of the note

  • duration – int, duration of the note

  • track_index – int, index of the track

  • bar_index – int, index of the bar

  • time – int, time of the note

add_silence_bars(n_bars, add_fake_notes=True)

Add n_bars of silence to the end of the score

Parameters:
  • n_bars – int, number of silence bars to add

  • add_fake_notes – bool, if True add a fake note to each track (Default value = True)

add_track(program, is_drum)

Add an empty track (with fake notes) to the score

Parameters:
  • program – int, program number

  • is_drum – bool, is drum track

assign_tracks(track_indexes, other_score, bar_range=None)

Assign some tracks of the other_score to the current score

change_instrument(track_idx, instrument)

Change the instrument of a track

Parameters:
  • track_idx – param instrument:

  • instrument

change_ts(new_ts, dilate_time=True)

Change the time signature of the score

Parameters:
  • new_ts (tuple) – New time signature of the score

  • dilate_time (bool (Default value = True)) – If True, dilate the time of the notes to match the new time signature

check_mask(mask)

Check that the mask is valid

Parameters:

mask – np.array of shape (n_tracks, n_bars)

check_times()
concatenate(other_score, axis=0)

Concatenate two scores along a specific axis (0 = horizontally, 1 = vertically)

For 0 axis concatenation, the number of tracks must be the same, the bars from left score are kept For 1 axis concatenation, the number of bars must be the same, the tracks from the left score are kept

Parameters:
  • other_score (MidiScore) – The score to concatenate with

  • axis (int (Default value = 0)) – The axis along which to concatenate (0 = horizontally, 1 = vertically)

classmethod concatenate_scores(scores, axis=0)

Concatenate multiple scores along a specific axis (0 = horizontally, 1 = vertically)

For 0 axis concatenation, the number of tracks must be the same, the bars from left score are kept For 1 axis concatenation, the number of bars must be the same, the tracks from the left score are kept

Parameters:
  • scores (list) – List of scores to concatenate with

  • axis (int (Default value = 0)) – The axis along which to concatenate (0 = horizontally, 1 = vertically)

Returns:

The concatenated score

Return type:

MidiScore

copy()
cut_notes_at_the_end(only_end=True)

On last bar, cut duration of note if it goes after the bar duration

Parameters:

only_end (boolean) – Only cut the last bar (Default value = True)

cut_silence_bars_at_end()

Cut the silence bars at the end of the score

cut_silenced_bars_at_beginning_and_end()

Cut silenced bars at the beginning and end of the score Cut the bar only if all tracks do not have notes (or fake notes)

Returns:

delete_bar(bar_index)

Delete a bar from the score

Parameters:

bar_index – int, index of the bar to delete

dilate_time(factors)

Dilate the time of the notes in the score to match the time signature of the score

Parameters:

factor (float or list of float) – Factor to dilate the time of the notes, if a list is provided, the factors are applied to each bar

classmethod from_base64(base64_string, tpq=24)

Create a score from a base64 string

Parameters:
  • base64_string – str, base64 string

  • tpq – int, ticks per quarter note (Default value = 24)

classmethod from_empty(instruments, nb_bars, ts=(4, 4), tempo=120, tpq=24, add_fake_notes=True)
Parameters:
  • instruments

  • nb_bars (int) –

    Number of bars to create

    (Default value = (4)

  • ts (tuple) – Time signature of the score (Default value = (4, 4))

  • 4)

  • tempo (int (Default value = 120)) – Tempo of the score

  • tpq (int (Default value = 24)) – Ticks per quarter note, usually you don’t need to change this

  • add_fake_notes (bool (Default value = True)) – If True, add fake notes to the score (a ghost note with low velocity that is not considered in the generation)

classmethod from_midi(midi_file, tpq=24, bar_range=None, force_ts=None)
Parameters:
  • midi_file

  • tpq – (Default value = 24)

  • bar_range – (Default value = None)

get_bar_duration(bar_index)

Get the duration of a bar in ticks for a specific bar of the score

Parameters:

bar_index (int) – Index of the bar

Returns:

Duration of the bar in ticks

Return type:

int

get_bar_start_end_tick(bar_index)

Calculate the start and end tick of a given bar on the score

Parameters:

bar_index (int) – Index of the bar

Returns:

  • start (int) – Start tick of the bar

  • end (int) – End tick of the bar

get_bars(item)

Get the bars between the start and end index

slice: int or Slice, slice object

get_chord_manager(use_last_chord_for_silence=True)

Return a chord manager from the chords of the score

Parameters:

use_last_chord_for_silence (bool) – If True, use the last chord played for silenced bars, otherwise return None

Returns:

cm

Return type:

ChordManager

get_chords(use_last_chord_for_silence=True)

Return the list of chords in the score in the format [(chord_degree, tonality, mode, chord extension), …]

Chord degree : int, degree of the chord in the tonality but 0 indexed (0-6), tonic is 0, fifth is 4 Tonality : int, tonality in which the chord is played (0-11), 0 is C, 1 is C#, 2 is D, … Mode : str, mode of the tonality, “m” for minor, “M” for major Chord extension : str, extension of the chord as in roman numeral notation, in [‘’, ‘,6’, ‘64’, ‘7’, ‘65’, ‘43’, ‘2’] Optionally you can use (sus2) or (sus4) for suspended chords

Parameters:

use_last_chord_for_silence (bool) – If True, use the last chord played for silenced bars, otherwise return None

Returns:

  • chords (list of tuple)

  • As specified above

get_empty_controls(prevent_silence=True)

Get the mask, the tags and the bars of the current score. The mask is a np.array of shape (n_tracks, n_bars) The tags is a list of list of list of size (n_tracks, n_bars, <variable size>) The bars is a list of size (n_bars,)

Parameters:

prevent_silence – bool, if True add a tag to each bar to explicitly prevent silence during generation (Default value = False)

get_mask()

Get the mask of the score (np.array of shape (n_tracks, n_bars)) The mask allows to specify which bar of the score should be regenerated by a model (ones) The mask is the same size as the score and is empty by default (all zeros)

Returns:

mask – Mask of the score, empty by default (all zeros)

Return type:

np.array of shape (n_tracks, n_bars)

get_score_between(start_bar, end_bar)
Parameters:
  • start_bar

  • end_bar

get_silenced_bars()
get_silenced_mask()
Returns:

return:

Return type:

type

get_track_subset(start, end)
Parameters:
  • start

  • end

get_tracks(item)

Get the tracks between the start and end index

slice: int or Slice, slice object

is_bar_empty(bar_index, keep_ghost_note=False)

Check if a bar is empty

Parameters:
  • bar_index (int) – Index of the bar to check

  • keep_ghost_note (bool) – If True, ghost note counts as note in the check

is_bar_track_empty(track_index, bar_index, keep_ghost_note=False)

Check if a bar is empty

Parameters:
  • track_index (int) – Index of the track

  • bar_index (int) – Index of the bar to check

  • keep_ghost_note (bool) – If True, ghost note counts as note in the check

normalize_track_indexes()

Normalize the track indexes to be in the range of the number of tracks

classmethod prevent_silence_tags(tags)

Prevent silence tags from being added to the tags

Parameters:

tags – list of list of list of str, tags to prevent silence

to_base64()

Transform the score to a base64 string :return:

classmethod track_notes_to_score_notes(bars, track_notes, tpq)
Parameters:
  • bars

  • track_notes

write(filename)
Parameters:

filename

CHORD_EXTENSION_INDEX = 4
CHORD_OCTAVE_INDEX = 3
FAKE_NOTE_DURATION = 2
FAKE_NOTE_PITCH = 60
FAKE_NOTE_VELOCITY = 1
MINIMUM_VELOCITY = 2
MODE_INDEX = 2
SCALE_DEGREE_INDEX = 0
TIME_SIGNATURE_DENOMINATOR_INDEX = 6
TIME_SIGNATURE_NUMERATOR_INDEX = 5
TONALITY_INDEX = 1
property instruments

Get the list of instruments in the score as a list of strings

Returns:

instruments

Return type:

list of str

property nb_bars
property nb_tracks

Number of tracks (or instruments) in the score

property shape

Return the shape of the score (n_tracks, n_bars)