74 currentParameters = newParameters;
76 sustainLevel = newParameters.
sustain;
77 calculateRates (newParameters);
79 if (currentState != State::idle)
90 bool isActive() const noexcept {
return currentState != State::idle; }
99 jassert (sampleRate > 0.0);
108 currentState = State::idle;
114 if (attackRate > 0.0f) currentState = State::attack;
115 else if (decayRate > 0.0f) currentState = State::decay;
116 else currentState = State::sustain;
122 if (currentState != State::idle)
124 if (releaseRate > 0.0f)
126 if (currentState != State::sustain)
127 releaseRate =
static_cast<float> (envelopeVal / (currentParameters.
release * sr));
129 currentState = State::release;
145 if (currentState == State::idle)
148 if (currentState == State::attack)
150 envelopeVal += attackRate;
152 if (envelopeVal >= 1.0f)
156 if (decayRate > 0.0f)
157 currentState = State::decay;
159 currentState = State::sustain;
162 else if (currentState == State::decay)
164 envelopeVal -= decayRate;
166 if (envelopeVal <= sustainLevel)
168 envelopeVal = sustainLevel;
169 currentState = State::sustain;
172 else if (currentState == State::sustain)
174 envelopeVal = sustainLevel;
176 else if (currentState == State::release)
178 envelopeVal -= releaseRate;
180 if (envelopeVal <= 0.0f)
192 template<
typename FloatType>
195 jassert (startSample + numSamples <= buffer.
getNumSamples());
199 while (--numSamples >= 0)
203 for (
int i = 0; i < numChannels; ++i)
212 void calculateRates (
const Parameters& parameters)
217 attackRate = (parameters.attack > 0.0f ?
static_cast<float> (1.0f / (parameters.attack * sr)) : -1.0f);
218 decayRate = (parameters.decay > 0.0f ?
static_cast<float> ((1.0f - sustainLevel) / (parameters.decay * sr)) : -1.0f);
219 releaseRate = (parameters.release > 0.0f ?
static_cast<float> (sustainLevel / (parameters.release * sr)) : -1.0f);
222 void checkCurrentState()
224 if (currentState == State::attack && attackRate <= 0.0f) currentState = decayRate > 0.0f ? State::decay : State::sustain;
225 else if (currentState == State::decay && decayRate <= 0.0f) currentState = State::sustain;
226 else if (currentState == State::release && releaseRate <= 0.0f)
reset();
230 enum class State { idle, attack, decay, sustain, release };
232 State currentState = State::idle;
233 Parameters currentParameters;
237 float envelopeVal = 0.0f;
239 float sustainLevel = 0.0f;
240 float attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
A very simple ADSR envelope class.
void setSampleRate(double sampleRate)
Sets the sample rate that will be used for the envelope.
bool isActive() const noexcept
Returns true if the envelope is in its attack, decay, sustain or release stage.
void setParameters(const Parameters &newParameters)
Sets the parameters that will be used by an ADSR object.
void noteOff()
Starts the release phase of the envelope.
float getNextSample()
Returns the next sample value for an ADSR object.
void noteOn()
Starts the attack phase of the envelope.
void reset()
Resets the envelope to an idle state.
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
This method will conveniently apply the next numSamples number of envelope values to an AudioBuffer.
const Parameters & getParameters() const
Returns the parameters currently being used by an ADSR object.
A multi-channel buffer containing floating point audio samples.
Type * getWritePointer(int channelNumber) noexcept
Returns a writeable pointer to one of the buffer's channels.
int getNumChannels() const noexcept
Returns the number of channels of audio data that this buffer contains.
int getNumSamples() const noexcept
Returns the number of samples allocated in each of the buffer's channels.
float attack
Attack time in seconds.
float sustain
Sustain level.
float release
Release time in seconds.
float decay
Decay time in seconds.
Holds the parameters being used by an ADSR object.