55 struct JUCE_API Parameters
57 Parameters() =
default;
59 Parameters (
float attackTimeSeconds,
60 float decayTimeSeconds,
62 float releaseTimeSeconds)
63 : attack (attackTimeSeconds),
64 decay (decayTimeSeconds),
65 sustain (sustainLevel),
66 release (releaseTimeSeconds)
70 float attack = 0.1f, decay = 0.1f, sustain = 1.0f, release = 0.1f;
83 jassert (sampleRate > 0.0);
85 parameters = newParameters;
96 bool isActive() const noexcept {
return state != State::idle; }
105 jassert (newSampleRate > 0.0);
106 sampleRate = newSampleRate;
120 if (attackRate > 0.0f)
122 state = State::attack;
124 else if (decayRate > 0.0f)
127 state = State::decay;
131 envelopeVal = parameters.sustain;
132 state = State::sustain;
139 if (state != State::idle)
141 if (parameters.release > 0.0f)
143 releaseRate = (float) (envelopeVal / (parameters.release * sampleRate));
144 state = State::release;
169 envelopeVal += attackRate;
171 if (envelopeVal >= 1.0f)
182 envelopeVal -= decayRate;
184 if (envelopeVal <= parameters.sustain)
186 envelopeVal = parameters.sustain;
195 envelopeVal = parameters.sustain;
201 envelopeVal -= releaseRate;
203 if (envelopeVal <= 0.0f)
218 template <
typename FloatType>
221 jassert (startSample + numSamples <= buffer.
getNumSamples());
223 if (state == State::idle)
225 buffer.
clear (startSample, numSamples);
229 if (state == State::sustain)
231 buffer.
applyGain (startSample, numSamples, parameters.sustain);
237 while (--numSamples >= 0)
241 for (
int i = 0; i < numChannels; ++i)
250 void recalculateRates() noexcept
252 auto getRate = [] (
float distance,
float timeInSeconds,
double sr)
254 return timeInSeconds > 0.0f ? (float) (distance / (timeInSeconds * sr)) : -1.0f;
257 attackRate = getRate (1.0f, parameters.attack, sampleRate);
258 decayRate = getRate (1.0f - parameters.sustain, parameters.decay, sampleRate);
259 releaseRate = getRate (parameters.sustain, parameters.release, sampleRate);
261 if ((state == State::attack && attackRate <= 0.0f)
262 || (state == State::decay && (decayRate <= 0.0f || envelopeVal <= parameters.sustain))
263 || (state == State::release && releaseRate <= 0.0f))
269 void goToNextState() noexcept
271 if (state == State::attack)
273 state = (decayRate > 0.0f ? State::decay : State::sustain);
277 if (state == State::decay)
279 state = State::sustain;
283 if (state == State::release)
288 enum class State { idle, attack, decay, sustain, release };
290 State state = State::idle;
291 Parameters parameters;
293 double sampleRate = 44100.0;
294 float envelopeVal = 0.0f, attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;