Embedder
- class music_embedding.embedder.embedder(pianoroll=None, intervals=None, default_velocity=100, origin=60, pixels_per_bar=96)[source]
Bases:
object
A class for embedding musical data, providing functionalities to convert between pianoroll representations and interval-based representations.
This class handles various operations related to musical data manipulation, including extracting notes from pianorolls, converting pianoroll data to melodic, harmonic, and barwise intervals, and vice versa. Additionally, it supports Run-Length Encoding (RLE) compression for intervals.
The constant NOTES_IN_MIDI is set to 128, reflecting the total number of MIDI notes in the standard MIDI range. This constant is used throughout the class to standardize the size of the second dimension in pianoroll arrays, ensuring they conform to MIDI standards. The pianoroll arrays are therefore structured with a shape of (?, 128), where each column represents a possible MIDI note, allowing for a consistent representation of musical data.
See also
interval
Class used for interval-related calculations.
- Attributes:
- pianorollndarray, dtype=uint8, shape=(?, 128), optional
Pianoroll representation of musical data. The first dimension represents timesteps, and the second dimension has a fixed size of 128, corresponding to MIDI standards.
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions), optional
Interval representation of musical data. The first dimension represents timesteps, and the second dimension corresponds to interval features.
- default_velocityint
Default velocity used for notes in pianoroll representation. Defaults to 100.
- originint
Reference note for melody, used as the starting note when decoding a melody. Defaults to 60 (Middle C in MIDI)
- pixels_per_barint
Number of pixels representing each bar in a pianoroll, calculated as the time signature’s numerator multiplied by the resolution per pixel. Defaults to 96.
Methods
chunk_sequence_of_intervals
([intervals, ...])Breaks a long sequence of intervals into chunks of a specified length.
Extracts the highest pitch note at each timestep from the pianoroll attribute.
get_RLE_from_intervals
([intervals])Compresses a sequence of intervals using Run-Length Encoding (RLE).
get_RLE_from_intervals_bulk
(bulk_intervals)Bulk compresses a sequence of intervals using Run-Length Encoding (RLE).
Creates a sequence of barwise intervals from a pianoroll, calculating intervals with respect to the first note of each bar.
get_harmonic_intervals_from_pianoroll
(...[, ...])Creates a sequence of harmonic intervals from the pianoroll relative to a reference pianoroll.
get_intervals_from_RLE
(RLE_data)Uncompresses a Run-Length Encoded sequence of intervals.
get_intervals_from_RLE_bulk
(bulk_RLE_data)Bulk uncompresses a sequence of Run-Length Encoded intervals.
get_melodic_intervals_from_pianoroll
([pianoroll])Creates a sequence of melodic intervals from a pianoroll.
Creates a pianoroll from a sequence of barwise intervals.
Creates a pianoroll from a sequence of harmonic intervals.
Creates a pianoroll from a sequence of melodic intervals.
merge_chunked_intervals
(chunked_intervals)Merges chunks of interval sequences into a single sequence.
- chunk_sequence_of_intervals(intervals: ndarray | None = None, pixels_per_chunk: int | None = None) ndarray [source]
Breaks a long sequence of intervals into chunks of a specified length.
This method divides a sequence of intervals into smaller, equally-sized chunks, which can be useful for processing or analyzing data in segments. If intervals is None, the method works on self.intervals.
- Parameters:
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions)
Sequence of intervals to be chunked. If None, uses self.intervals.
- pixels_per_chunkint
Number of pixels in each chunk. Defaults to self.pixels_per_bar if None.
- Returns:
- ndarray, dtype=int8
Array of chunked intervals. Shape is (?, pixels_per_chunk, interval.feature_dimensions), where ? is the number of chunks.
- Raises:
- TypeError
If both intervals argument and self.intervals are None.
- IndexError
If intervals shape’s second dimension is not equal to interval.feature_dimensions.
- ValueError
If pixels_per_chunk is less than 1 or if it’s None and self.pixels_per_bar is less than 1.
- extract_highest_pitch_notes_from_pianoroll(preserve_pianoroll: bool = True) ndarray [source]
Extracts the highest pitch note at each timestep from the pianoroll attribute.
This method processes the self.pianoroll array to find the highest pitch note for each timestep. It can operate in either a non-destructive mode, preserving the original pianoroll, or a faster, destructive mode that alters the original data.
Example: Given the pianoroll of an SATB choir, returns Soprano notes.
- Parameters:
- preserve_pianorollbool, optional
Determines if self.pianoroll should be preserved. Setting it to False increases performance by avoiding data copying. Default is True.
- Returns:
- ndarray, dtype=int64, shape=(?)
An array containing the highest pitch note at each timestep. Indicates silence with a value of 0.
- Raises:
- TypeError
If self.pianoroll is None.
- IndexError
If self.pianoroll does not have the second dimension size of 128.
Notes
The method operates on self.pianoroll and requires it to be filled before calling. The pianoroll format is expected to conform to MIDI standards with 128 pitches.
- get_RLE_from_intervals(intervals: ndarray | None = None) ndarray [source]
Compresses a sequence of intervals using Run-Length Encoding (RLE).
This method takes a sequence of intervals and compresses it using RLE, which is useful for reducing the size of repetitive data. The output is an array where each row represents a compressed sequence of intervals, and the last column in each row indicates the number of repetitions.
- Parameters:
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions) | None, optional
The sequence of intervals to be compressed. If None, uses self.intervals.
- Returns:
- ndarray, dtype=int32, shape=(?, interval.feature_dimensions + 1)
The RLE compressed intervals. Each row contains the compressed interval data with the last element indicating the count of repetitions.
- Raises:
- TypeError
If both intervals argument and self.intervals are None.
- IndexError
If intervals.shape[1] != interval.feature_dimensions (if intervals is None, then self.intervals.shape[1] is checked).
- get_RLE_from_intervals_bulk(bulk_intervals: ndarray) List[ndarray] [source]
Bulk compresses a sequence of intervals using Run-Length Encoding (RLE).
This method processes multiple sequences of intervals simultaneously, applying RLE compression to each sequence in the bulk data. It is useful for handling large datasets where individual processing would be inefficient.
- Parameters:
- bulk_intervalsndarray
An array containing multiple sequences of intervals, with shape (n_chunks, chunk_size, interval.feature_dimensions). Each sequence (chunk) in the first dimension will be compressed using RLE.
- Returns:
- List[ndarray]
A list of RLE-compressed interval sequences, where each element in the list corresponds to the RLE representation of a chunk in bulk_intervals. Each ndarray in the list has shape (?, interval.feature_dimensions + 1), where the last dimension includes the run lengths.
See also
get_RLE_from_intervals
Compresses a single sequence of intervals using Run-Length Encoding.
get_intervals_from_RLE_bulk
Bulk decompresses Run-Length Encoded interval sequences.
- get_barwise_intervals_from_pianoroll(pianoroll: ndarray | None = None, pixels_per_bar: int | None = None) ndarray [source]
Creates a sequence of barwise intervals from a pianoroll, calculating intervals with respect to the first note of each bar. For the first notes of bars, intervals are calculated with respect to the first note of the previous bar.
- Parameters:
- pianorollndarray, dtype=uint8, shape=(?, 128) | None, optional
Pianoroll representation of musical data. If not provided, self.pianoroll is used. The first dimension represents timesteps, and the second dimension has a fixed size of 128, corresponding to MIDI standards.
- pixels_per_barint | None, optional
Number of pixels in each bar, equal to the time signature’s numerator multiplied by the resolution per pixel. If not provided, self.pixels_per_bar is used.
- Returns:
- ndarray, dtype=int8, shape=(?, interval.feature_dimensions)
Interval representation of musical data. The first dimension represents timesteps, and the second dimension corresponds to interval features.
- Raises:
- TypeError
If both pianoroll argument and self.pianoroll are None.
- IndexError
If pianoroll.shape[1] != 128.
- ValueError
If pixels_per_bar < 1 or if pixels_per_bar is None and self.pixels_per_bar < 1.
- get_harmonic_intervals_from_pianoroll(ref_pianoroll: ndarray, pianoroll: ndarray | None = None) ndarray [source]
Creates a sequence of harmonic intervals from the pianoroll relative to a reference pianoroll.
This method computes harmonic intervals of the highest pitch notes in self.pianoroll with respect to ref_pianoroll. It updates self.pianoroll if pianoroll argument is passed and also updates self.intervals.
- Parameters:
- ref_pianorollndarray, dtype=uint8, shape=(?, 128)
Reference pianoroll to which harmonic intervals are calculated.
- pianorollndarray, dtype=uint8, shape=(?, 128) | None, default=None
Pianoroll for which to calculate harmonic intervals. If None, uses self.pianoroll.
- Returns:
- ndarray, dtype=int8, shape=(?, interval.feature_dimensions)
Array of harmonic intervals. First dimension represents timesteps, and the second dimension corresponds to interval features.
- Raises:
- TypeError
If both pianoroll argument and self.pianoroll are None.
- IndexError
If pianoroll.shape[1] is not 128 or if ref_pianoroll.shape[1] is not 128.
- get_intervals_from_RLE(RLE_data: ndarray) ndarray [source]
Uncompresses a Run-Length Encoded sequence of intervals.
This method takes a Run-Length Encoded (RLE) array representing a sequence of intervals and decompresses it to obtain the original sequence of intervals.
- Parameters:
- RLE_datandarray, dtype=int32, shape=(?, interval.feature_dimensions + 1)
Compressed intervals using Run-Length Encoding. The last element in each row indicates the number of repetitions for the interval.
- Returns:
- ndarray, dtype=int8, shape=(?, interval.feature_dimensions)
Decompressed sequence of intervals. The first dimension represents timesteps, and the second dimension corresponds to interval features.
- get_intervals_from_RLE_bulk(bulk_RLE_data: List[ndarray]) ndarray [source]
Bulk uncompresses a sequence of Run-Length Encoded intervals.
This method uncompresses multiple sequences of intervals that have been compressed using Run-Length Encoding (RLE). It processes a list of RLE-compressed data and returns the uncompressed intervals in bulk.
- Parameters:
- bulk_RLE_dataList[np.ndarray]
A list of RLE-compressed data, where each element is an ndarray with the shape (?, interval.feature_dimensions + 1). The last element in each row indicates the number of repetitions for the rest of the elements in the row.
- Returns:
- np.ndarray
An ndarray of uncompressed intervals. The shape of the output array is (?, pixels_per_chunk, interval.feature_dimensions), where the first dimension represents chunks, the second dimension represents pixels in each chunk, and the third dimension represents interval features.
Notes
The output size is inferred from the first chunk in the bulk RLE data.
- get_melodic_intervals_from_pianoroll(pianoroll: ndarray | None = None) ndarray [source]
Creates a sequence of melodic intervals from a pianoroll.
This method calculates the melodic intervals of the highest pitch notes in the pianoroll. If a pianoroll is provided as an argument, it updates self.pianoroll with this new data. The resulting intervals are stored in self.intervals.
Example: Given the pianoroll of an SATB choir, returns melodic intervals of Soprano.
- Parameters:
- pianorollndarray, dtype=uint8, shape=(?, 128), optional
Pianoroll to be processed. If not provided, the method uses self.pianoroll. The first dimension represents timesteps, and the second dimension is fixed to 128, corresponding to MIDI standards.
- Returns:
- ndarray, dtype=int8, shape=(?, interval.feature_dimensions)
Array of melodic intervals. The first dimension represents timesteps, and the second dimension corresponds to interval features.
- Raises:
- TypeError
If both the pianoroll argument and self.pianoroll are None.
- IndexError
If the provided pianoroll (or self.pianoroll if pianoroll is None) does not have a second dimension of size 128.
- get_pianoroll_from_barwise_intervals(intervals: ndarray | None = None, origin: int | None = None, velocity: int | None = None, leading_silence: int = 0, pixels_per_bar: int | None = None) ndarray [source]
Creates a pianoroll from a sequence of barwise intervals.
This method decodes barwise interval data into a pianoroll representation, considering each bar’s first note and the intervals following it. It supports specifying the origin note, velocity, leading silence, and pixels per bar.
- Parameters:
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions), default=None
Sequence of barwise intervals. Uses self.intervals if None.
- originint, default=None
Reference note for the melody (MIDI value). Uses self.origin if None.
- velocityint, default=None
Velocity for notes in the pianoroll. Uses self.default_velocity if None.
- leading_silenceint, default=0
Number of silent pixels at the beginning of the melody.
- pixels_per_barint, default=None
Number of pixels in each bar. Uses self.pixels_per_bar if None.
- Returns:
- ndarray, dtype=uint8, shape=(?, 128)
Pianoroll representation with each timestep and MIDI note.
- Raises:
- ValueError
If pixels_per_bar is less than 1 or leading_silence is greater than or equal to the length of intervals.
- IndexError
If origin or velocity is out of MIDI range (0-127), or if note calculations lead to values outside this range.
- get_pianoroll_from_harmonic_intervals(pianoroll: ndarray | None = None, intervals: ndarray | None = None, velocity: int | None = None) ndarray [source]
Creates a pianoroll from a sequence of harmonic intervals.
This method builds a new pianoroll based on the highest pitch notes extracted from the provided or class’s pianoroll and the harmonic intervals stored in the class’s intervals.
Example: Given ATB choir pianoroll and Soprano’s harmonic intervals with respect to Alto, returns Soprano’s pianoroll.
- Parameters:
- pianorollndarray, dtype=uint8, shape=(?, 128) | None, optional
Pianoroll representation of musical data to be used. If None, the method uses self.pianoroll.
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions) | None, optional
Sequence of harmonic intervals. If None, the method uses self.intervals.
- velocityint | None, optional
Velocity for notes in the pianoroll. If None, self.default_velocity is used.
- Returns:
- ndarray, dtype=uint8, shape=(?, 128)
The generated pianoroll, where the first dimension is timesteps and the second dimension is fixed to 128 per MIDI standard.
- Raises:
- TypeError
If both pianoroll argument and self.pianoroll are None.
- IndexError
If pianoroll.shape[1] != 128, or if intervals.shape[1] != interval.feature_dimensions, or if adding the interval to the pianoroll leads to a note out of MIDI range (0-127), or if velocity is out of MIDI range (0-127).
- get_pianoroll_from_melodic_intervals(intervals: ndarray | None = None, origin: int | None = None, velocity: int | None = None, leading_silence: int = 0) ndarray [source]
Creates a pianoroll from a sequence of melodic intervals.
This method generates a pianoroll representation of a melody based on the provided sequence of melodic intervals. The origin note is used as the starting point for the melody, and the specified velocity is applied to the notes.
- Parameters:
- intervalsndarray, dtype=int8, shape=(?, interval.feature_dimensions), optional
Sequence of melodic intervals. If None, the method uses self.intervals. Each row represents interval features for a timestep.
- originint, optional
The reference note of the melody; used as the starting note for decoding the melody. Defaults to self.origin if None.
- velocityint, optional
Velocity used for notes in the pianoroll. Defaults to self.default_velocity if None.
- leading_silenceint, optional
Number of silent pixels at the beginning of the melody. Defaults to 0.
- Returns:
- ndarray, dtype=uint8, shape=(?, 128)
Pianoroll representation of the melody. The first dimension represents timesteps, and the second dimension is fixed to 128, corresponding to MIDI standards.
- Raises:
- TypeError
If both intervals argument and self.intervals are None.
- IndexError
If intervals.shape[1] != interval.feature_dimensions or if the sequence of given intervals leads to a note outside the MIDI range (0-127).
- ValueError
If leading_silence is greater than or equal to the number of intervals.
- merge_chunked_intervals(chunked_intervals: ndarray) ndarray [source]
Merges chunks of interval sequences into a single sequence.
This method flattens a 3D array of chunked intervals into a 2D array, where the first dimension represents the total timesteps and the second dimension represents interval features. It is useful for reassembling interval data that was previously divided into chunks.
- Parameters:
- chunked_intervalsndarray
A 3D array of chunked intervals, with shape (num_chunks, chunk_size, interval.feature_dimensions). Each chunk represents a portion of the interval sequence.
- Returns:
- ndarray
A 2D array of merged intervals, with shape (num_timesteps, interval.feature_dimensions). Represents the entire sequence of intervals as a single continuous array.