scamp_extensions.utilities.time_varying_parameter.TimeVaryingParameter

class scamp_extensions.utilities.time_varying_parameter.TimeVaryingParameter(levels: Sequence = (0,), durations: Sequence[float] = (), curve_shapes: Optional[Sequence[Union[float, str]]] = None, offset: float = 0, clock: Optional[Clock] = None, units: str = 'beats')[source]

Bases: Envelope

A simple wrapper around Envelope that is aware of the current time or beat in the current clock. Simply call it like a function to get its value at the current time or beat.

Parameters:
  • levels – see Envelope

  • durations – see Envelope

  • curve_shapes – see Envelope

  • offset – see Envelope

  • clock – the clock whose time/beat this TimeVaryingParameter uses for lookup. Defaults to the current active clock.

  • units – either “beats” or “time”; whether or not to use the time or the beat of the clock to look up the parameter value

Methods

adsr(attack_length, attack_level, ...[, ...])

Same as adsr(), but taking an optional clock and units parameter.

ar(attack_length, release_length[, ...])

Same as ar(), but taking an optional clock and units parameter.

asr(attack_length, sustain_level, ...[, ...])

Same as asr(), but taking an optional clock and units parameter.

finished()

from_function(function[, domain_start, ...])

Same as from_function(), but taking an optional clock and units parameter.

from_levels(levels[, length, offset, clock, ...])

Same as from_levels(), but taking an optional clock and units parameter.

from_levels_and_durations(levels, durations)

Same as from_levels_and_durations(), but taking an optional clock and units parameter.

from_list(constructor_list[, clock, units])

Same as from_list(), but taking an optional clock and units parameter.

from_points(*points[, clock, units])

Same as from_points(), but taking an optional clock and units parameter.

from_segments(segments[, clock, units])

Same as from_segments(), but taking an optional clock and units parameter.

release(duration[, start_level, ...])

Same as release(), but taking an optional clock and units parameter.

Inherited Methods

append_envelope(envelope_to_append)

Extends this envelope by another one (shifted to start at the end of this one).

append_segment(level, duration[, ...])

Append a segment to the end of the curve ending at level and lasting for duration.

average_level([t_range])

Returns the average value that the Envelope takes over the given range.

duplicate()

Returns a copy of this object by serializing to and from JSON.

end_level()

Ending value of the Envelope

end_time()

End of the domain on which this Envelope is defined.

get_upper_integration_bound(t1, desired_area)

Given a lower integration bound, find the upper bound that will result in the desired integral

insert(t, level[, curve_shape_in, ...])

Insert a curve point at time t, and set the shape of the curve into and out of it.

insert_interpolated(t[, min_difference])

Insert another curve point at the given time, without changing the shape of the curve.

integrate_interval(t1, t2)

Get the definite integral under this Envelope from t1 to t2

is_shifted_version_of(other[, tolerance])

Determines if this segment is simply a shifted version of another segment

json_dumps()

Dump this object as a JSON string.

json_loads(s)

Load this object from a JSON string.

length()

The length of the domain on which this Envelope is defined (end time minus start time).

load_from_json(file_path)

Load this object from a JSON file with the given path.

local_extrema([include_saddle_points])

Returns a list of the times where the curve changes direction.

max_absolute_slope()

Returns the maximum absolute value of the slope over the entire Envelope.

max_level([t_range])

Returns the highest value that the Envelope takes over the given range.

min_level([t_range])

Returns the lowest value that the Envelope takes over the given range.

normalize_to_duration(desired_duration[, ...])

Stretch or squeeze the segments of this Envelope so that it has the desired total duration.

pop_segment()

Remove and return the last segment of this Envelope.

pop_segment_from_start()

Remove and return the first segment of this Envelope.

prepend_envelope(envelope_to_prepend)

Extends this envelope backwards by another one (shifted to end at the start of this one).

prepend_segment(level, duration[, ...])

Prepend a segment to the beginning of the curve, starting at level and lasting for duration.

remove_segments_after(t)

Removes all segments after the given time (including a partial segment if t lands in the middle of a segment).

remove_segments_before(t)

Removes all segments before the given time (including a partial segment if t lands in the middle of a segment).

save_to_json(file_path)

Save this object to a JSON file using the given path.

scale_horizontal(amount)

Scales the domain of this Envelope by the specified amount.

scale_vertical(amount)

Scales the levels of this segment by the specified amount.

shift_horizontal(amount)

Shifts the domain of this Envelope by the specified amount.

shift_vertical(amount)

Shifts the levels of this Envelope the specified amount.

show_plot([title, resolution, ...])

Shows a plot of this Envelope using matplotlib.

split_at(t[, change_original, zero_out_offsets])

Splits the Envelope at one or several points and returns a tuple of the pieces

start_level()

Beginning value of the Envelope

start_time()

Beginning of the domain on which this Envelope is defined.

value_at(t[, from_left])

Get the value of this Envelope at the given time.

Attributes

curve_shapes

Tuple of all the segment curve shapes.

durations

Tuple of all the segment lengths.

levels

Tuple of levels at all segment boundary points.

offset

Alias for Envelope.start_time().

times

Tuple of all the segment start times.

finished()[source]
classmethod from_segments(segments: Sequence[EnvelopeSegment], clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_segments(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod from_levels_and_durations(levels: Sequence, durations: Sequence[float], curve_shapes: Optional[Sequence[Union[float, str]]] = None, offset: float = 0, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_levels_and_durations(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod from_levels(levels: Sequence, length: float = 1.0, offset: float = 0, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_levels(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod from_list(constructor_list: Sequence, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_list(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod from_points(*points: Sequence, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_points(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod release(duration: float, start_level=1, curve_shape: Optional[Union[float, str]] = None, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as release(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod ar(attack_length: float, release_length: float, peak_level=1, attack_shape: Optional[Union[float, str]] = None, release_shape: Optional[Union[float, str]] = None, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as ar(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod asr(attack_length: float, sustain_level, sustain_length: float, release_length: float, attack_shape: Optional[Union[float, str]] = None, release_shape: Optional[Union[float, str]] = None, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as asr(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod adsr(attack_length: float, attack_level, decay_length: float, sustain_level, sustain_length: float, release_length: float, attack_shape: Optional[Union[float, str]] = None, decay_shape: Optional[Union[float, str]] = None, release_shape: Optional[Union[float, str]] = None, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as adsr(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

classmethod from_function(function: Callable[[float], float], domain_start: float = 0, domain_end: float = 1, resolution_multiple: int = 2, key_point_precision: int = 2000, key_point_iterations: int = 5, clock: Optional[Clock] = None, units: str = 'beats') T[source]

Same as from_function(), but taking an optional clock and units parameter. (See TimeVaryingParameter)

append_envelope(envelope_to_append: T) T

Extends this envelope by another one (shifted to start at the end of this one).

append_segment(level, duration: float, curve_shape: Optional[float] = None, tolerance: float = 0, halfway_level=None) None

Append a segment to the end of the curve ending at level and lasting for duration. If we’re adding a linear segment to a linear segment, then we extend the last linear segment instead of adding a new one if the level is within tolerance of where the last one was headed

Parameters:
  • level – the level we’re going to

  • duration – the duration of the new segment

  • curve_shape – defaults to 0 (linear)

  • tolerance – tolerance for extending a linear segment rather than adding a new one

  • halfway_level – alternate way of defining the curve shape. If this is set and the curve shape is not then we use this to determine the curve shape.

average_level(t_range: Optional[tuple[float, float]] = None)

Returns the average value that the Envelope takes over the given range.

Parameters:

t_range – tuple defining the start and end time of the interval to check. If None, return the average level reached over the entire Envelope.

property curve_shapes: Sequence[Union[float, str]]

Tuple of all the segment curve shapes.

duplicate() T

Returns a copy of this object by serializing to and from JSON.

property durations: Sequence[float]

Tuple of all the segment lengths.

end_level()

Ending value of the Envelope

end_time() float

End of the domain on which this Envelope is defined.

get_upper_integration_bound(t1: float, desired_area: float, max_error: float = 1e-10) float

Given a lower integration bound, find the upper bound that will result in the desired integral

Parameters:
  • t1 – lower bound of integration

  • desired_area – desired value of the integral.

  • max_error – the upper bound is found through a process of successive approximation; once we get within this error, the approximation is considered good enough.

insert(t, level, curve_shape_in=0, curve_shape_out=0) None

Insert a curve point at time t, and set the shape of the curve into and out of it. This essentially divides the segment at that point in two.

Parameters:
  • t – The time at which to add a point

  • level – The level of the new point we are adding

  • curve_shape_in – the curve shape of the new segment going into the point we are adding

  • curve_shape_out – the curve shape of the new segment going out of the point we are adding

insert_interpolated(t: float, min_difference: float = 1e-07) float

Insert another curve point at the given time, without changing the shape of the curve. A point only gets added if it’s at least min_difference from all existing control points.

Parameters:
  • t – the point at which to insert the point

  • min_difference – the minimum difference that this point has to be from an existing point on the curve in order for a new point to be added.

Returns:

the t value at which we interpolated. If we try to insert within min_difference of an existing control point, then no new point is added, and we return the t of the nearest control point.

integrate_interval(t1: float, t2: float)

Get the definite integral under this Envelope from t1 to t2

Parameters:
  • t1 – lower bound of integration

  • t2 – upper bound of integration

is_shifted_version_of(other: T, tolerance: float = 1e-10) bool

Determines if this segment is simply a shifted version of another segment

Parameters:
  • other – another EnvelopeSegment

  • tolerance – how close it needs to be to count as the same

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

length() float

The length of the domain on which this Envelope is defined (end time minus start time).

property levels: Sequence

Tuple of levels at all segment boundary points.

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

local_extrema(include_saddle_points: bool = False) Sequence[float]

Returns a list of the times where the curve changes direction.

Parameters:

include_saddle_points – if True, also include points where the curve starts to plateau

max_absolute_slope()

Returns the maximum absolute value of the slope over the entire Envelope.

max_level(t_range: Optional[tuple[float, float]] = None)

Returns the highest value that the Envelope takes over the given range.

Parameters:

t_range – tuple defining the start and end time of the interval to check. If None, return the max level reached over the entire Envelope.

min_level(t_range: Optional[tuple[float, float]] = None)

Returns the lowest value that the Envelope takes over the given range.

Parameters:

t_range – tuple defining the start and end time of the interval to check. If None, return the max level reached over the entire Envelope.

normalize_to_duration(desired_duration: float, in_place: bool = True) T

Stretch or squeeze the segments of this Envelope so that it has the desired total duration.

Parameters:
  • desired_duration – the desired new duration of the Envelope

  • in_place – if True, modifies this Envelope in place; if False, makes a copy first

property offset: float

Alias for Envelope.start_time().

pop_segment() EnvelopeSegment | None

Remove and return the last segment of this Envelope. If there is only one segment, reduce it to length zero and return None.

pop_segment_from_start() EnvelopeSegment | None

Remove and return the first segment of this Envelope. If there is only one segment, reduce it to length zero and return None.

prepend_envelope(envelope_to_prepend: T) T

Extends this envelope backwards by another one (shifted to end at the start of this one).

prepend_segment(level, duration: float, curve_shape: Optional[float] = None, tolerance: float = 0, halfway_level=None) None

Prepend a segment to the beginning of the curve, starting at level and lasting for duration. If we’re adding a linear segment to a linear segment, then we extend the last linear segment instead of adding a new one if the level is within tolerance of where the last one was headed

Parameters:
  • level – the level that the prepended segment starts at

  • duration – the duration of the new segment

  • curve_shape – defaults to 0 (linear)

  • tolerance – tolerance for extending a linear segment rather than adding a new one

  • halfway_level – alternate way of defining the curve shape. If this is set and the curve shape is not then we use this to determine the curve shape.

remove_segments_after(t: float) None

Removes all segments after the given time (including a partial segment if t lands in the middle of a segment).

Parameters:

t – the point at which this Envelope is to be truncated.

remove_segments_before(t: float) None

Removes all segments before the given time (including a partial segment if t lands in the middle of a segment).

Parameters:

t – the point at which this Envelope is to be truncated.

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

scale_horizontal(amount: float) T

Scales the domain of this Envelope by the specified amount.

Parameters:

amount – amount to scale domain by

Returns:

self, for chaining purposes

scale_vertical(amount) T

Scales the levels of this segment by the specified amount.

Parameters:

amount – amount to scale output by

Returns:

self, for chaining purposes

shift_horizontal(amount: float) T

Shifts the domain of this Envelope by the specified amount.

Parameters:

amount – the amount to shift the domain by

Returns:

self, for chaining purposes

shift_vertical(amount) T

Shifts the levels of this Envelope the specified amount.

Parameters:

amount – the amount to shift up and down by

Returns:

self, for chaining purposes

show_plot(title: Optional[str] = None, resolution: int = 25, show_segment_divisions: bool = True, x_range: Optional[tuple[float, float]] = None, y_range: Optional[tuple[float, float]] = None) None

Shows a plot of this Envelope using matplotlib.

Parameters:
  • title – A title to give the plot.

  • resolution – number of points to use per envelope segment

  • show_segment_divisions – Whether or not to place dots at the division points between envelope segments

  • x_range – min and max value shown on the x-axis

  • y_range – min and max value shown on the y-axis

split_at(t: Union[float, Sequence[float]], change_original: bool = False, zero_out_offsets: bool = True) Sequence[T]

Splits the Envelope at one or several points and returns a tuple of the pieces

Parameters:
  • t – either the time t or a tuple/list of times t at which to split the curve

  • change_original – if true, the original Envelope gets turned into the first of the returned tuple

  • zero_out_offsets – if true, each new piece is shifted to start at zero

Returns:

tuple of Envelopes representing the pieces this has been split into

start_level()

Beginning value of the Envelope

start_time() float

Beginning of the domain on which this Envelope is defined.

property times: Sequence[float]

Tuple of all the segment start times.

value_at(t: float, from_left: bool = False)

Get the value of this Envelope at the given time.

Parameters:
  • t – the time

  • from_left – if true, get the limit as we approach t from the left. In the case of a zero-length segment, which suddenly changes the value, this tells us what the value was right before the jump instead of right after the jump.