scamp.performance.Performance
- class scamp.performance.Performance(parts: Optional[Sequence[PerformancePart]] = None, tempo_envelope: Optional[TempoEnvelope] = None)[source]
Bases:
SavesToJSON
,_NoteFiltersMixin
Representation of note playback events, usually a transcription of the notes played by an
Ensemble
. Operates in continuous time, without regard to any particular way of notating it. (As opposed to aScore
, which represents the notated music.)- Parameters:
parts – list of parts (
PerformancePart
objects) to start with (defaults to empty list)tempo_envelope – a tempo_envelope to associate with this performance
- Variables:
parts – list of parts (
PerformancePart
objects) in this Performancetempo_envelope – the tempo_envelope associated this performance and used for playback by default
Methods
add_part
(part)Add the given PerformancePart to this performance
export_to_midi_file
(output_file[, ...])Exports the Performance to a MIDI file.
get_note_iterator
([start_beat, stop_beat, ...])Returns an iterator returning all the notes from start_beat to stop_beat in the selected voices, in all parts.
get_part_by_index
(index)Get the part with the given index (Parts are numbered starting with 0, in order that they are added/created.)
get_parts_by_instrument
(instrument)Get all parts with the given instrument
get_parts_by_name
(name)Get all parts with the given name
Checks if this Performance has been quantized
length
()Total length of this performance.
new_part
([instrument])Construct and add a new PerformancePart to this Performance
If this Performance has been quantized, gets the number of measures
play
([start_beat, stop_beat, ensemble, ...])Play back this Performance (or a selection of it)
quantize
([quantization_scheme, ...])Quantizes all parts according to the quantization_scheme
quantized
([quantization_scheme, ...])Same as quantize, except that it returns a new copy, rather than changing this Performance in place.
remap_to_tempo
(tempo)Remaps this performance to use the given tempo or tempo envelope.
set_instruments_from_ensemble
(ensemble[, ...])Set the playback instruments for each part in this Performance by their best match in the ensemble given.
to_score
([quantization_scheme, ...])Convert this Performance (list of note events in continuous time and pitch) to a Score object, which represents the music in traditional western notation.
Inherited Methods
apply_note_filter
(filter_function[, ...])Applies a filter function to every note in this Performance.
apply_pitch_filter
(filter_function[, ...])Applies a filter function to transform the pitch of every note in this Performance.
apply_volume_filter
(filter_function[, ...])Applies a filter function to transform the volume of every note in this Performance.
Returns a copy of this object by serializing to and from JSON.
Dump this object as a JSON string.
json_loads
(s)Load this object from a JSON string.
load_from_json
(file_path)Load this object from a JSON file with the given path.
save_to_json
(file_path)Save this object to a JSON file using the given path.
transpose
(interval)Transposes all notes in this Performance up or down by the desired interval.
Attributes
The end beat of this performance.
- new_part(instrument: Optional[ScampInstrument] = None) PerformancePart [source]
Construct and add a new PerformancePart to this Performance
- Parameters:
instrument – the instrument to use as a default for playing back the part
- Returns:
the newly constructed part
- add_part(part: PerformancePart) None [source]
Add the given PerformancePart to this performance
- Parameters:
part – a PerformancePart to add
- get_part_by_index(index: int) PerformancePart [source]
Get the part with the given index (Parts are numbered starting with 0, in order that they are added/created.)
- Parameters:
index – the index of the part in question
- Returns:
the PerformancePart
- get_parts_by_name(name: str) Sequence[PerformancePart] [source]
Get all parts with the given name
- Parameters:
name – the part name to search for
- Returns:
a list of parts with this name
- get_parts_by_instrument(instrument: ScampInstrument) Sequence[PerformancePart] [source]
Get all parts with the given instrument
- Parameters:
instrument – the instrument to search for
- Returns:
a list of parts with this instrument
- property end_beat: float
The end beat of this performance. (i.e. the beat corresponding to the end of the last note)
- Returns:
float representing the beat at which all notes are done playing
- length() float [source]
Total length of this performance. (Identical to Performance.end_beat)
- Returns:
float representing the total length of the Performance
- get_note_iterator(start_beat: float = 0, stop_beat: Optional[float] = None, selected_voices: Optional[Sequence[str]] = None) Iterator[PerformanceNote] [source]
Returns an iterator returning all the notes from start_beat to stop_beat in the selected voices, in all parts. In order of start time, jumping from part to part as needed.
- Parameters:
start_beat – beat to start on
stop_beat – beat to stop on (None keeps going until the end of the part)
selected_voices – which voices to take notes from (defaults to all if None)
- Returns:
an iterator
- remap_to_tempo(tempo: TempoEnvelope | float)[source]
Remaps this performance to use the given tempo or tempo envelope. All notes will happen at the same time, but on different beats.
- Parameters:
tempo – the new tempo envelope to use
- Returns:
self, for chaining purposes
- play(start_beat: float = 0, stop_beat: Optional[float] = None, ensemble: Ensemble = 'auto', clock: Clock = 'auto', blocking: bool = True, tempo_envelope: TempoEnvelope = 'auto', note_filter: Optional[Callable[[PerformanceNote], PerformanceNote]] = None) Clock [source]
Play back this Performance (or a selection of it)
- Parameters:
start_beat – Place to start playing from
stop_beat – Place to stop playing at
ensemble – The Ensemble whose instruments to use for playback. If “auto”, checks to see if we are operating in a particular Session, and uses those instruments if so.
clock – clock to use for playback
blocking – if True, don’t return until the part is done playing; if False, return immediately
tempo_envelope – the TempoEnvelope with which to play back this performance. The default value of “auto” uses the tempo_envelope associated with the performance, and None uses a flat tempo of rate 60bpm
note_filter – a function that takes the PerformanceNote about to be played and returns a modified PerformanceNote to play. NB: this will modify the original note unless the input to the function is duplicated and left unaltered!
- Returns:
the clock on which this performance is playing back
- set_instruments_from_ensemble(ensemble: Ensemble, override: bool = True) Performance [source]
Set the playback instruments for each part in this Performance by their best match in the ensemble given. If override is False, only set the instrument for parts that don’t already have one set.
- Parameters:
ensemble – the Ensemble in which to search for instruments
override – Whether or not to override any instruments already assigned to parts
- Returns:
self
- quantize(quantization_scheme: QuantizationScheme = 'default', onset_weighting: float = 'default', termination_weighting: float = 'default') Performance [source]
Quantizes all parts according to the quantization_scheme
- Parameters:
quantization_scheme – the QuantizationScheme to use. If “default”, uses the default time signature defined in the quantization_settings.
onset_weighting – how much to weight note onsets in the quantization. If “default”, uses the default value defined in the quantization_settings.
termination_weighting – how much to weight note terminations in the quantization. If “default”, uses the default value defined in the quantization_settings.
- Returns:
this Performance, having been quantized
- quantized(quantization_scheme: QuantizationScheme = 'default', onset_weighting: float = 'default', termination_weighting: float = 'default') Performance [source]
Same as quantize, except that it returns a new copy, rather than changing this Performance in place.
- Parameters:
quantization_scheme – the QuantizationScheme to use. If “default”, uses the default time signature defined in the quantization_settings.
onset_weighting – how much to weight note onsets in the quantization. If “default”, uses the default value defined in the quantization_settings.
termination_weighting – how much to weight note terminations in the quantization. If “default”, uses the default value defined in the quantization_settings.
- Returns:
a quantized copy of this Performance
- is_quantized() bool [source]
Checks if this Performance has been quantized
- Returns:
True if all parts are quantized, False if not
- num_measures() int [source]
If this Performance has been quantized, gets the number of measures
- Returns:
number of measures
- export_to_midi_file(output_file, flatten_tempo_changes=False, max_channels: int = 16, ring_time: float = 0.5, pitch_bend_range: float = 2, envelope_precision: float = 0.01, tempo_precision: float = 0.1)[source]
Exports the Performance to a MIDI file.
- Parameters:
output_file – path of the MIDI file to create and write to.
flatten_tempo_changes – If True, then everything is flattened to a tempo of 60bpm, and notes at a faster tempo are simply made shorter. If False, tempo changes are exported as part of the MIDI file.
max_channels – maximum number of channels to use for different notes. By default, notes with different pitch bends and cc messages will be placed on different channels to avoid interference.
ring_time – When multiple channels are used for juggling different pitch bends and cc messages, channels are reused when the notes on them have finished. However, if they’re reused right away, this can cause the note that just finished and is perhaps ringing/reverberating to get altered undesirably. ring_time is the amount of time that we wait before reassigning a channel.
pitch_bend_range – By default +- 2 semitones. If a greater pitch bend is needed, this parameter will scale all pitch bend messages accordingly. It will also attempt to send RPN messages to let the synthesizer know, though in practice many softsynths ignore this and will need to have their pitch bend range set manually.
envelope_precision – For glissandi, volume curves, and any other parameter that is being given an
Envelope
, this is the temporal precision of the corresponding midi events.tempo_precision – if flatten_tempo_changes is False, then this determines the precision of tempo change MIDI events during gradual accelerandi/ritardandi.
- apply_note_filter(filter_function: Callable[[PerformanceNote], None], start_beat: float = 0, stop_beat: Optional[float] = None, selected_voices: Optional[Sequence[str]] = None)
Applies a filter function to every note in this Performance. This can be used to apply a transformation to the entire Performance on a note-by-note basis.
- Parameters:
filter_function – function taking a PerformanceNote object and modifying it in place
start_beat – beat to start on
stop_beat – beat to stop on (None keeps going until the end of the part)
selected_voices – which voices to take notes from (defaults to all if None)
- Returns:
self, for chaining purposes
- apply_pitch_filter(filter_function: Callable[[Envelope | float], Envelope | float], start_beat: float = 0, stop_beat: Optional[float] = None, selected_voices: Optional[Sequence[str]] = None)
Applies a filter function to transform the pitch of every note in this Performance.
- Parameters:
filter_function – function taking a pitch (can be envelope, float, or even a chord tuple) and returning another pitch-like object. If the performance hasn’t been quantized and you’re not using any glissandi, though, you can assume the pitch is a float.
start_beat – beat to start on
stop_beat – beat to stop on (None keeps going until the end of the part)
selected_voices – which voices to take notes from (defaults to all if None)
- Returns:
self, for chaining purposes
- apply_volume_filter(filter_function: Callable[[Envelope | float], Envelope | float], start_beat: float = 0, stop_beat: Optional[float] = None, selected_voices: Optional[Sequence[str]] = None)
Applies a filter function to transform the volume of every note in this Performance.
- Parameters:
filter_function – function taking a volume (can be envelope or float) and returning another volume-like object. If you haven’t used any envelopes, though, you can assume the pitch is a float.
start_beat – beat to start on
stop_beat – beat to stop on (None keeps going until the end of the part)
selected_voices – which voices to take notes from (defaults to all if None)
- Returns:
self, for chaining purposes
- duplicate() T
Returns a copy of this object by serializing to and from JSON.
- json_dumps() str
Dump this object as a JSON string. This uses a custom encoder that recognizes and appropriately converts any attributes that are object inheriting from SavesToJSON.
- classmethod json_loads(s: str) T
Load this object from a JSON string. This uses a custom decoder that looks for a “_type” key in any object/dictionary being parsed and converts it to the class specified (assuming it a subclass of SavesToJSON).
- Parameters:
s – a string representing this object in JSON format
- classmethod load_from_json(file_path: str) T
Load this object from a JSON file with the given path. This uses a custom decoder that looks for a “_type” key in any object/dictionary being parsed and converts it to the class specified (assuming it a subclass of SavesToJSON).
- Parameters:
file_path – path for loading the file
- save_to_json(file_path: str) None
Save this object to a JSON file using the given path. This uses a custom encoder that recognizes and appropriately converts any attributes that are object inheriting from SavesToJSON.
- Parameters:
file_path – path for saving the file
- to_score(quantization_scheme: Optional[QuantizationScheme] = None, time_signature: Optional[Union[str, Sequence]] = None, bar_line_locations: Optional[Sequence[float]] = None, max_divisor: Optional[int] = None, max_divisor_indigestibility: Optional[int] = None, simplicity_preference: Optional[float] = None, title: str = 'default', composer: str = 'default') Score [source]
Convert this Performance (list of note events in continuous time and pitch) to a Score object, which represents the music in traditional western notation. In the process, the music must be quantized, for which two different options are available: one can either pass a QuantizationScheme to the first argument, which is very flexible but rather verbose to create, or one can specify arguments such as time signature and max divisor directly.
- Parameters:
quantization_scheme – The quantization scheme to be used when converting this performance into a score. If this is defined, none of the other quantization-related arguments should be defined.
time_signature – the time signature to be used, represented as a string, e.g. “3/4”, or a tuple, e.g. (3, 2). Alternatively, a list of time signatures can be given. If this list ends in “loop”, then the pattern specified by the list will be looped. For example, [“4/4”, “2/4”, “3/4”, “loop”] will cause the fourth measure to be in “4/4”, the fifth in “2/4”, etc. If the list does not end in “loop”, all measures after the final time signature specified will continue to be in that time signature.
bar_line_locations – As an alternative to defining the time signatures, a list of numbers representing the bar line locations can be given. For instance, [4.5, 6.5, 8, 11] would result in bars of time signatures 9/8, 2/4, 3/8, and 3/4
max_divisor – The largest divisor that will be allowed to divide the beat.
max_divisor_indigestibility – Indigestibility, devised by composer Clarence Barlow, is a measure of the “primeness” of a beat divisor, and therefore of its complexity from the point of view of a performer. For instance, it is easier to divide a beat in 8 than in 7, even though 7 is a smaller number. See Clarence’s paper here: https://mat.ucsb.edu/Publications/Quantification_of_Harmony_and_Metre.pdf. By setting a max indigestibility, we can allow larger divisions of the beat, but only so long as they are easy ones. For instance, a max_divisor of 16 and a max_divisor_indigestibility of 8 would allow the beat to be divided in 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, and 16.
simplicity_preference – This defines the degree to which the quantizer will favor simple divisors. The higher the simplicity preference, the more precisely the notes have to fit for you to get a divisor like 7. Simplicity preference can range from 0 (in which case the divisor is chosen purely based on the lowest error) to infinity, with a typical value somewhere around 1.
title – Title of the piece to be printed on the score.
composer – Composer of the piece to be printed on the score.
- Returns:
the resulting Score object, which can then be rendered either as XML or LilyPond
- transpose(interval: float)
Transposes all notes in this Performance up or down by the desired interval. For greater flexibility, use the
apply_pitch_filter
andapply_note_filter
methods.- Parameters:
interval – the interval by which to transpose this Performance
- Returns:
self, for chaining purposes