Utils methods

You will also find some useful methods.

miditok.utils.convert_ids_tensors_to_list(ids: Any)

Convert a PyTorch, Tensorflow Tensor or numpy array to a list of integers. This method can be used seamlessly with Jax too.

Parameters:

ids – ids sequence to convert.

Returns:

the input, as a list of integers

miditok.utils.detect_chords(notes: Sequence[Note], time_division: int, chord_maps: Dict[str, Sequence[int]], specify_root_note: bool = True, beat_res: int = 4, onset_offset: int = 1, unknown_chords_nb_notes_range: Tuple[int, int] = None, simul_notes_limit: int = 10) List[Event]

Chord detection method. Make sure to sort notes by start time then pitch before: notes.sort(key=lambda x: (x.start, x.pitch)). On very large tracks with high note density this method can be slow. If you plan to use it with the Maestro or GiantMIDI datasets, it can take up to hundreds of seconds per MIDI depending on your cpu. This method works by iterating over each note, find if it played with other notes, and if it forms a chord from the chord maps. It does not consider chord inversion.

Parameters:
  • notes – notes to analyse (sorted by starting time, them pitch)

  • time_division – MIDI time division / resolution, in ticks/beat (of the MIDI being parsed)

  • chord_maps – list of chord maps, to be given as a dictionary where keys are chord qualities (e.g. “maj”) and values pitch maps as tuples of integers (e.g. (0, 4, 7)). You can use miditok.constants.CHORD_MAPS as an example.

  • specify_root_note – the root note of each chord will be specified in Events / tokens. Tokens will look as “Chord_C:maj”. (default: True)

  • beat_res – beat resolution, i.e. nb of samples per beat (default 4).

  • onset_offset – maximum offset (in samples) ∈ N separating notes starts to consider them starting at the same time / onset (default is 1).

  • unknown_chords_nb_notes_range – range of number of notes to represent unknown chords. If you want to represent chords that does not match any combination in chord_maps, use this argument. Leave None to not represent unknown chords. (default: None)

  • simul_notes_limit – nb of simultaneous notes being processed when looking for a chord this parameter allows to speed up the chord detection, and must be >= 5 (default 10).

Returns:

the detected chords as Event objects.

miditok.utils.fix_offsets_overlapping_notes(notes: List[Note])

Reduces the durations of overlapping notes, so that when a note starts, if it was previously being played, th previous note will end. Before running this method make sure the notes has been sorted by start then pitch then end values: notes.sort(key=lambda x: (x.start, x.pitch, x.end))

Parameters:

notes – notes to fix.

miditok.utils.get_midi_programs(midi: MidiFile) List[Tuple[int, bool]]

Returns the list of programs of the tracks of a MIDI, deeping the same order. It returns it as a list of tuples (program, is_drum).

Parameters:

midi – the MIDI object to extract tracks programs

Returns:

the list of track programs, as a list of tuples (program, is_drum)

miditok.utils.merge_same_program_tracks(tracks: List[Instrument])

Takes a list of tracks and merge the ones with the same programs. NOTE: Control change messages are not considered

Parameters:

tracks – list of tracks

miditok.utils.merge_tracks(tracks: List[Instrument] | MidiFile, effects: bool = False) Instrument

Merge several miditoolkit Instrument objects, from a list of Instruments or a MidiFile object. All the tracks will be merged into the first Instrument object (notes concatenated and sorted), beware of giving tracks with the same program (no assessment is performed). The other tracks will be deleted.

Parameters:
  • tracks – list of tracks to merge, or MidiFile object

  • effects – will also merge effects, i.e. control changes, sustain pedals and pitch bends

Returns:

the merged track

miditok.utils.merge_tracks_per_class(midi: MidiFile, classes_to_merge: List[int] = None, new_program_per_class: Dict[int, int] = None, max_nb_of_tracks_per_inst_class: Dict[int, int] = None, valid_programs: List[int] = None, filter_pitches: bool = True)

Merges per instrument class the tracks which are in the class in classes_to_merge. Example, a list of tracks / programs [0, 3, 8, 10, 11, 24, 25, 44, 47] will become [0, 8, 24, 25, 40] if classes_to_merge is [0, 1, 5]. The classes are in miditok.constants.INSTRUMENT_CLASSES.

Note: programs of drum tracks will be set to -1.

Parameters:
  • midi – MIDI object to merge tracks

  • classes_to_merge – instrument classes to merge, to give as list of indexes (see miditok.constants.INSTRUMENT_CLASSES). Give None to merge nothing, the function will still remove non-valid programs / tracks if given (default: None)

  • new_program_per_class – new program of the final merged tracks, to be given per instrument class as a dict {class_id: program}

  • max_nb_of_tracks_per_inst_class – max number of tracks per instrument class, if the limit is exceeded for one class only the tracks with the maximum notes will be kept, give None for no limit (default: None)

  • valid_programs – valid program ids to keep, others will be deleted, give None for keep all programs (default None)

  • filter_pitches – after merging, will remove notes whose pitches are out the recommended range defined by the GM2 specs (default: True)

Returns:

True if the MIDI is valid, else False

miditok.utils.nb_bar_pos(seq: Sequence[int], bar_token: int, position_tokens: Sequence[int]) Tuple[int, int]

Returns the number of bars and the last position of a sequence of tokens. This method is compatible with tokenizations representing time with Bar and Position tokens, such as miditok.REMI.

Parameters:
  • seq – sequence of tokens

  • bar_token – the bar token value

  • position_tokens – position tokens values

Returns:

the current bar, current position within the bar, current pitches played at this position, and if a chord token has been predicted at this position

miditok.utils.remove_duplicated_notes(notes: List[Note], filter_by_starting_tick: bool = True)

Removes (inplace) possible duplicated notes, i.e. with the same pitch, starting and ending times. Before running this method make sure the notes has been sorted by start then pitch then end values: notes.sort(key=lambda x: (x.start, x.pitch, x.end))

Parameters:
  • notes – notes to analyse

  • filter_by_starting_tick – will remove identical notes being played at the same onset time regarless of their duration / offset time. If this argument is disabled, only 100% identical notes will be deduplicated, i.e. with the same duration too. (default: True)