Technical Documentation
A Python library for handling multitrack pianorolls.
Pypianoroll is an open source Python library for working with piano rolls. It provides essential tools for handling multitrack piano rolls, including efficient I/O as well as manipulation, visualization and evaluation tools.
Features
Manipulate multitrack piano rolls intuitively
Visualize multitrack piano rolls beautifully
Save and load multitrack piano rolls in a space-efficient format
Parse MIDI files into multitrack piano rolls
Write multitrack piano rolls into MIDI files
- class pypianoroll.BinaryTrack(name: Optional[str] = None, program: Optional[int] = None, is_drum: Optional[bool] = None, pianoroll: Optional[numpy.ndarray] = None)[source]
A container for single-track, binary piano rolls.
- name
Track name.
- Type
str, optional
- program
Program number according to General MIDI specification [1]. Defaults to 0 (Acoustic Grand Piano).
- Type
int, 0-127, default: pypianoroll.DEFAULT_PROGRAM (0)
- is_drum
Whether it is a percussion track.
- Type
bool, default: pypianoroll.DEFAULT_IS_DRUM (False)
- pianoroll
Piano-roll matrix. The first dimension represents time, and the second dimension represents pitch. Cast to bool if not of data type bool.
- Type
ndarray, dtype=bool, shape=(?, 128), optional
References
- copy() pypianoroll.track.BinaryTrack [source]
Return a copy of the track.
- Returns
- Return type
A copy of the object itself.
Notes
The piano-roll array is copied using
numpy.copy()
.
- set_nonzeros(value: int) pypianoroll.track.StandardTrack [source]
Assign a constant value to all nonzeros entries.
- Parameters
value (int) – Value to assign.
- Returns
- Return type
Converted StandardTrack object.
- class pypianoroll.Multitrack(name: Optional[str] = None, resolution: Optional[int] = None, tempo: Optional[numpy.ndarray] = None, beat: Optional[numpy.ndarray] = None, downbeat: Optional[numpy.ndarray] = None, tracks: Optional[Sequence[pypianoroll.track.Track]] = None)[source]
A container for multitrack piano rolls.
This is the core class of Pypianoroll. A Multitrack object can be constructed in the following ways.
pypianoroll.Multitrack()
: Construct by setting values for attributespypianoroll.read()
: Read from a MIDI filepypianoroll.from_pretty_midi()
: Convert from apretty_midi.PrettyMIDI
objectpypianoroll.load()
: Load from a JSON or a YAML file saved bypypianoroll.save()
- name
Multitrack name.
- Type
str, optional
- resolution
Time steps per quarter note.
- Type
int, default: pypianoroll.DEFAULT_RESOLUTION (24)
- tempo
Tempo (in qpm) at each time step. Length is the total number of time steps. Cast to float if not of float type.
- Type
ndarray, dtype=float, shape=(?, 1), optional
- beat
A boolean array that indicates whether the time step contains a beat. Length is the total number of time steps. Cast to bool if not of bool type.
- Type
ndarray, dtype=bool, shape=(?, 1), optional
- downbeat
A boolean array that indicates whether the time step contains a downbeat, i.e., the first time step of a measure. Length is the total number of time steps. Cast to bool if not of bool type.
- Type
ndarray, dtype=bool, shape=(?, 1), optional
- tracks
Music tracks.
- Type
sequence of
pypianoroll.Track
, default: []
- append(track: pypianoroll.track.Track) pypianoroll.multitrack.MultitrackType [source]
Append a Track object to the track list.
- Parameters
track (
pypianoroll.Track
) – Track to append.- Returns
- Return type
Object itself.
- binarize(threshold: float = 0) pypianoroll.multitrack.MultitrackType [source]
Binarize the piano rolls.
- Parameters
threshold (int or float, default: 0) – Threshold to binarize the piano rolls.
- Returns
- Return type
Object itself.
- blend(mode: Optional[str] = None) numpy.ndarray [source]
Return the blended pianoroll.
- Parameters
mode ({'sum', 'max', 'any'}, default: 'sum') – Blending strategy to apply along the track axis. For ‘sum’ mode, integer summation is performed for binary piano rolls.
- Returns
Blended piano roll.
- Return type
ndarray, shape=(?, 128)
- clip(lower: int = 0, upper: int = 127) pypianoroll.multitrack.MultitrackType [source]
Clip (limit) the the piano roll into [lower, upper].
- Parameters
lower (int, default: 0) – Lower bound.
upper (int, default: 127) – Upper bound.
- Returns
- Return type
Object itself.
Note
Only affect StandardTrack instances.
- copy()[source]
Return a copy of the multitrack.
- Returns
- Return type
A copy of the object itself.
Notes
Arrays are copied using
numpy.copy()
.
- count_beat() int [source]
Return the number of beats.
- Returns
Number of beats.
- Return type
int
Note
Return value is calculated based only on the attribute beat.
- count_downbeat() int [source]
Return the number of downbeats.
- Returns
Number of downbeats.
- Return type
int
Note
Return value is calculated based only on the attribute downbeat.
- get_beat_steps() numpy.ndarray [source]
Return the indices of time steps that contain beats.
- Returns
Indices of time steps that contain beats.
- Return type
ndarray, dtype=int
- get_downbeat_steps() numpy.ndarray [source]
Return the indices of time steps that contain downbeats.
- Returns
Indices of time steps that contain downbeats.
- Return type
ndarray, dtype=int
- get_length() int [source]
Return the maximum active length of the piano rolls.
- Returns
Maximum active length (in time steps) of the piano rolls, where active length is the length of the piano roll without trailing silence.
- Return type
int
- get_max_length() int [source]
Return the maximum length of the piano rolls.
- Returns
Maximum length (in time steps) of the piano rolls.
- Return type
int
- is_valid(attr: Optional[str] = None) bool [source]
Return True if an attribute is valid.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
Whether the attribute has a valid type and value.
- Return type
bool
- is_valid_type(attr: Optional[str] = None) bool [source]
Return True if an attribute is of a valid type.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
Whether the attribute is of a valid type.
- Return type
bool
- pad(pad_length) pypianoroll.multitrack.MultitrackType [source]
Pad the piano rolls.
Notes
The lengths of the resulting piano rolls are not guaranteed to be the same.
- Parameters
pad_length (int) – Length to pad along the time axis.
- Returns
- Return type
Object itself.
See also
pypianoroll.Multitrack.pad_to_multiple()
Pad the piano rolls so that their lengths are some multiples.
pypianoroll.Multitrack.pad_to_same()
Pad the piano rolls so that they have the same length.
- pad_to_multiple(factor: int) pypianoroll.multitrack.MultitrackType [source]
Pad the piano rolls so that their lengths are some multiples.
Pad the piano rolls at the end along the time axis of the minimum length that makes the lengths of the resulting piano rolls multiples of factor.
- Parameters
factor (int) – The value which the length of the resulting piano rolls will be a multiple of.
- Returns
- Return type
Object itself.
Notes
Lengths of the resulting piano rolls are necessarily the same.
See also
pypianoroll.Multitrack.pad()
Pad the piano rolls.
pypianoroll.Multitrack.pad_to_same()
Pad the piano rolls so that they have the same length.
- pad_to_same() pypianoroll.multitrack.MultitrackType [source]
Pad the piano rolls so that they have the same length.
Pad shorter piano rolls at the end along the time axis so that the resulting piano rolls have the same length.
- Returns
- Return type
Object itself.
See also
pypianoroll.Multitrack.pad()
Pad the piano rolls.
pypianoroll.Multitrack.pad_to_multiple()
Pad the piano rolls so that their lengths are some multiples.
- plot(axs: Optional[Sequence[matplotlib.axes._axes.Axes]] = None, **kwargs) List[matplotlib.axes._axes.Axes] [source]
Plot the multitrack piano roll.
Refer to
pypianoroll.plot_multitrack()
for full documentation.
- save(path: str, compressed: bool = True)[source]
Save to a NPZ file.
Refer to
pypianoroll.save()
for full documentation.
- set_nonzeros(value: int) pypianoroll.multitrack.MultitrackType [source]
Assign a constant value to all nonzero entries.
- Parameters
value (int) – Value to assign.
- Returns
- Return type
Object itself.
- set_resolution(resolution: int, rounding: str = 'round') pypianoroll.multitrack.MultitrackType [source]
Set the resolution.
- Parameters
resolution (int) – Target resolution.
rounding ({'round', 'ceil', 'floor'}, default: 'round') – Rounding mode.
- Returns
- Return type
Object itself.
- stack() numpy.ndarray [source]
Return the piano rolls stacked as a 3D tensor.
- Returns
Stacked piano roll, provided as (track, time, pitch).
- Return type
ndarray, shape=(?, ?, 128)
- to_pretty_midi(**kwargs)[source]
Return as a PrettyMIDI object.
Refer to
pypianoroll.to_pretty_midi()
for full documentation.
- transpose(semitone: int) pypianoroll.multitrack.MultitrackType [source]
Transpose the piano rolls by a number of semitones.
- Parameters
semitone (int) – Number of semitones to transpose. A positive value raises the pitches, while a negative value lowers the pitches.
- Returns
- Return type
Object itself.
Notes
Drum tracks are skipped.
- trim(start: Optional[int] = None, end: Optional[int] = None) pypianoroll.multitrack.MultitrackType [source]
Trim the trailing silences of the piano rolls.
- Parameters
start (int, default: 0) – Start time.
end (int, optional) – End time. Defaults to active length.
- Returns
- Return type
Object itself.
- validate(attr=None) pypianoroll.multitrack.MultitrackType [source]
Raise an error if an attribute has an invalid type or value.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
- Return type
Object itself.
- validate_type(attr=None)[source]
Raise an error if an attribute has an invalid type.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
- Return type
Object itself.
- write(path: str)[source]
Write to a MIDI file.
Refer to
pypianoroll.write()
for full documentation.
- class pypianoroll.StandardTrack(name: Optional[str] = None, program: Optional[int] = None, is_drum: Optional[bool] = None, pianoroll: Optional[numpy.ndarray] = None)[source]
A container for single-track piano rolls with velocities.
- name
Track name.
- Type
str, optional
- program
Program number according to General MIDI specification [1]. Defaults to 0 (Acoustic Grand Piano).
- Type
int, 0-127, default: pypianoroll.DEFAULT_PROGRAM (0)
- is_drum
Whether it is a percussion track.
- Type
bool, default: pypianoroll.DEFAULT_IS_DRUM (False)
- pianoroll
Piano-roll matrix. The first dimension represents time, and the second dimension represents pitch. Cast to uint8 if not of data type uint8.
- Type
ndarray, dtype=uint8, shape=(?, 128), optional
References
- clip(lower: int = 0, upper: int = 127) pypianoroll.track.StandardTrackType [source]
Clip (limit) the the piano roll into [lower, upper].
- Parameters
lower (int, default: 0) – Lower bound.
upper (int, default: 127) – Upper bound.
- Returns
- Return type
Object itself.
- copy() pypianoroll.track.StandardTrack [source]
Return a copy of the track.
- Returns
- Return type
A copy of the object itself.
Notes
The piano-roll array is copied using
numpy.copy()
.
- class pypianoroll.Track(name: Optional[str] = None, program: Optional[int] = None, is_drum: Optional[bool] = None, pianoroll: Optional[numpy.ndarray] = None)[source]
A generic container for single-track piano rolls.
- name
Track name.
- Type
str, optional
- program
Program number according to General MIDI specification [1]. Defaults to 0 (Acoustic Grand Piano).
- Type
int, 0-127, default: pypianoroll.DEFAULT_PROGRAM (0)
- is_drum
Whether it is a percussion track.
- Type
bool, pypianoroll.DEFAULT_IS_DRUM (False)
- pianoroll
Piano-roll matrix. The first dimension represents time, and the second dimension represents pitch.
- Type
ndarray, shape=(?, 128), optional
References
- binarize(threshold: float = 0) pypianoroll.track.BinaryTrack [source]
Binarize the track.
This will binarize the piano roll by the given threshold.
- Parameters
threshold (int or float, default: 0) – Threshold.
- Returns
- Return type
Converted BinaryTrack object.
- copy() pypianoroll.track.Track [source]
Return a copy of the track.
- Returns
- Return type
A copy of the object itself.
Notes
The piano-roll array is copied using
numpy.copy()
.
- get_length() int [source]
Return the active length of the piano roll.
- Returns
Length (in time steps) of the piano roll without trailing silence.
- Return type
int
- is_valid(attr: Optional[str] = None) bool [source]
Return True if an attribute is valid.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
Whether the attribute has a valid type and value.
- Return type
bool
- is_valid_type(attr: Optional[str] = None) bool [source]
Return True if an attribute is of a valid type.
- Parameters
attr (str) – Attribute to validate. Defaults to validate all attributes.
- Returns
Whether the attribute is of a valid type.
- Return type
bool
- pad(pad_length: int) pypianoroll.track.TrackType [source]
Pad the piano roll.
- Parameters
pad_length (int) – Length to pad along the time axis.
- Returns
- Return type
Object itself.
See also
pypianoroll.Track.pad_to_multiple()
Pad the piano roll so that its length is some multiple.
- pad_to_multiple(factor: int) pypianoroll.track.TrackType [source]
Pad the piano roll so that its length is some multiple.
Pad the piano roll at the end along the time axis of the minimum length that makes the length of the resulting piano roll a multiple of factor.
- Parameters
factor (int) – The value which the length of the resulting piano roll will be a multiple of.
- Returns
- Return type
Object itself.
See also
pypianoroll.Track.pad()
Pad the piano roll.
- plot(ax: Optional[matplotlib.axes._axes.Axes] = None, **kwargs) matplotlib.axes._axes.Axes [source]
Plot the piano roll.
Refer to
pypianoroll.plot_track()
for full documentation.
- standardize() pypianoroll.track.StandardTrack [source]
Standardize the track.
This will clip the piano roll to [0, 127] and cast to np.uint8.
- Returns
- Return type
Converted StandardTrack object.
- transpose(semitone: int) pypianoroll.track.TrackType [source]
Transpose the piano roll by a number of semitones.
- Parameters
semitone (int) – Number of semitones to transpose. A positive value raises the pitches, while a negative value lowers the pitches.
- Returns
- Return type
Object itself.
- trim(start: Optional[int] = None, end: Optional[int] = None) pypianoroll.track.TrackType [source]
Trim the piano roll.
- Parameters
start (int, default: 0) – Start time.
end (int, optional) – End time. Defaults to active length.
- Returns
- Return type
Object itself.
- pypianoroll.binarize(obj: Union[pypianoroll.multitrack.Multitrack, pypianoroll.track.StandardTrack], threshold: int = 0)[source]
Binarize the piano roll(s).
- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.StandardTrack
) – Object to binarize.threshold (int, default: 0) – Threshold.
- pypianoroll.clip(obj: pypianoroll.core.MultitrackType, lower: int = 0, upper: int = 127) pypianoroll.core.MultitrackType [source]
Clip (limit) the the piano roll(s) into [lower, upper].
- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.StandardTrack
) – Object to clip.lower (int, default: 0) – Lower bound.
upper (int, default: 127) – Upper bound.
- Returns
- Return type
Object itself.
- pypianoroll.drum_in_pattern_rate(pianoroll: numpy.ndarray, resolution: int, tolerance: float = 0.1) float [source]
Return the ratio of drum notes in a certain drum pattern.
The drum-in-pattern rate is defined as the ratio of the number of notes in a certain scale to the total number of notes. Only drum tracks are considered. Return NaN if no drum note is found. This metric is used in [1].
\[drum\_in\_pattern\_rate = \frac{ \#(drum\_notes\_in\_pattern)}{\#(drum\_notes)}\]- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
resolution (int) – Time steps per beat.
tolerance (float, default: 0.1) – Tolerance.
- Returns
Drum-in-pattern rate.
- Return type
float
References
Hao-Wen Dong, Wen-Yi Hsiao, Li-Chia Yang, and Yi-Hsuan Yang, “MuseGAN: Multi-track sequential generative adversarial networks for symbolic music generation and accompaniment,” in Proceedings of the 32nd AAAI Conference on Artificial Intelligence (AAAI), 2018.
- pypianoroll.empty_beat_rate(pianoroll: numpy.ndarray, resolution: int) float [source]
Return the ratio of empty beats.
The empty-beat rate is defined as the ratio of the number of empty beats (where no note is played) to the total number of beats. Return NaN if song length is zero.
\[empty\_beat\_rate = \frac{\#(empty\_beats)}{\#(beats)}\]- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
- Returns
Empty-beat rate.
- Return type
float
- pypianoroll.from_pretty_midi(midi: pretty_midi.pretty_midi.PrettyMIDI, resolution: int = 24, mode: str = 'max', algorithm: str = 'normal', collect_onsets_only: bool = False, first_beat_time: Optional[float] = None) pypianoroll.multitrack.Multitrack [source]
Return a Multitrack object converted from a PrettyMIDI object.
Parse a
pretty_midi.PrettyMIDI
object. The data type of the resulting piano rolls is automatically determined (int if ‘mode’ is ‘sum’ and np.uint8 if mode is ‘max’).- Parameters
midi (
pretty_midi.PrettyMIDI
) – PrettyMIDI object to parse.mode ({'max', 'sum'}, default: 'max') – Merging strategy for duplicate notes.
algorithm ({'normal', 'strict', 'custom'}, default: 'normal') – Algorithm for finding the location of the first beat (see Notes).
collect_onsets_only (bool, default: False) – True to collect only the onset of the notes (i.e. note on events) in all tracks, where the note off and duration information are discarded. False to parse regular piano rolls.
first_beat_time (float, optional) – Location of the first beat, in sec. Required and only effective when using ‘custom’ algorithm.
- Returns
Converted Multitrack object.
- Return type
Notes
There are three algorithms for finding the location of the first beat:
‘normal’ : Estimate the location of the first beat using
pretty_midi.PrettyMIDI.estimate_beat_start()
.‘strict’ : Set the location of the first beat to the time of the first time signature change. Raise a RuntimeError if no time signature change is found.
‘custom’ : Set the location of the first beat to the value of argument first_beat_time. Raise a ValueError if first_beat_time is not given.
If an incomplete beat before the first beat is found, an additional beat will be added before the (estimated) beat starting time. However, notes before the (estimated) beat starting time for more than one beat are dropped.
- pypianoroll.in_scale_rate(pianoroll: numpy.ndarray, root: int = 3, mode: str = 'major') float [source]
Return the ratio of pitches in a certain musical scale.
The pitch-in-scale rate is defined as the ratio of the number of notes in a certain scale to the total number of notes. Drum tracks are ignored. Return NaN if no note is found. This metric is used in [1].
\[pitch\_in\_scale\_rate = \frac{\#(notes\_in\_scale)}{\#(notes)}\]- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
root (int) – Root of the scale.
mode (str, {'major', 'minor'}) – Mode of the scale.
- Returns
Pitch-in-scale rate.
- Return type
float
See also
muspy.scale_consistency()
Compute the largest pitch-in-class rate.
References
Hao-Wen Dong, Wen-Yi Hsiao, Li-Chia Yang, and Yi-Hsuan Yang, “MuseGAN: Multi-track sequential generative adversarial networks for symbolic music generation and accompaniment,” in Proceedings of the 32nd AAAI Conference on Artificial Intelligence (AAAI), 2018.
- pypianoroll.load(path: Union[str, pathlib.Path]) pypianoroll.multitrack.Multitrack [source]
Load a NPZ file into a Multitrack object.
Supports only files previously saved by
pypianoroll.save()
.- Parameters
path (str or Path) – Path to the file to load.
See also
pypianoroll.save()
Save a Multitrack object to a NPZ file.
pypianoroll.read()
Read a MIDI file into a Multitrack object.
- pypianoroll.n_pitch_classes_used(pianoroll: numpy.ndarray) int [source]
Return the number of unique pitch classes used.
- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
- Returns
Number of unique pitch classes used.
- Return type
int
See also
pypianoroll.n_pitches_used()
Compute the number of unique pitches used.
- pypianoroll.n_pitches_used(pianoroll: numpy.ndarray) int [source]
Return the number of unique pitches used.
- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
- Returns
Number of unique pitch classes used.
- Return type
int
See also
pypianoroll.n_pitch_class_used()
Compute the number of unique pitch classes used.
- pypianoroll.pad(obj: pypianoroll.core.MultitrackOrTrackType, pad_length: int) pypianoroll.core.MultitrackOrTrackType [source]
Pad the piano roll(s).
Notes
The lengths of the resulting piano rolls are not guaranteed to be the same. See
pypianoroll.Multitrack.pad_to_same()
.- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.Track
) – Object to pad.pad_length (int) – Length to pad along the time axis.
- Returns
- Return type
Object itself.
See also
pypianoroll.pad_to_same()
Pad the piano rolls so that they have the same length.
pypianoroll.pad_to_multiple()
Pad the piano rolls so that their lengths are some multiples.
- pypianoroll.pad_to_multiple(obj: pypianoroll.core.MultitrackOrTrackType, factor: int) pypianoroll.core.MultitrackOrTrackType [source]
Pad the piano roll(s) so that their lengths are some multiples.
Pad the piano rolls at the end along the time axis of the minimum length that makes the lengths of the resulting piano rolls multiples of factor.
- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.Track
) – Object to pad.factor (int) – The value which the length of the resulting pianoroll(s) will be a multiple of.
- Returns
- Return type
Object itself.
Notes
Lengths of the resulting piano rolls are necessarily the same.
See also
pypianoroll.pad()
Pad the piano rolls.
pypianoroll.pad_to_same()
Pad the piano rolls so that they have the same length.
- pypianoroll.pad_to_same(obj: pypianoroll.core.MultitrackType) pypianoroll.core.MultitrackType [source]
Pad the piano rolls so that they have the same length.
Pad shorter piano rolls at the end along the time axis so that the resulting piano rolls have the same length.
- Parameters
obj (
pypianoroll.Multitrack
) – Object to pad.- Returns
- Return type
Object itself.
See also
pypianoroll.pad()
Pad the piano rolls.
pypianoroll.pad_to_multiple()
Pad the piano rolls so that their lengths are some multiples.
- pypianoroll.pitch_range(pianoroll) float [source]
Return the pitch range.
- Returns
Pitch range (in semitones), i.e., difference between the highest and the lowest active pitches.
- Return type
int or nan
See also
pypianoroll.pitch_range_tuple()
Return the pitch range as a tuple.
- pypianoroll.pitch_range_tuple(pianoroll) Tuple[float, float] [source]
Return the pitch range as a tuple (lowest, highest).
- Returns
int or nan – Highest active pitch.
int or nan – Lowest active pitch.
See also
pypianoroll.pitch_range()
Compute the pitch range.
- pypianoroll.plot(obj: Union[pypianoroll.track.Track, pypianoroll.multitrack.Multitrack], **kwargs) Union[List[matplotlib.axes._axes.Axes], matplotlib.axes._axes.Axes] [source]
Plot the object.
See
pypianoroll.plot_multitrack()
andpypianoroll.plot_track()
for full documentation.
- pypianoroll.plot_multitrack(multitrack: Multitrack, axs: Sequence[matplotlib.axes._axes.Axes] = None, mode: str = 'separate', track_label: str = 'name', preset: str = 'full', cmaps: Sequence[str] = None, xtick: str = 'auto', ytick: str = 'octave', xticklabel: bool = True, yticklabel: str = 'auto', tick_loc: Sequence[str] = ('bottom', 'left'), tick_direction: str = 'in', label: str = 'both', grid_axis: str = 'both', grid_linestyle: str = ':', grid_linewidth: float = 0.5, **kwargs) List[matplotlib.axes._axes.Axes] [source]
Plot the multitrack.
- Parameters
multitrack (
pypianoroll.Multitrack
) – Multitrack to plot.axs (sequence of
matplotlib.axes.Axes
, optional) – Axes to plot the tracks on.mode ({'separate', 'blended', 'hybrid'}, default: 'separate') – Plotting strategy for visualizing multiple tracks. For ‘separate’ mode, plot each track separately. For ‘blended’, blend and plot the pianoroll as a colored image. For ‘hybrid’ mode, drum tracks are blended into a ‘Drums’ track and all other tracks are blended into an ‘Others’ track.
track_label ({'name', 'program', 'family', 'off'}) – Track label format. When mode is ‘hybrid’, all options other than ‘off’ will label the two track with ‘Drums’ and ‘Others’.
preset ({'full', 'frame', 'plain'}, default: 'full') – Preset theme to use. For ‘full’ preset, ticks, grid and labels are on. For ‘frame’ preset, ticks and grid are both off. For ‘plain’ preset, the x- and y-axis are both off.
cmaps (tuple or list) – Colormaps. Will be passed to
matplotlib.pyplot.imshow()
. Only effective when pianoroll is 2D. Defaults to ‘Blues’. If mode is ‘separate’, defaults to (‘Blues’, ‘Oranges’, ‘Greens’, ‘Reds’, ‘Purples’, ‘Greys’). If mode is ‘blended’, defaults to (‘hsv’). If mode is ‘hybrid’, defaults to (‘Blues’, ‘Greens’).**kwargs – Keyword arguments to pass to
pypianoroll.plot_pianoroll()
.
- Returns
(Created) list of Axes objects.
- Return type
list of
matplotlib.axes.Axes
- pypianoroll.plot_pianoroll(ax: matplotlib.axes._axes.Axes, pianoroll: numpy.ndarray, is_drum: bool = False, resolution: Optional[int] = None, downbeats: Optional[numpy.ndarray] = None, preset: str = 'full', cmap: str = 'Blues', xtick: str = 'auto', ytick: str = 'octave', xticklabel: bool = True, yticklabel: str = 'auto', tick_loc: Sequence[str] = ('bottom', 'left'), tick_direction: str = 'in', label: str = 'both', grid_axis: str = 'both', grid_linestyle: str = ':', grid_linewidth: float = 0.5, **kwargs)[source]
Plot a piano roll.
- Parameters
ax (
matplotlib.axes.Axes
) – Axes to plot the piano roll on.pianoroll (ndarray, shape=(?, 128), (?, 128, 3) or (?, 128, 4)) – Piano roll to plot. For a 3D piano-roll array, the last axis can be either RGB or RGBA.
is_drum (bool, default: False) – Whether it is a percussion track.
resolution (int) – Time steps per quarter note. Required if xtick is ‘beat’.
downbeats (list) – Boolean array that indicates whether the time step contains a downbeat (i.e., the first time step of a bar).
preset ({'full', 'frame', 'plain'}, default: 'full') – Preset theme. For ‘full’ preset, ticks, grid and labels are on. For ‘frame’ preset, ticks and grid are both off. For ‘plain’ preset, the x- and y-axis are both off.
cmap (str or
matplotlib.colors.Colormap
, default: ‘Blues’) – Colormap. Will be passed tomatplotlib.pyplot.imshow()
. Only effective when pianoroll is 2D.xtick ({'auto', 'beat', 'step', 'off'}) – Tick format for the x-axis. For ‘auto’ mode, set to ‘beat’ if resolution is given, otherwise set to ‘step’. Defaults to ‘auto’.
ytick ({'octave', 'pitch', 'off'}, default: 'octave') – Tick format for the y-axis.
xticklabel (bool) – Whether to add tick labels along the x-axis.
yticklabel ({'auto', 'name', 'number', 'off'}, default: 'auto') – Tick label format for the y-axis. For ‘name’ mode, use pitch name as tick labels. For ‘number’ mode, use pitch number. For ‘auto’ mode, set to ‘name’ if ytick is ‘octave’ and ‘number’ if ytick is ‘pitch’.
tick_loc (sequence of {'bottom', 'top', 'left', 'right'}) – Tick locations. Defaults to (‘bottom’, ‘left’).
tick_direction ({'in', 'out', 'inout'}, default: 'in') – Tick direction.
label ({'x', 'y', 'both', 'off'}, default: 'both') – Whether to add labels to x- and y-axes.
grid_axis ({'x', 'y', 'both', 'off'}, default: 'both') – Whether to add grids to the x- and y-axes.
grid_linestyle (str) – Grid line style. Will be passed to
matplotlib.axes.Axes.grid()
.grid_linewidth (float) – Grid line width. Will be passed to
matplotlib.axes.Axes.grid()
.**kwargs – Keyword arguments to be passed to
matplotlib.axes.Axes.imshow()
.
- pypianoroll.plot_track(track: Track, ax: matplotlib.axes._axes.Axes = None, **kwargs) matplotlib.axes._axes.Axes [source]
Plot a track.
- Parameters
track (
pypianoroll.Track
) – Track to plot.ax (
matplotlib.axes.Axes
, optional) – Axes to plot the piano roll on. Defaults to call plt.gca().**kwargs – Keyword arguments to pass to
pypianoroll.plot_pianoroll()
.
- Returns
(Created) Axes object.
- Return type
- pypianoroll.polyphonic_rate(pianoroll: numpy.ndarray, threshold: float = 2) float [source]
Return the ratio of time steps where multiple pitches are on.
The polyphony rate is defined as the ratio of the number of time steps where multiple pitches are on to the total number of time steps. Drum tracks are ignored. Return NaN if song length is zero. This metric is used in [1], where it is called polyphonicity.
\[polyphony\_rate = \frac{ \#(time\_steps\_where\_multiple\_pitches\_are\_on) }{ \#(time\_steps) }\]- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
threshold (int) – Threshold of number of pitches to count into the numerator.
- Returns
Polyphony rate.
- Return type
float
References
Hao-Wen Dong, Wen-Yi Hsiao, Li-Chia Yang, and Yi-Hsuan Yang, “MuseGAN: Multi-track sequential generative adversarial networks for symbolic music generation and accompaniment,” in Proceedings of the 32nd AAAI Conference on Artificial Intelligence (AAAI), 2018.
- pypianoroll.qualified_note_rate(pianoroll: numpy.ndarray, threshold: float = 2) float [source]
Return the ratio of the number of the qualified notes.
The qualified note rate is defined as the ratio of the number of qualified notes (notes longer than threshold, in time steps) to the total number of notes. Return NaN if no note is found.
\[qualified\_note\_rate = \frac{ \#(notes\_longer\_than\_the\_threshold) }{ \#(notes) }\]- Parameters
pianoroll (ndarray) – Piano roll to evaluate.
threshold (int) – Threshold of note length to count into the numerator.
- Returns
Qualified note rate.
- Return type
float
References
Hao-Wen Dong, Wen-Yi Hsiao, Li-Chia Yang, and Yi-Hsuan Yang, “MuseGAN: Multi-track sequential generative adversarial networks for symbolic music generation and accompaniment,” in Proceedings of the 32nd AAAI Conference on Artificial Intelligence (AAAI), 2018.
- pypianoroll.read(path: Union[str, pathlib.Path], **kwargs) pypianoroll.multitrack.Multitrack [source]
Read a MIDI file into a Multitrack object.
- Parameters
path (str or Path) – Path to the file to read.
**kwargs – Keyword arguments to pass to
pypianoroll.from_pretty_midi()
.
See also
pypianoroll.write()
Write a Multitrack object to a MIDI file.
pypianoroll.load()
Load a NPZ file into a Multitrack object.
- pypianoroll.save(path: Union[str, pathlib.Path], multitrack: Multitrack, compressed: bool = True)[source]
Save a Multitrack object to a NPZ file.
- Parameters
path (str or Path) – Path to the NPZ file to save.
multitrack (
pypianoroll.Multitrack
) – Multitrack to save.compressed (bool, default: True) – Whether to save to a compressed NPZ file.
Notes
To reduce the file size, the piano rolls are first converted to instances of
scipy.sparse.csc_matrix
. The component arrays are then collected and saved to a npz file.See also
pypianoroll.load()
Load a NPZ file into a Multitrack object.
pypianoroll.write()
Write a Multitrack object to a MIDI file.
- pypianoroll.set_nonzeros(obj: Union[pypianoroll.multitrack.Multitrack, pypianoroll.track.StandardTrack, pypianoroll.track.BinaryTrack], value: int)[source]
Assign a constant value to all nonzeros entries.
- Parameters
obj (
pypianoroll.Multitrack
,pypianoroll.StandardTrack
orpypianoroll.BinaryTrack
) – Object to modify.value (int) – Value to assign.
- pypianoroll.set_resolution(obj: pypianoroll.core.MultitrackType, resolution: int, rounding: str = 'round') pypianoroll.core.MultitrackType [source]
Downsample the piano rolls by a factor.
- Parameters
obj (
pypianoroll.Multitrack
) – Object to downsample.resolution (int) – Target resolution.
rounding ({'round', 'ceil', 'floor'}, default: 'round') – Rounding mode.
- Returns
- Return type
Object itself.
- pypianoroll.to_pretty_midi(multitrack: Multitrack, default_tempo: float = None, default_velocity: int = 64) pretty_midi.pretty_midi.PrettyMIDI [source]
Return a Multitrack object as a PrettyMIDI object.
- Parameters
default_tempo (int, default: pypianoroll.DEFAULT_TEMPO (120)) – Default tempo to use. If attribute tempo is available, use its first element.
default_velocity (int, default: pypianoroll.DEFAULT_VELOCITY (64)) – Default velocity to assign to binarized tracks.
- Returns
Converted PrettyMIDI object.
- Return type
Notes
Tempo changes are not supported.
Time signature changes are not supported.
The velocities of the converted piano rolls will be clipped to [0, 127].
Adjacent nonzero values of the same pitch will be considered a single note with their mean as its velocity.
- pypianoroll.tonal_distance(pianoroll_1: numpy.ndarray, pianoroll_2: numpy.ndarray, resolution: int, radii: Sequence[float] = (1.0, 1.0, 0.5)) float [source]
Return the tonal distance [1] between the two input piano rolls.
- Parameters
pianoroll_1 (ndarray) – First piano roll to evaluate.
pianoroll_2 (ndarray) – Second piano roll to evaluate.
resolution (int) – Time steps per beat.
radii (tuple of float) – Radii of the three tonal circles (see Equation 3 in [1]).
References
Christopher Harte, Mark Sandler, and Martin Gasser, “Detecting harmonic change in musical audio,” in Proceedings of the 1st ACM workshop on Audio and music computing multimedia, 2006.
- pypianoroll.transpose(obj: pypianoroll.core.MultitrackOrTrackType, semitone: int) pypianoroll.core.MultitrackOrTrackType [source]
Transpose the piano roll(s) by a number of semitones.
Positive values are for a higher key, while negative values are for a lower key. Drum tracks are ignored.
- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.Track
) – Object to transpose.semitone (int) – Number of semitones to transpose. A positive value raises the pitches, while a negative value lowers the pitches.
- Returns
- Return type
Object itself.
- pypianoroll.trim(obj: pypianoroll.core.MultitrackOrTrackType, start: Optional[int] = None, end: Optional[int] = None) pypianoroll.core.MultitrackOrTrackType [source]
Trim the trailing silences of the piano roll(s).
- Parameters
obj (
pypianoroll.Multitrack
orpypianoroll.Track
) – Object to trim.start (int, default: 0) – Start time.
end (int, optional) – End time. Defaults to active length.
- Returns
- Return type
Object itself.
- pypianoroll.write(path: str, multitrack: Multitrack)[source]
Write a Multitrack object to a MIDI file.
- Parameters
path (str) – Path to write the file.
multitrack (
pypianoroll.Multitrack
) – Multitrack to save.
See also
pypianoroll.read()
Read a MIDI file into a Multitrack object.
pypianoroll.save()
Save a Multitrack object to a NPZ file.