80 currentParameters = newParameters;
82 sustainLevel = newParameters.
sustain;
83 calculateRates (newParameters);
85 if (currentState != State::idle)
96 bool isActive() const noexcept {
return currentState != State::idle; }
105 jassert (sampleRate > 0.0);
114 currentState = State::idle;
120 if (attackRate > 0.0f)
122 currentState = State::attack;
124 else if (decayRate > 0.0f)
127 currentState = State::decay;
131 currentState = State::sustain;
138 if (currentState != State::idle)
140 if (currentParameters.
release > 0.0f)
142 releaseRate =
static_cast<float> (envelopeVal / (currentParameters.
release * sr));
143 currentState = State::release;
159 if (currentState == State::idle)
162 if (currentState == State::attack)
164 envelopeVal += attackRate;
166 if (envelopeVal >= 1.0f)
170 if (decayRate > 0.0f)
171 currentState = State::decay;
173 currentState = State::sustain;
176 else if (currentState == State::decay)
178 envelopeVal -= decayRate;
180 if (envelopeVal <= sustainLevel)
182 envelopeVal = sustainLevel;
183 currentState = State::sustain;
186 else if (currentState == State::sustain)
188 envelopeVal = sustainLevel;
190 else if (currentState == State::release)
192 envelopeVal -= releaseRate;
194 if (envelopeVal <= 0.0f)
206 template<
typename FloatType>
209 jassert (startSample + numSamples <= buffer.
getNumSamples());
213 while (--numSamples >= 0)
217 for (
int i = 0; i < numChannels; ++i)
226 void calculateRates (
const Parameters& parameters)
231 attackRate = (parameters.attack > 0.0f ?
static_cast<float> (1.0f / (parameters.attack * sr)) : -1.0f);
232 decayRate = (parameters.decay > 0.0f ?
static_cast<float> ((1.0f - sustainLevel) / (parameters.decay * sr)) : -1.0f);
235 void checkCurrentState()
237 if (currentState == State::attack && attackRate <= 0.0f) currentState = decayRate > 0.0f ? State::decay : State::sustain;
238 else if (currentState == State::decay && decayRate <= 0.0f) currentState = State::sustain;
239 else if (currentState == State::release && releaseRate <= 0.0f)
reset();
243 enum class State { idle, attack, decay, sustain, release };
245 State currentState = State::idle;
246 Parameters currentParameters;
249 float envelopeVal = 0.0f, sustainLevel = 0.0f, attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
A very simple ADSR envelope class.
const Parameters & getParameters() const
Returns the parameters currently being used by an ADSR object.
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 attack
Attack time in seconds.
float getNextSample()
Returns the next sample value for an ADSR object.
float sustain
Sustain level.
void noteOn()
Starts the attack phase of the envelope.
void reset()
Resets the envelope to an idle state.
float release
Release time in seconds.
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
This method will conveniently apply the next numSamples number of envelope values to an AudioBuffer.
float decay
Decay time in seconds.
Holds the parameters 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.