Envelope

The reflected ADSR envelope — an authorable attack/decay/sustain/release shape with evaluation, duration and completion helpers.

GS_Core::Envelope provides an ADSR envelope — the attack / decay / sustain / release shape borrowed from synthesis, generalised for any value that needs to rise, hold and fall over time.

It is a general-purpose utility, not an audio one. Anywhere a value should ramp in, hold, and ramp out — a shake intensity, a feedback effect’s strength, a UI element’s emphasis — an envelope describes that shape as data instead of as hand-written timing code.

For usage guides and setup examples, see The Basics: GS_Core.

 

Contents


ADSREnvelope

A reflected struct, so it can be authored directly on a component or asset and tuned in the Inspector.

FieldDefaultDescription
Attack0.05Seconds to rise from zero to full.
Decay0.10Seconds to fall from full to the sustain level.
Sustain0.00Seconds to hold at the sustain level.
Release0.30Seconds to fall from the sustain level to zero.
Sustain Level1.0The level held during the sustain phase.

The defaults describe an attack-release shape — a quick rise and a slower fall with no hold, which is what most one-shot effects want. Give Sustain a non-zero duration when the value should stay up for a while before releasing.

Being reflected is the point: a designer authors the envelope on the component, and the code just evaluates it.


Functions

FunctionReturnsDescription
Evaluate(elapsed, envelope)floatThe envelope’s value at a given elapsed time.
TotalDuration(envelope)floatAttack + decay + sustain + release.
IsFinished(elapsed, envelope)boolWhether the envelope has completed.

IsFinished is worth using rather than comparing against TotalDuration yourself — it is the signal to stop evaluating and shut the effect down, which is the cheaper path when many effects are running.


Usage

The pattern is always the same: accumulate elapsed time, evaluate, and stop when finished.

#include <GS_Core/Utility/Math/EnvelopeUtility.h>

// each tick, while active
m_elapsed += deltaTime;

const float gain = GS_Core::Envelope::Evaluate(m_elapsed, m_envelope);
ApplyGain(gain);

if (GS_Core::Envelope::IsFinished(m_elapsed, m_envelope))
{
    m_active = false;
}

Reset m_elapsed to zero to retrigger. Because the envelope is data, retriggering with a different shape is a matter of swapping the struct rather than changing any of this code.


See Also

For related utilities:

  • Easing Curves — shaping a single transition rather than a full envelope
  • Noise — continuous variation rather than a one-shot shape
  • Gradients — value over a normalized range rather than over time

For conceptual overviews and usage guides:


Get GS_Core

GS_Core — Explore this gem on the product page and add it to your project.