LMMS
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//==============================================================================
41{
42public:
43 //==============================================================================
45 {
47 }
48
49 //==============================================================================
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;
87 }
88
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 //==============================================================================
112 {
113 envelopeVal = 0.0f;
115 }
116
119 {
120 if (attackRate > 0.0f)
121 {
123 }
124 else if (decayRate > 0.0f)
125 {
126 envelopeVal = 1.0f;
128 }
129 else
130 {
131 envelopeVal = parameters.sustain;
133 }
134 }
135
138 {
139 if (state != State::idle)
140 {
141 if (parameters.release > 0.0f)
142 {
143 releaseRate = (float) (envelopeVal / (parameters.release * sampleRate));
145 }
146 else
147 {
148 reset();
149 }
150 }
151 }
152
153 //==============================================================================
159 {
160 switch (state)
161 {
162 case State::idle:
163 {
164 return 0.0f;
165 }
166
167 case State::attack:
168 {
170
171 if (envelopeVal >= 1.0f)
172 {
173 envelopeVal = 1.0f;
175 }
176
177 break;
178 }
179
180 case State::decay:
181 {
183
184 if (envelopeVal <= parameters.sustain)
185 {
186 envelopeVal = parameters.sustain;
188 }
189
190 break;
191 }
192
193 case State::sustain:
194 {
195 envelopeVal = parameters.sustain;
196 break;
197 }
198
199 case State::release:
200 {
202
203 if (envelopeVal <= 0.0f)
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 //==============================================================================
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 {
266 }
267 }
268
270 {
271 if (state == State::attack)
272 {
274 return;
275 }
276
277 if (state == State::decay)
278 {
280 return;
281 }
282
283 if (state == State::release)
284 reset();
285 }
286
287 //==============================================================================
288 enum class State { idle, attack, decay, sustain, release };
289
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
#define noexcept
Definition DistrhoDefines.h:72
void setSampleRate(double newSampleRate) noexcept
Definition juce_ADSR.h:103
void noteOff() noexcept
Definition juce_ADSR.h:137
bool isActive() const noexcept
Definition juce_ADSR.h:96
void reset() noexcept
Definition juce_ADSR.h:111
float getNextSample() noexcept
Definition juce_ADSR.h:158
float decayRate
Definition juce_ADSR.h:294
void setParameters(const Parameters &newParameters)
Definition juce_ADSR.h:80
State state
Definition juce_ADSR.h:290
float envelopeVal
Definition juce_ADSR.h:294
void goToNextState() noexcept
Definition juce_ADSR.h:269
double sampleRate
Definition juce_ADSR.h:293
void recalculateRates() noexcept
Definition juce_ADSR.h:250
State
Definition juce_ADSR.h:288
@ sustain
Definition juce_ADSR.h:288
@ release
Definition juce_ADSR.h:288
@ decay
Definition juce_ADSR.h:288
@ idle
Definition juce_ADSR.h:288
@ attack
Definition juce_ADSR.h:288
void noteOn() noexcept
Definition juce_ADSR.h:118
Parameters parameters
Definition juce_ADSR.h:291
const Parameters & getParameters() const noexcept
Definition juce_ADSR.h:93
float releaseRate
Definition juce_ADSR.h:294
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
Definition juce_ADSR.h:219
float attackRate
Definition juce_ADSR.h:294
ADSR()
Definition juce_ADSR.h:44
Definition juce_AudioSampleBuffer.h:34
register unsigned i
Definition inflate.c:1575
#define jassert(expression)
#define JUCE_API
Definition juce_StandardHeader.h:152
Definition carla_juce.cpp:31
Definition juce_ADSR.h:56
float attack
Definition juce_ADSR.h:70
Parameters(float attackTimeSeconds, float decayTimeSeconds, float sustainLevel, float releaseTimeSeconds)
Definition juce_ADSR.h:59
float sustain
Definition juce_ADSR.h:70
float release
Definition juce_ADSR.h:70
float decay
Definition juce_ADSR.h:70
#define const
Definition zconf.h:137