JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_ADSR.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
40class JUCE_API ADSR
41{
42public:
43 //==============================================================================
44 ADSR()
45 {
46 recalculateRates();
47 }
48
49 //==============================================================================
55 struct JUCE_API Parameters
56 {
57 Parameters() = default;
58
59 Parameters (float attackTimeSeconds,
60 float decayTimeSeconds,
61 float sustainLevel,
62 float releaseTimeSeconds)
63 : attack (attackTimeSeconds),
64 decay (decayTimeSeconds),
65 sustain (sustainLevel),
66 release (releaseTimeSeconds)
67 {
68 }
69
70 float attack = 0.1f, decay = 0.1f, sustain = 1.0f, release = 0.1f;
71 };
72
80 void setParameters (const Parameters& newParameters)
81 {
82 // need to call setSampleRate() first!
83 jassert (sampleRate > 0.0);
84
85 parameters = newParameters;
86 recalculateRates();
87 }
88
93 const Parameters& getParameters() const noexcept { return parameters; }
94
96 bool isActive() const noexcept { return state != State::idle; }
97
98 //==============================================================================
103 void setSampleRate (double newSampleRate) noexcept
104 {
105 jassert (newSampleRate > 0.0);
106 sampleRate = newSampleRate;
107 }
108
109 //==============================================================================
111 void reset() noexcept
112 {
113 envelopeVal = 0.0f;
114 state = State::idle;
115 }
116
118 void noteOn() noexcept
119 {
120 if (attackRate > 0.0f)
121 {
122 state = State::attack;
123 }
124 else if (decayRate > 0.0f)
125 {
126 envelopeVal = 1.0f;
127 state = State::decay;
128 }
129 else
130 {
131 envelopeVal = parameters.sustain;
132 state = State::sustain;
133 }
134 }
135
137 void noteOff() noexcept
138 {
139 if (state != State::idle)
140 {
141 if (parameters.release > 0.0f)
142 {
143 releaseRate = (float) (envelopeVal / (parameters.release * sampleRate));
144 state = State::release;
145 }
146 else
147 {
148 reset();
149 }
150 }
151 }
152
153 //==============================================================================
158 float getNextSample() noexcept
159 {
160 switch (state)
161 {
162 case State::idle:
163 {
164 return 0.0f;
165 }
166
167 case State::attack:
168 {
169 envelopeVal += attackRate;
170
171 if (envelopeVal >= 1.0f)
172 {
173 envelopeVal = 1.0f;
174 goToNextState();
175 }
176
177 break;
178 }
179
180 case State::decay:
181 {
182 envelopeVal -= decayRate;
183
184 if (envelopeVal <= parameters.sustain)
185 {
186 envelopeVal = parameters.sustain;
187 goToNextState();
188 }
189
190 break;
191 }
192
193 case State::sustain:
194 {
195 envelopeVal = parameters.sustain;
196 break;
197 }
198
199 case State::release:
200 {
201 envelopeVal -= releaseRate;
202
203 if (envelopeVal <= 0.0f)
204 goToNextState();
205
206 break;
207 }
208 }
209
210 return envelopeVal;
211 }
212
218 template <typename FloatType>
219 void applyEnvelopeToBuffer (AudioBuffer<FloatType>& buffer, int startSample, int numSamples)
220 {
221 jassert (startSample + numSamples <= buffer.getNumSamples());
222
223 if (state == State::idle)
224 {
225 buffer.clear (startSample, numSamples);
226 return;
227 }
228
229 if (state == State::sustain)
230 {
231 buffer.applyGain (startSample, numSamples, parameters.sustain);
232 return;
233 }
234
235 auto numChannels = buffer.getNumChannels();
236
237 while (--numSamples >= 0)
238 {
239 auto env = getNextSample();
240
241 for (int i = 0; i < numChannels; ++i)
242 buffer.getWritePointer (i)[startSample] *= env;
243
244 ++startSample;
245 }
246 }
247
248private:
249 //==============================================================================
250 void recalculateRates() noexcept
251 {
252 auto getRate = [] (float distance, float timeInSeconds, double sr)
253 {
254 return timeInSeconds > 0.0f ? (float) (distance / (timeInSeconds * sr)) : -1.0f;
255 };
256
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);
260
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))
264 {
265 goToNextState();
266 }
267 }
268
269 void goToNextState() noexcept
270 {
271 if (state == State::attack)
272 {
273 state = (decayRate > 0.0f ? State::decay : State::sustain);
274 return;
275 }
276
277 if (state == State::decay)
278 {
279 state = State::sustain;
280 return;
281 }
282
283 if (state == State::release)
284 reset();
285 }
286
287 //==============================================================================
288 enum class State { idle, attack, decay, sustain, release };
289
290 State state = State::idle;
291 Parameters parameters;
292
293 double sampleRate = 44100.0;
294 float envelopeVal = 0.0f, attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
295};
296
297} // namespace juce
A very simple ADSR envelope class.
Definition juce_ADSR.h:41
void setSampleRate(double newSampleRate) noexcept
Sets the sample rate that will be used for the envelope.
Definition juce_ADSR.h:103
void noteOff() noexcept
Starts the release phase of the envelope.
Definition juce_ADSR.h:137
bool isActive() const noexcept
Returns true if the envelope is in its attack, decay, sustain or release stage.
Definition juce_ADSR.h:96
void reset() noexcept
Resets the envelope to an idle state.
Definition juce_ADSR.h:111
float getNextSample() noexcept
Returns the next sample value for an ADSR object.
Definition juce_ADSR.h:158
void setParameters(const Parameters &newParameters)
Sets the parameters that will be used by an ADSR object.
Definition juce_ADSR.h:80
void noteOn() noexcept
Starts the attack phase of the envelope.
Definition juce_ADSR.h:118
const Parameters & getParameters() const noexcept
Returns the parameters currently being used by an ADSR object.
Definition juce_ADSR.h:93
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
This method will conveniently apply the next numSamples number of envelope values to an AudioBuffer.
Definition juce_ADSR.h:219
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.
void clear() noexcept
Clears all the samples in all channels and marks the buffer as cleared.
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
Applies a gain multiple to a region of one channel.
#define jassert(expression)
Platform-independent assertion macro.
typedef float
JUCE Namespace.
Holds the parameters being used by an ADSR object.
Definition juce_ADSR.h:56