@maruaudio/dsp/envelopes/adsr is an exponential ADSR state machine in VCA form, the same one the subtractive voice runs. Each stage moves the level one f32 step toward its target, level += (target − level)·c, with c = 1 − exp(−4.6 / (t·rate)) so a stage gets about 99 % of the way in its time (@maru/voices-stages). Attack ends at 0.999 and jumps to 1, decay ends within 0.001 of sustain, release ends at 0.0005 and goes idle. Gate-on is a full retrigger from level 0; gate-off releases from the current level.
const env = initAdsrNode(48000)
setAdsrNodeRelease(env, 0.8)
adsrNodeGateOn(env)
const gain = adsrNodeTick(env) // per sampleParameters
| Setter | Range the setter enforces | Default | Unit |
|---|---|---|---|
setAdsrNodeAttack | 0 to 2 | 0.01 | s |
setAdsrNodeDecay | 0 to 2 | 0.2 | s |
setAdsrNodeSustain | 0 to 1 | 0.7 | level |
setAdsrNodeRelease | 0 to 5 | 0.3 | s |
Times below 0.0001 s are floored to 0.0001 s in the coefficient.
Lifecycle
initAdsrNode(sampleRate) → setters → adsrNodeGateOn and adsrNodeGateOff → adsrNodeTick per sample → resetAdsrNode, which returns to idle at level 0 and keeps the times. Gate-off while idle does nothing. Stages are ADSR_STAGE_IDLE (0) to ADSR_STAGE_RELEASE (4).
When to use it
Shaping the amplitude or filter of a synth voice, with an exponential curve and a retrigger that always restarts the attack from silence.
Limits
- One envelope, one sample per tick; the level is f32.
- The coefficient is recomputed from the stored time on every attack, decay and release sample, so each such tick calls
exp. - Gate-on restarts from 0, which can click on a sounding note; there is no legato mode.
audio-kernelskeeps the PCM16 render entry.