expenvelope.envelope.Envelope¶

class
expenvelope.envelope.
Envelope
(levels: Sequence = 0, durations: Sequence[float] = (), curve_shapes: Sequence[Union[float, str]] = None, offset: float = 0)[source]¶ Bases:
expenvelope.json_serializer.SavesToJSON
Class representing a piecewise exponential function. This class was designed with musical applications in mind, with the intention being to represent a continuously changing musical parameter over time. For instance, an Envelope might be used to represent the pitch curve of a glissando, or the volume curve of a fortepiano.
 Parameters
levels – the levels of the curve. These can be anything that acts like a number. For instance, one could even use numpy arrays as levels.
durations – the durations of the curve segments. (Should have length one less than levels.)
curve_shapes – the curve shape values (optional, should have length one less than levels). Generally these will be floats, with the default of 0 representing linear change, > 0 representing late change, and < 0 representing early change. It is also possible to use the string “exp” to produce constant proportional change per unit time, so long as the segment does not touch zero. Finally, strings containing “exp”, such as “exp ** 2 / 5” will be evaluated with the curve shape required for exponential change being plugged in for the variable “exp”.
offset – starts curve from somewhere other than zero
 Variables
segments – list of
EnvelopeSegment
s representing the pieces of this envelope.
Methods
adsr
(attack_length, attack_level, …[, …])Construct a standard attack/decay/sustain/release envelope
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.
ar
(attack_length, release_length[, …])Construct an attack/release envelope
asr
(attack_length, sustain_level, …[, …])Construct an attack/sustain/release envelope
average_level
([t_range])Returns the average value that the Envelope takes over the given range.
Ending value of the Envelope
end_time
()End of the domain on which this Envelope is defined.
from_function
(function[, domain_start, …])Constructs an Envelope that approximates an arbitrary function.
from_levels
(levels[, length, offset])Construct an envelope from levels alone, normalized to the given length.
from_levels_and_durations
(levels, durations)Construct an Envelope from levels, durations, and optionally curve shapes.
from_list
(constructor_list)Construct an envelope from a list that can take a number of formats
from_points
(*points)Construct an envelope from points
from_segments
(segments)Create a new envelope from a list of
EnvelopeSegment
s.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
length
()The length of the domain on which this Envelope is defined (end time minus start time).
local_extrema
([include_saddle_points])Returns a list of the times where the curve changes direction.
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.
normalize_to_duration
(desired_duration[, …])Stretch or squeeze the segments of this Envelope so that it has the desired total duration.
Remove and return the last segment of this Envelope.
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.
release
(duration[, start_level, curve_shape])Construct an simple decaying envelope
Removes all segments after the given time (including a partial segment if t lands in the middle of a segment).
Removes all segments before the given time (including a partial segment if t lands in the middle of a segment).
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])Splits the Envelope at one or several points and returns a tuple of the pieces
Beginning value of the Envelope
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.
Inherited Methods
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.
Attributes
Tuple of all the segment curve shapes.
Tuple of all the segment lengths.
Tuple of levels at all segment boundary points.
Alias for
Envelope.start_time()
.Tuple of all the segment start times.

classmethod
from_segments
(segments: Sequence[expenvelope.envelope_segment.EnvelopeSegment]) → T[source]¶ Create a new envelope from a list of
EnvelopeSegment
s. Parameters
segments – list of segments

classmethod
from_levels_and_durations
(levels: Sequence, durations: Sequence[float], curve_shapes: Sequence[Union[float, str]] = None, offset: float = 0) → T[source]¶ Construct an Envelope from levels, durations, and optionally curve shapes.
 Parameters
levels – the levels of the curve. These can be anything that acts like a number. For instance, one could even use numpy arrays as levels.
durations – the durations of the curve segments. (Should have length one less than levels.)
curve_shapes – the curve shape values (optional, should have length one less than levels). Generally these will be floats, with the default of 0 representing linear change, > 0 representing late change, and < 0 representing early change. It is also possible to use the string “exp” to produce constant proportional change per unit time, so long as the segment does not touch zero. Finally, strings containing “exp”, such as “exp ** 2 / 5” will be evaluated with the curve shape required for exponential change being plugged in for the variable “exp”.
offset – starts curve from somewhere other than zero
 Returns
an Envelope constructed accordingly

classmethod
from_levels
(levels: Sequence, length: float = 1.0, offset: float = 0) → T[source]¶ Construct an envelope from levels alone, normalized to the given length.
 Parameters
levels – the levels of the curve. These can be anything that acts like a number. For instance, one could even use numpy arrays as levels.
length – the total length of the curve, divided evenly amongst the levels
offset – starts curve from somewhere other than zero
 Returns
an Envelope constructed accordingly

classmethod
from_list
(constructor_list: Sequence) → T[source]¶ Construct an envelope from a list that can take a number of formats
 Parameters
constructor_list – Either a flat list that just contains levels, or a list of lists either of the form [levels_list, total_duration], [levels_list, durations_list] or [levels_list, durations_list, curve_shape_list] for example:  an input of [1, 0.5, 0.3] is interpreted as evenly spaced levels with a total duration of 1  an input of [[1, 0.5, 0.3], 3.0] is interpreted as levels and durations with a total duration of e.g. 3.0  an input of [[1, 0.5, 0.3], [0.2, 0.8]] is interpreted as levels and durations  an input of [[1, 0.5, 0.3], [0.2, 0.8], [2, 0.5]] is interpreted as levels, durations, and curvatures
 Returns
an Envelope constructed accordingly

classmethod
from_points
(*points: Sequence) → T[source]¶ Construct an envelope from points
 Parameters
points – list of points, each of which is of the form (time, value) or (time, value, curve_shape)
 Returns
an Envelope constructed accordingly

classmethod
release
(duration: float, start_level=1, curve_shape: Union[float, str] = None) → T[source]¶ Construct an simple decaying envelope
 Parameters
duration – total decay length
start_level – level decayed from
curve_shape – shape of the curve (see documentation for
Envelope.from_levels_and_durations()
)
 Returns
an Envelope constructed accordingly

classmethod
ar
(attack_length: float, release_length: float, peak_level=1, attack_shape: Union[float, str] = None, release_shape: Union[float, str] = None) → T[source]¶ Construct an attack/release envelope
 Parameters
attack_length – rise time
release_length – release time
peak_level – level reached after attack and before release (see documentation for
Envelope.from_levels_and_durations()
)attack_shape – sets curve shape for attack portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)release_shape – sets curve shape for release portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)
 Returns
an Envelope constructed accordingly

classmethod
asr
(attack_length: float, sustain_level, sustain_length: float, release_length: float, attack_shape: Union[float, str] = None, release_shape: Union[float, str] = None) → T[source]¶ Construct an attack/sustain/release envelope
 Parameters
attack_length – rise time
sustain_level – sustain level reached after attack and before release
sustain_length – length of sustain portion of curve
release_length – release time
attack_shape – sets curve shape for attack portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)release_shape – sets curve shape for release portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)
 Returns
an Envelope constructed accordingly

classmethod
adsr
(attack_length: float, attack_level, decay_length: float, sustain_level, sustain_length: float, release_length: float, attack_shape: Union[float, str] = None, decay_shape: Union[float, str] = None, release_shape: Union[float, str] = None) → T[source]¶ Construct a standard attack/decay/sustain/release envelope
 Parameters
attack_length – rise time
attack_level – level reached after attack before decay
decay_length – length of decay portion of the curve
sustain_level – sustain level reached after decay and before release
sustain_length – length of sustain portion of curve
release_length – release time
attack_shape – sets curve shape for attack portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)decay_shape – sets curve shape for decay portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)release_shape – sets curve shape for release portion of the curve (see documentation for
Envelope.from_levels_and_durations()
)
 Returns
an Envelope constructed accordingly

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) → T[source]¶ Constructs an Envelope that approximates an arbitrary function. By default, the function is split at local extrema and inflection points found through a pretty unsophisticated numerical process.
 Parameters
function – a function from time to level (often a lambda function)
domain_start – the beginning of the function domain range to capture
domain_end – the end of the function domain range to capture
resolution_multiple – factor by which we add extra key points between the extrema and inflection points to improve the curve fit..
key_point_precision – precision with which we break up the domain of the function in searching for key points (how many discrete differences we use).
key_point_iterations – every time a prospective key point is found, we run a more narrow search on that segment of the domain, using smaller step sizes, which gives us a more precise location for the key point. We then repeat this narrowing in process, up to this many iterations
 Returns
an Envelope constructed accordingly

length
() → float[source]¶ The length of the domain on which this Envelope is defined (end time minus start time).

max_level
(t_range: Tuple[float, float] = None)[source]¶ 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.

average_level
(t_range: Tuple[float, float] = None)[source]¶ 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.

max_absolute_slope
()[source]¶ Returns the maximum absolute value of the slope over the entire Envelope.

property
levels
¶ Tuple of levels at all segment boundary points.

property
durations
¶ Tuple of all the segment lengths.

property
times
¶ Tuple of all the segment start times.

property
curve_shapes
¶ Tuple of all the segment curve shapes.

property
offset
¶ Alias for
Envelope.start_time()
.

insert
(t, level, curve_shape_in=0, curve_shape_out=0) → None[source]¶ 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 = 1e07) → float[source]¶ 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.

append_segment
(level, duration: float, curve_shape: float = None, tolerance: float = 0, halfway_level=None) → None[source]¶ 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.

prepend_segment
(level, duration: float, curve_shape: float = None, tolerance: float = 0, halfway_level=None) → None[source]¶ 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.

pop_segment
() → Optional[expenvelope.envelope_segment.EnvelopeSegment][source]¶ 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
() → Optional[expenvelope.envelope_segment.EnvelopeSegment][source]¶ Remove and return the first segment of this Envelope. If there is only one segment, reduce it to length zero and return None.

remove_segments_after
(t: float) → None[source]¶ 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[source]¶ 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.

append_envelope
(envelope_to_append: T) → expenvelope.envelope.Envelope[source]¶ Extends this envelope by another one (shifted to start at the end of this one).

prepend_envelope
(envelope_to_prepend: T) → T[source]¶ Extends this envelope backwards by another one (shifted to end at the start of this one).

value_at
(t: float, from_left: bool = False)[source]¶ 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 zerolength segment, which suddenly changes the value, this tells us what the value was right before the jump instead of right after the jump.

integrate_interval
(t1: float, t2: float)[source]¶ Get the definite integral under this Envelope from t1 to t2
 Parameters
t1 – lower bound of integration
t2 – upper bound of integration

get_upper_integration_bound
(t1: float, desired_area: float, max_error: float = 0.001) → float[source]¶ 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.

normalize_to_duration
(desired_duration: float, in_place: bool = True) → T[source]¶ 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

local_extrema
(include_saddle_points: bool = False) → Sequence[float][source]¶ 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

split_at
(t: Union[float, Sequence[float]], change_original: bool = False) → Sequence[T][source]¶ 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
 Returns
tuple of Envelopes representing the pieces this has been split into

is_shifted_version_of
(other: T, tolerance: float = 1e10) → bool[source]¶ 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

shift_vertical
(amount) → T[source]¶ Shifts the levels of this Envelope the specified amount.
 Parameters
amount – the amount to shift up and down by
 Returns
self, for chaining purposes

scale_vertical
(amount) → T[source]¶ 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[source]¶ Shifts the domain of this Envelope by the specified amount.
 Parameters
amount – the amount to shift the domain by
 Returns
self, for chaining purposes

scale_horizontal
(amount: float) → T[source]¶ Scales the domain of this Envelope by the specified amount.
 Parameters
amount – amount to scale domain by
 Returns
self, for chaining purposes

show_plot
(title: str = None, resolution: int = 25, show_segment_divisions: bool = True, x_range: Tuple[float, float] = None, y_range: Tuple[float, float] = None) → None[source]¶ 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 xaxis
y_range – min and max value shown on the yaxis

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