OpenShot Audio Library | OpenShotAudio  0.3.1
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 
23 namespace juce
24 {
25 
26 //==============================================================================
36 class ADSR
37 {
38 public:
39  //==============================================================================
40  ADSR()
41  {
42  setSampleRate (44100.0);
43  setParameters ({});
44  }
45 
46  //==============================================================================
52  struct Parameters
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 
74  void setParameters (const Parameters& newParameters)
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 
220 private:
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
void noteOn()
Definition: juce_ADSR.h:114
void reset()
Definition: juce_ADSR.h:107
bool isActive() const noexcept
Definition: juce_ADSR.h:92
int getNumChannels() const noexcept
float getNextSample()
Definition: juce_ADSR.h:153
void noteOff()
Definition: juce_ADSR.h:132
void applyEnvelopeToBuffer(AudioBuffer< FloatType > &buffer, int startSample, int numSamples)
Definition: juce_ADSR.h:203
void setParameters(const Parameters &newParameters)
Definition: juce_ADSR.h:74
Type * getWritePointer(int channelNumber) noexcept
int getNumSamples() const noexcept
const Parameters & getParameters() const
Definition: juce_ADSR.h:89