OpenShot Library | OpenShotAudio 0.2.2
juce_ADSR.h
1
2/** @weakgroup juce_audio_basics-utilities
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 A very simple ADSR envelope class.
33
34 To use it, call setSampleRate() with the current sample rate and give it some parameters
35 with setParameters() then call getNextSample() to get the envelope value to be applied
36 to each audio sample or applyEnvelopeToBuffer() to apply the envelope to a whole buffer.
37
38 @tags{Audio}
39*/
40class ADSR
41{
42public:
43 //==============================================================================
44 ADSR()
45 {
46 setSampleRate (44100.0);
47 setParameters ({});
48 }
49
50 //==============================================================================
51 /**
52 Holds the parameters being used by an ADSR object.
53
54 @tags{Audio}
55 */
57 {
58 /** Attack time in seconds. */
59 float attack = 0.1f;
60
61 /** Decay time in seconds. */
62 float decay = 0.1f;
63
64 /** Sustain level. */
65 float sustain = 1.0f;
66
67 /** Release time in seconds. */
68 float release = 0.1f;
69 };
70
71 /** Sets the parameters that will be used by an ADSR object.
72
73 You must have called setSampleRate() with the correct sample rate before
74 this otherwise the values may be incorrect!
75
76 @see getParameters
77 */
78 void setParameters (const Parameters& newParameters)
79 {
80 currentParameters = newParameters;
81
82 sustainLevel = newParameters.sustain;
83 calculateRates (newParameters);
84
85 if (currentState != State::idle)
86 checkCurrentState();
87 }
88
89 /** Returns the parameters currently being used by an ADSR object.
90
91 @see setParameters
92 */
93 const Parameters& getParameters() const { return currentParameters; }
94
95 /** Returns true if the envelope is in its attack, decay, sustain or release stage. */
96 bool isActive() const noexcept { return currentState != State::idle; }
97
98 //==============================================================================
99 /** Sets the sample rate that will be used for the envelope.
100
101 This must be called before the getNextSample() or setParameters() methods.
102 */
103 void setSampleRate (double sampleRate)
104 {
105 jassert (sampleRate > 0.0);
106 sr = sampleRate;
107 }
108
109 //==============================================================================
110 /** Resets the envelope to an idle state. */
111 void reset()
112 {
113 envelopeVal = 0.0f;
114 currentState = State::idle;
115 }
116
117 /** Starts the attack phase of the envelope. */
118 void noteOn()
119 {
120 if (attackRate > 0.0f)
121 {
122 currentState = State::attack;
123 }
124 else if (decayRate > 0.0f)
125 {
126 envelopeVal = 1.0f;
127 currentState = State::decay;
128 }
129 else
130 {
131 currentState = State::sustain;
132 }
133 }
134
135 /** Starts the release phase of the envelope. */
136 void noteOff()
137 {
138 if (currentState != State::idle)
139 {
140 if (currentParameters.release > 0.0f)
141 {
142 releaseRate = static_cast<float> (envelopeVal / (currentParameters.release * sr));
143 currentState = State::release;
144 }
145 else
146 {
147 reset();
148 }
149 }
150 }
151
152 //==============================================================================
153 /** Returns the next sample value for an ADSR object.
154
155 @see applyEnvelopeToBuffer
156 */
158 {
159 if (currentState == State::idle)
160 return 0.0f;
161
162 if (currentState == State::attack)
163 {
164 envelopeVal += attackRate;
165
166 if (envelopeVal >= 1.0f)
167 {
168 envelopeVal = 1.0f;
169
170 if (decayRate > 0.0f)
171 currentState = State::decay;
172 else
173 currentState = State::sustain;
174 }
175 }
176 else if (currentState == State::decay)
177 {
178 envelopeVal -= decayRate;
179
180 if (envelopeVal <= sustainLevel)
181 {
182 envelopeVal = sustainLevel;
183 currentState = State::sustain;
184 }
185 }
186 else if (currentState == State::sustain)
187 {
188 envelopeVal = sustainLevel;
189 }
190 else if (currentState == State::release)
191 {
192 envelopeVal -= releaseRate;
193
194 if (envelopeVal <= 0.0f)
195 reset();
196 }
197
198 return envelopeVal;
199 }
200
201 /** This method will conveniently apply the next numSamples number of envelope values
202 to an AudioBuffer.
203
204 @see getNextSample
205 */
206 template<typename FloatType>
207 void applyEnvelopeToBuffer (AudioBuffer<FloatType>& buffer, int startSample, int numSamples)
208 {
209 jassert (startSample + numSamples <= buffer.getNumSamples());
210
211 auto numChannels = buffer.getNumChannels();
212
213 while (--numSamples >= 0)
214 {
215 auto env = getNextSample();
216
217 for (int i = 0; i < numChannels; ++i)
218 buffer.getWritePointer (i)[startSample] *= env;
219
220 ++startSample;
221 }
222 }
223
224private:
225 //==============================================================================
226 void calculateRates (const Parameters& parameters)
227 {
228 // need to call setSampleRate() first!
229 jassert (sr > 0.0);
230
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);
233 }
234
235 void checkCurrentState()
236 {
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();
240 }
241
242 //==============================================================================
243 enum class State { idle, attack, decay, sustain, release };
244
245 State currentState = State::idle;
246 Parameters currentParameters;
247
248 double sr = 0.0;
249 float envelopeVal = 0.0f, sustainLevel = 0.0f, attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
250};
251
252} // namespace juce
253
254/** @}*/
A very simple ADSR envelope class.
Definition: juce_ADSR.h:41
void setSampleRate(double sampleRate)
Sets the sample rate that will be used for the envelope.
Definition: juce_ADSR.h:103
bool isActive() const noexcept
Returns true if the envelope is in its attack, decay, sustain or release stage.
Definition: juce_ADSR.h:96
void setParameters(const Parameters &newParameters)
Sets the parameters that will be used by an ADSR object.
Definition: juce_ADSR.h:78
void noteOff()
Starts the release phase of the envelope.
Definition: juce_ADSR.h:136
float getNextSample()
Returns the next sample value for an ADSR object.
Definition: juce_ADSR.h:157
void noteOn()
Starts the attack phase of the envelope.
Definition: juce_ADSR.h:118
void reset()
Resets the envelope to an idle state.
Definition: juce_ADSR.h:111
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:207
const Parameters & getParameters() const
Returns the parameters currently being used by an ADSR object.
Definition: juce_ADSR.h:93
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.
Definition: juce_ADSR.h:59
float sustain
Sustain level.
Definition: juce_ADSR.h:65
float release
Release time in seconds.
Definition: juce_ADSR.h:68
float decay
Decay time in seconds.
Definition: juce_ADSR.h:62
Holds the parameters being used by an ADSR object.
Definition: juce_ADSR.h:57