return to src
 
ADSR class

Design inspired by 
https://python.plainenglish.io/build-your-own-python-synthesizer-part-2-66396f6dad81
 
The ADSREnvelope class represents an Attack-Decay-Sustain-Release (ADSR) envelope used in 
a synthesizer. This envelope is responsible for modulating the amplitude of the synthesized 
waveform over time, creating dynamic changes in the sound.
 
To use the ADSREnvelope class, follow these steps:
 
1. Create an instance of the ADSREnvelope class, specifying the parameters of 
attack, decay, sustain, release durations, and sample rate.
2. Update the envelope state using the update_state() method to set the initial state.
3. Optionally, dynamically update the attack, decay, sustain, or release parameters using the corresponding 
update methods (update_attack(), update_decay(), update_sustain(), update_release()).
4. Process each sample of the audio waveform by passing it to the process() method, which 
applies the envelope based on the current state and returns the output sample with the envelope applied.

 
Modules
       
enum
numpy
numpy.typing
sounddevice

 
Classes
       
ADSREnvelope
State

 
class ADSREnvelope
    ADSREnvelope(attack_duration: float = 0.5, decay_duration: int = 1, sustain_level: int = 1, release_duration: int = 1, sample_rate: int = 48000) -> None
 
The Attack-Decay-Sustain-Release (ADSR) envelope class is responsible for 
shaping the parameters of the sound.
 
Attributes:
    attack_duration: the time it takes for a sound to reach full volume.
    decay_duration: the time it takes to reach the sustain level.
    sustain_level: the level at which a sound is held.
    release_duration: the time it takes for a sound to gradually fade.
    sample_rate: speed that samples are loaded in cycles per second (hertz)
 
  Methods defined here:
__init__(self, attack_duration: float = 0.5, decay_duration: int = 1, sustain_level: int = 1, release_duration: int = 1, sample_rate: int = 48000) -> None
Initialize self.  See help(type(self)) for accurate signature.
create_attack_envelope(self) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
Create an array of evenly spaced numbers from 0 to 1 
with the attack sample as the step
create_decay_envelope(self) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
Create an array of evenly spaced numbers from 1 to the sustain
with the decay sample as the step
create_release_envelope(self) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
Create an array of evenly spaced numbers from the sustain to 0
with the release sample as the step
process(self, sample: numpy.int16) -> float | None
takes in a sample, process based on state, return sample with envelope applied
update_attack(self, attack_duration: float) -> None
update the attack samples and recreate the attack envelope
update_decay(self, decay_duration: int) -> None
update the decay samples and recreate the decay envelope
update_release(self, release_duration: int) -> None
update the release samples and recreate the release envelope
update_state(self, state: adsr.State) -> None
updates the current ADSR state
update_sustain(self, sustain_level: int) -> None
recalculate and update the sustain

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class State
    State(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
 

 
 
Method resolution order:
State
enum.Enum
builtins.object

Data and other attributes defined here:
ATTACK = <State.ATTACK: 1>
DECAY = <State.DECAY: 2>
IDLE = <State.IDLE: 0>
RELEASE = <State.RELEASE: 4>
SUSTAIN = <State.SUSTAIN: 3>

Data descriptors inherited from enum.Enum:
name
The name of the Enum member.
value
The value of the Enum member.

Methods inherited from enum.EnumType:
__contains__(member) from enum.EnumType
Return True if member is a member of this enum
raises TypeError if member is not an enum member
 
note: in 3.12 TypeError will no longer be raised, and True will also be
returned if member is the value of a member in this enum
__getitem__(name) from enum.EnumType
Return the member matching `name`.
__iter__() from enum.EnumType
Return members in definition order.
__len__() from enum.EnumType
Return the number of members (no aliases)

Readonly properties inherited from enum.EnumType:
__members__
Returns a mapping of member name->value.
 
This mapping lists all enum members, including aliases. Note that this
is a read-only view of the internal mapping.

 
Data
        DEFAULT_MS = 0.05
__annotations__ = {'DEFAULT_MS': <class 'float'>}