OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_ADSR.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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//==============================================================================
36class ADSR
37{
38public:
39 //==============================================================================
40 ADSR()
41 {
42 setSampleRate (44100.0);
43 setParameters ({});
44 }
45
46 //==============================================================================
53 {
55 float attack = 0.1f;
56
58 float decay = 0.1f;
59
61 float sustain = 1.0f;
62
64 float release = 0.1f;
65 };
66
75 {
76 currentParameters = newParameters;
77
78 sustainLevel = newParameters.sustain;
79 calculateRates (newParameters);
80
81 if (currentState != State::idle)
82 checkCurrentState();
83 }
84
89 const Parameters& getParameters() const { return currentParameters; }
90
92 bool isActive() const noexcept { return currentState != State::idle; }
93
94 //==============================================================================
99 void setSampleRate (double sampleRate)
100 {
101 jassert (sampleRate > 0.0);
102 sr = sampleRate;
103 }
104
105 //==============================================================================
107 void reset()
108 {
109 envelopeVal = 0.0f;
110 currentState = State::idle;
111 }
112
114 void noteOn()
115 {
116 if (attackRate > 0.0f)
117 {
118 currentState = State::attack;
119 }
120 else if (decayRate > 0.0f)
121 {
122 envelopeVal = 1.0f;
123 currentState = State::decay;
124 }
125 else
126 {
127 currentState = State::sustain;
128 }
129 }
130
132 void noteOff()
133 {
134 if (currentState != State::idle)
135 {
136 if (currentParameters.release > 0.0f)
137 {
138 releaseRate = static_cast<float> (envelopeVal / (currentParameters.release * sr));
139 currentState = State::release;
140 }
141 else
142 {
143 reset();
144 }
145 }
146 }
147
148 //==============================================================================
154 {
155 if (currentState == State::idle)
156 return 0.0f;
157
158 if (currentState == State::attack)
159 {
160 envelopeVal += attackRate;
161
162 if (envelopeVal >= 1.0f)
163 {
164 envelopeVal = 1.0f;
165
166 if (decayRate > 0.0f)
167 currentState = State::decay;
168 else
169 currentState = State::sustain;
170 }
171 }
172 else if (currentState == State::decay)
173 {
174 envelopeVal -= decayRate;
175
176 if (envelopeVal <= sustainLevel)
177 {
178 envelopeVal = sustainLevel;
179 currentState = State::sustain;
180 }
181 }
182 else if (currentState == State::sustain)
183 {
184 envelopeVal = sustainLevel;
185 }
186 else if (currentState == State::release)
187 {
188 envelopeVal -= releaseRate;
189
190 if (envelopeVal <= 0.0f)
191 reset();
192 }
193
194 return envelopeVal;
195 }
196
202 template<typename FloatType>
203 void applyEnvelopeToBuffer (AudioBuffer<FloatType>& buffer, int startSample, int numSamples)
204 {
205 jassert (startSample + numSamples <= buffer.getNumSamples());
206
207 auto numChannels = buffer.getNumChannels();
208
209 while (--numSamples >= 0)
210 {
211 auto env = getNextSample();
212
213 for (int i = 0; i < numChannels; ++i)
214 buffer.getWritePointer (i)[startSample] *= env;
215
216 ++startSample;
217 }
218 }
219
220private:
221 //==============================================================================
222 void calculateRates (const Parameters& parameters)
223 {
224 // need to call setSampleRate() first!
225 jassert (sr > 0.0);
226
227 attackRate = (parameters.attack > 0.0f ? static_cast<float> (1.0f / (parameters.attack * sr)) : -1.0f);
228 decayRate = (parameters.decay > 0.0f ? static_cast<float> ((1.0f - sustainLevel) / (parameters.decay * sr)) : -1.0f);
229 }
230
231 void checkCurrentState()
232 {
233 if (currentState == State::attack && attackRate <= 0.0f) currentState = decayRate > 0.0f ? State::decay : State::sustain;
234 else if (currentState == State::decay && decayRate <= 0.0f) currentState = State::sustain;
235 else if (currentState == State::release && releaseRate <= 0.0f) reset();
236 }
237
238 //==============================================================================
239 enum class State { idle, attack, decay, sustain, release };
240
241 State currentState = State::idle;
242 Parameters currentParameters;
243
244 double sr = 0.0;
245 float envelopeVal = 0.0f, sustainLevel = 0.0f, attackRate = 0.0f, decayRate = 0.0f, releaseRate = 0.0f;
246};
247
248} // namespace juce
void setSampleRate(double sampleRate)
Definition juce_ADSR.h:99
bool isActive() const noexcept
Definition juce_ADSR.h:92
void setParameters(const Parameters &newParameters)
Definition juce_ADSR.h:74
void noteOff()
Definition juce_ADSR.h:132
float getNextSample()
Definition juce_ADSR.h:153
void noteOn()
Definition juce_ADSR.h:114
void reset()
Definition juce_ADSR.h:107
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
Definition juce_ADSR.h:203
const Parameters & getParameters() const
Definition juce_ADSR.h:89