OpenShot Library | libopenshot-audio 0.2.0
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*/
38class ADSR
39{
40public:
41 //==============================================================================
42 ADSR()
43 {
44 setSampleRate (44100.0);
45 setParameters ({});
46 }
47
48 //==============================================================================
49 /** Holds the parameters being used by an ADSR object. */
51 {
52 /** Attack time in seconds. */
53 float attack = 0.1f;
54
55 /** Decay time in seconds. */
56 float decay = 0.1f;
57
58 /** Sustain level. */
59 float sustain = 1.0f;
60
61 /** Release time in seconds. */
62 float release = 0.1f;
63 };
64
65 /** Sets the parameters that will be used by an ADSR object.
66
67 You must have called setSampleRate() with the correct sample rate before
68 this otherwise the values may be incorrect!
69
70 @see getParameters
71 */
73 {
74 currentParameters = newParameters;
75
76 sustainLevel = newParameters.sustain;
77 calculateRates (newParameters);
78
79 if (currentState != State::idle)
80 checkCurrentState();
81 }
82
83 /** Returns the parameters currently being used by an ADSR object.
84
85 @see setParameters
86 */
87 const Parameters& getParameters() const { return currentParameters; }
88
89 /** Returns true if the envelope is in its attack, decay, sustain or release stage. */
90 bool isActive() const noexcept { return currentState != State::idle; }
91
92 //==============================================================================
93 /** Sets the sample rate that will be used for the envelope.
94
95 This must be called before the getNextSample() or setParameters() methods.
96 */
97 void setSampleRate (double sampleRate)
98 {
99 jassert (sampleRate > 0.0);
100 sr = sampleRate;
101 }
102
103 //==============================================================================
104 /** Resets the envelope to an idle state. */
105 void reset()
106 {
107 envelopeVal = 0.0f;
108 currentState = State::idle;
109 }
110
111 /** Starts the attack phase of the envelope. */
112 void noteOn()
113 {
114 if (attackRate > 0.0f) currentState = State::attack;
115 else if (decayRate > 0.0f) currentState = State::decay;
116 else currentState = State::sustain;
117 }
118
119 /** Starts the release phase of the envelope. */
120 void noteOff()
121 {
122 if (currentState != State::idle)
123 {
124 if (releaseRate > 0.0f)
125 {
126 if (currentState != State::sustain)
127 releaseRate = static_cast<float> (envelopeVal / (currentParameters.release * sr));
128
129 currentState = State::release;
130 }
131 else
132 {
133 reset();
134 }
135 }
136 }
137
138 //==============================================================================
139 /** Returns the next sample value for an ADSR object.
140
141 @see applyEnvelopeToBuffer
142 */
144 {
145 if (currentState == State::idle)
146 return 0.0f;
147
148 if (currentState == State::attack)
149 {
150 envelopeVal += attackRate;
151
152 if (envelopeVal >= 1.0f)
153 {
154 envelopeVal = 1.0f;
155
156 if (decayRate > 0.0f)
157 currentState = State::decay;
158 else
159 currentState = State::sustain;
160 }
161 }
162 else if (currentState == State::decay)
163 {
164 envelopeVal -= decayRate;
165
166 if (envelopeVal <= sustainLevel)
167 {
168 envelopeVal = sustainLevel;
169 currentState = State::sustain;
170 }
171 }
172 else if (currentState == State::sustain)
173 {
174 envelopeVal = sustainLevel;
175 }
176 else if (currentState == State::release)
177 {
178 envelopeVal -= releaseRate;
179
180 if (envelopeVal <= 0.0f)
181 reset();
182 }
183
184 return envelopeVal;
185 }
186
187 /** This method will conveniently apply the next numSamples number of envelope values
188 to an AudioBuffer.
189
190 @see getNextSample
191 */
192 template<typename FloatType>
193 void applyEnvelopeToBuffer (AudioBuffer<FloatType>& buffer, int startSample, int numSamples)
194 {
195 jassert (startSample + numSamples <= buffer.getNumSamples());
196
197 auto numChannels = buffer.getNumChannels();
198
199 while (--numSamples >= 0)
200 {
201 auto env = getNextSample();
202
203 for (int i = 0; i < numChannels; ++i)
204 buffer.getWritePointer (i)[startSample] *= env;
205
206 ++startSample;
207 }
208 }
209
210private:
211 //==============================================================================
212 void calculateRates (const Parameters& parameters)
213 {
214 // need to call setSampleRate() first!
215 jassert (sr > 0.0);
216
217 attackRate = (parameters.attack > 0.0f ? static_cast<float> (1.0f / (parameters.attack * sr)) : -1.0f);
218 decayRate = (parameters.decay > 0.0f ? static_cast<float> ((1.0f - sustainLevel) / (parameters.decay * sr)) : -1.0f);
219 releaseRate = (parameters.release > 0.0f ? static_cast<float> (sustainLevel / (parameters.release * sr)) : -1.0f);
220 }
221
222 void checkCurrentState()
223 {
224 if (currentState == State::attack && attackRate <= 0.0f) currentState = decayRate > 0.0f ? State::decay : State::sustain;
225 else if (currentState == State::decay && decayRate <= 0.0f) currentState = State::sustain;
226 else if (currentState == State::release && releaseRate <= 0.0f) reset();
227 }
228
229 //==============================================================================
230 enum class State { idle, attack, decay, sustain, release };
231
232 State currentState = State::idle;
233 Parameters currentParameters;
234
235 double sr = 0.0;
236
237 float envelopeVal = 0.0f;
238
239 float sustainLevel = 0.0f;
240 float attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
241};
242
243} // namespace juce
244
245/** @}*/
A very simple ADSR envelope class.
Definition juce_ADSR.h:39
void setSampleRate(double sampleRate)
Sets the sample rate that will be used for the envelope.
Definition juce_ADSR.h:97
bool isActive() const noexcept
Returns true if the envelope is in its attack, decay, sustain or release stage.
Definition juce_ADSR.h:90
void setParameters(const Parameters &newParameters)
Sets the parameters that will be used by an ADSR object.
Definition juce_ADSR.h:72
void noteOff()
Starts the release phase of the envelope.
Definition juce_ADSR.h:120
float getNextSample()
Returns the next sample value for an ADSR object.
Definition juce_ADSR.h:143
void noteOn()
Starts the attack phase of the envelope.
Definition juce_ADSR.h:112
void reset()
Resets the envelope to an idle state.
Definition juce_ADSR.h:105
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:193
const Parameters & getParameters() const
Returns the parameters currently being used by an ADSR object.
Definition juce_ADSR.h:87
Holds a resizable array of primitive or copy-by-value objects.
Definition juce_Array.h:60
float attack
Attack time in seconds.
Definition juce_ADSR.h:53
float sustain
Sustain level.
Definition juce_ADSR.h:59
float release
Release time in seconds.
Definition juce_ADSR.h:62
float decay
Decay time in seconds.
Definition juce_ADSR.h:56
Holds the parameters being used by an ADSR object.
Definition juce_ADSR.h:51