OpenShot Audio Library | OpenShotAudio
1.0.0
Toggle main menu visibility
Loading...
Searching...
No Matches
juce_ADSR.h
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
23
namespace
juce
24
{
25
26
//==============================================================================
40
class
JUCE_API ADSR
41
{
42
public
:
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
248
private
:
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
juce::ADSR::setSampleRate
void setSampleRate(double newSampleRate) noexcept
Definition
juce_ADSR.h:103
juce::ADSR::noteOff
void noteOff() noexcept
Definition
juce_ADSR.h:137
juce::ADSR::isActive
bool isActive() const noexcept
Definition
juce_ADSR.h:96
juce::ADSR::reset
void reset() noexcept
Definition
juce_ADSR.h:111
juce::ADSR::getNextSample
float getNextSample() noexcept
Definition
juce_ADSR.h:158
juce::ADSR::setParameters
void setParameters(const Parameters &newParameters)
Definition
juce_ADSR.h:80
juce::ADSR::noteOn
void noteOn() noexcept
Definition
juce_ADSR.h:118
juce::ADSR::getParameters
const Parameters & getParameters() const noexcept
Definition
juce_ADSR.h:93
juce::ADSR::applyEnvelopeToBuffer
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
Definition
juce_ADSR.h:219
juce::AudioBuffer
Definition
juce_AudioSampleBuffer.h:34
juce::AudioBuffer::getWritePointer
Type * getWritePointer(int channelNumber) noexcept
Definition
juce_AudioSampleBuffer.h:291
juce::AudioBuffer::getNumChannels
int getNumChannels() const noexcept
Definition
juce_AudioSampleBuffer.h:236
juce::AudioBuffer::getNumSamples
int getNumSamples() const noexcept
Definition
juce_AudioSampleBuffer.h:242
juce::AudioBuffer::clear
void clear() noexcept
Definition
juce_AudioSampleBuffer.h:556
juce::AudioBuffer::applyGain
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
Definition
juce_AudioSampleBuffer.h:684
juce::ADSR::Parameters
Definition
juce_ADSR.h:56
libopenshot-audio
JuceLibraryCode
modules
juce_audio_basics
utilities
juce_ADSR.h
Generated by
1.18.0