diff --git a/_a_d_s_r_envelope_8h_source.html b/_a_d_s_r_envelope_8h_source.html new file mode 100644 index 00000000..7e9f944b --- /dev/null +++ b/_a_d_s_r_envelope_8h_source.html @@ -0,0 +1,404 @@ + + + + + + + + +iPlug 2: ADSREnvelope.h Source File + + + + + + + + + + + + +
+
+ + + + + + +
+
iPlug2 - C++ Audio Plug-in Framework +
+
+
+ + + + + + + + +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ + +
+
+
ADSREnvelope.h
+
+
+
1/*
+
2 ==============================================================================
+
3
+
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
+
5
+
6 See LICENSE.txt for more info.
+
7
+
8 ==============================================================================
+
9 */
+
10
+
11#pragma once
+
12
+
13#include "IPlugPlatform.h"
+
14#include "IPlugUtilities.h"
+
15
+
16#include <functional>
+
17#include <cmath>
+
18
+
19BEGIN_IPLUG_NAMESPACE
+
20
+
21template <typename T>
+ +
23{
+
24public:
+
25 enum EStage
+
26 {
+
27 kReleasedToEndEarly = -3,
+
28 kReleasedToRetrigger = -2,
+
29 kIdle = -1,
+
30 kAttack,
+
31 kDecay,
+
32 kSustain,
+
33 kRelease
+
34 };
+
35
+
36 static constexpr T EARLY_RELEASE_TIME = 20.; // ms
+
37 static constexpr T RETRIGGER_RELEASE_TIME = 3.; // ms
+
38 static constexpr T MIN_ENV_TIME_MS = 0.022675736961451; // 1 sample @44100
+
39 static constexpr T MAX_ENV_TIME_MS = 60000.;
+
40 static constexpr T ENV_VALUE_LOW = 0.000001; // -120dB
+
41 static constexpr T ENV_VALUE_HIGH = 0.999;
+
42
+
43private:
+
44#if DEBUG_ENV
+
45 bool mEnableDBGMSG = false;
+
46#endif
+
47
+
48 const char* mName;
+
49 T mEarlyReleaseIncr = 0.;
+
50 T mRetriggerReleaseIncr = 0.;
+
51 T mAttackIncr = 0.;
+
52 T mDecayIncr = 0.;
+
53 T mReleaseIncr = 0.;
+
54 T mSampleRate;
+
55 T mEnvValue = 0.; // current normalized value of the envelope
+
56 int mStage = kIdle; // the current stage
+
57 T mLevel = 0.; // envelope depth from velocity
+
58 T mReleaseLevel = 0.; // the level when the env is released
+
59 T mNewStartLevel = 0.; // envelope depth from velocity when retriggering
+
60 T mPrevResult = 0.; // last value BEFORE velocity scaling
+
61 T mPrevOutput = 0.; // last value AFTER velocity scaling
+
62 T mScalar = 1.; // for key-follow scaling
+
63 bool mReleased = true;
+
64 bool mSustainEnabled = true; // when false env is AD only
+
65
+
66 std::function<void()> mResetFunc = nullptr; // reset func
+
67 std::function<void()> mEndReleaseFunc = nullptr; // end release func
+
68
+
69public:
+
74 ADSREnvelope(const char* name = "", std::function<void()> resetFunc = nullptr, bool sustainEnabled = true)
+
75 : mName(name)
+
76 , mResetFunc(resetFunc)
+
77 , mSustainEnabled(sustainEnabled)
+
78 {
+
79 SetSampleRate(44100.);
+
80 }
+
81
+
85 void SetStageTime(int stage, T timeMS)
+
86 {
+
87 switch(stage)
+
88 {
+
89 case kAttack:
+
90 mAttackIncr = CalcIncrFromTimeLinear(Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
91 break;
+
92 case kDecay:
+
93 mDecayIncr = CalcIncrFromTimeExp(Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
94 break;
+
95 case kRelease:
+
96 mReleaseIncr = CalcIncrFromTimeExp(Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
97 break;
+
98 default:
+
99 //error
+
100 break;
+
101 }
+
102 }
+
103
+
105 bool GetBusy() const
+
106 {
+
107 return mStage != kIdle;
+
108 }
+
109
+
111 bool GetReleased() const
+
112 {
+
113 return mReleased;
+
114 }
+
115
+ +
118 {
+
119 return mPrevOutput;
+
120 }
+
121
+
125 inline void Start(T level, T timeScalar = 1.)
+
126 {
+
127 mStage = kAttack;
+
128 mEnvValue = 0.;
+
129 mLevel = level;
+
130 mScalar = 1./timeScalar;
+
131 mReleased = false;
+
132 }
+
133
+
135 inline void Release()
+
136 {
+
137 mStage = kRelease;
+
138 mReleaseLevel = mPrevResult;
+
139 mEnvValue = 1.;
+
140 mReleased = true;
+
141 }
+
142
+
146 inline void Retrigger(T newStartLevel, T timeScalar = 1.)
+
147 {
+
148 mEnvValue = 1.;
+
149 mNewStartLevel = newStartLevel;
+
150 mScalar = 1./timeScalar;
+
151 mReleaseLevel = mPrevResult;
+
152 mStage = kReleasedToRetrigger;
+
153 mReleased = false;
+
154
+
155 #if DEBUG_ENV
+
156 if (mEnableDBGMSG) DBGMSG("retrigger\n");
+
157 #endif
+
158 }
+
159
+
162 inline void Kill(bool hard)
+
163 {
+
164 if(hard)
+
165 {
+
166 if (mStage != kIdle)
+
167 {
+
168 mReleaseLevel = 0.;
+
169 mStage = kIdle;
+
170 mEnvValue = 0.;
+
171 }
+
172
+
173 #if DEBUG_ENV
+
174 if (mEnableDBGMSG) DBGMSG("hard kill\n");
+
175 #endif
+
176 }
+
177 else
+
178 {
+
179 if (mStage != kIdle)
+
180 {
+
181 mReleaseLevel = mPrevResult;
+
182 mStage = kReleasedToEndEarly;
+
183 mEnvValue = 1.;
+
184 }
+
185
+
186 #if DEBUG_ENV
+
187 if (mEnableDBGMSG) DBGMSG("soft kill\n");
+
188 #endif
+
189 }
+
190 }
+
191
+
195 void SetSampleRate(T sr)
+
196 {
+
197 mSampleRate = sr;
+
198 mEarlyReleaseIncr = CalcIncrFromTimeLinear(EARLY_RELEASE_TIME, sr);
+
199 mRetriggerReleaseIncr = CalcIncrFromTimeLinear(RETRIGGER_RELEASE_TIME, sr);
+
200 }
+
201
+
205 void SetResetFunc(std::function<void()> func) { mResetFunc = func; }
+
206
+
210 void SetEndReleaseFunc(std::function<void()> func) { mEndReleaseFunc = func; }
+
211
+
214 inline T Process(T sustainLevel = 0.)
+
215 {
+
216 T result = 0.;
+
217
+
218 switch(mStage)
+
219 {
+
220 case kIdle:
+
221 result = mEnvValue;
+
222 break;
+
223 case kAttack:
+
224 mEnvValue += (mAttackIncr * mScalar);
+
225 if (mEnvValue > ENV_VALUE_HIGH || mAttackIncr == 0.)
+
226 {
+
227 mStage = kDecay;
+
228 mEnvValue = 1.;
+
229 }
+
230 result = mEnvValue;
+
231 break;
+
232 case kDecay:
+
233 mEnvValue -= ((mDecayIncr*mEnvValue) * mScalar);
+
234 result = (mEnvValue * (1.-sustainLevel)) + sustainLevel;
+
235 if (mEnvValue < ENV_VALUE_LOW)
+
236 {
+
237 if(mSustainEnabled)
+
238 {
+
239 mStage = kSustain;
+
240 mEnvValue = 1.;
+
241 result = sustainLevel;
+
242 }
+
243 else
+
244 Release();
+
245 }
+
246 break;
+
247 case kSustain:
+
248 result = sustainLevel;
+
249 break;
+
250 case kRelease:
+
251 mEnvValue -= ((mReleaseIncr*mEnvValue) * mScalar);
+
252 if(mEnvValue < ENV_VALUE_LOW || mReleaseIncr == 0.)
+
253 {
+
254 mStage = kIdle;
+
255 mEnvValue = 0.;
+
256
+
257 if(mEndReleaseFunc)
+
258 mEndReleaseFunc();
+
259 }
+
260 result = mEnvValue * mReleaseLevel;
+
261 break;
+
262 case kReleasedToRetrigger:
+
263 mEnvValue -= mRetriggerReleaseIncr;
+
264 if(mEnvValue < ENV_VALUE_LOW)
+
265 {
+
266 mStage = kAttack;
+
267 mLevel = mNewStartLevel;
+
268 mEnvValue = 0.;
+
269 mPrevResult = 0.;
+
270 mReleaseLevel = 0.;
+
271
+
272 if(mResetFunc)
+
273 mResetFunc();
+
274 }
+
275 result = mEnvValue * mReleaseLevel;
+
276 break;
+
277 case kReleasedToEndEarly:
+
278 mEnvValue -= mEarlyReleaseIncr;
+
279 if(mEnvValue < ENV_VALUE_LOW)
+
280 {
+
281 mStage = kIdle;
+
282 mLevel = 0.;
+
283 mEnvValue = 0.;
+
284 mPrevResult = 0.;
+
285 mReleaseLevel = 0.;
+
286 if(mEndReleaseFunc)
+
287 mEndReleaseFunc();
+
288 }
+
289 result = mEnvValue * mReleaseLevel;
+
290 break;
+
291 default:
+
292 result = mEnvValue;
+
293 break;
+
294 }
+
295
+
296 mPrevResult = result;
+
297 mPrevOutput = (result * mLevel);
+
298 return mPrevOutput;
+
299 }
+
300
+
301private:
+
302 inline T CalcIncrFromTimeLinear(T timeMS, T sr) const
+
303 {
+
304 if (timeMS <= 0.) return 0.;
+
305 else return (1./sr) / (timeMS/1000.);
+
306 }
+
307
+
308 inline T CalcIncrFromTimeExp(T timeMS, T sr) const
+
309 {
+
310 T r;
+
311
+
312 if (timeMS <= 0.0) return 0.;
+
313 else
+
314 {
+
315 r = -std::expm1(1000.0 * std::log(0.001) / (sr * timeMS));
+
316 if (!(r < 1.0)) r = 1.0;
+
317
+
318 return r;
+
319 }
+
320 }
+
321};
+
322
+
323END_IPLUG_NAMESPACE
+
Include to get consistently named preprocessor macros for different platforms and logging functionali...
+
Utility functions and macros.
+ +
bool GetBusy() const
Definition: ADSREnvelope.h:105
+
void SetEndReleaseFunc(std::function< void()> func)
Sets a function to call when the envelope gets released, called when the ramp is at zero WARNING: don...
Definition: ADSREnvelope.h:210
+
bool GetReleased() const
Definition: ADSREnvelope.h:111
+
void SetResetFunc(std::function< void()> func)
Sets a function to call when the envelope gets retriggered, called when the fade out ramp is at zero,...
Definition: ADSREnvelope.h:205
+
void Kill(bool hard)
Kill the envelope.
Definition: ADSREnvelope.h:162
+
T GetPrevOutput() const
Definition: ADSREnvelope.h:117
+
void Start(T level, T timeScalar=1.)
Trigger/Start the envelope.
Definition: ADSREnvelope.h:125
+
void SetSampleRate(T sr)
Set the sample rate for processing, with updates the early release time and retrigger release time co...
Definition: ADSREnvelope.h:195
+
void Release()
Release the envelope.
Definition: ADSREnvelope.h:135
+
ADSREnvelope(const char *name="", std::function< void()> resetFunc=nullptr, bool sustainEnabled=true)
Constructs an ADSREnvelope object.
Definition: ADSREnvelope.h:74
+
T Process(T sustainLevel=0.)
Process the envelope, returning the value according to the current envelope stage.
Definition: ADSREnvelope.h:214
+
void SetStageTime(int stage, T timeMS)
Sets the time for a particular envelope stage.
Definition: ADSREnvelope.h:85
+
void Retrigger(T newStartLevel, T timeScalar=1.)
Retrigger the envelope.
Definition: ADSREnvelope.h:146
+
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
+
+ + + + diff --git a/_app_view_controller_8mm_source.html b/_app_view_controller_8mm_source.html index 955d0a14..90e8b296 100644 --- a/_app_view_controller_8mm_source.html +++ b/_app_view_controller_8mm_source.html @@ -111,7 +111,7 @@
24@interface AppViewController ()
25{
26 IPlugAUPlayer* player;
-
27 IPLUG_AUVIEWCONTROLLER* pluginVC;
+
27 IPLUG_AUVIEWCONTROLLER* pluginVC;
28 IBOutlet UIView* auView;
29}
30@end
@@ -210,7 +210,6 @@
123}
124@end
125
-
IPLUG_AUVIEWCONTROLLER
Definition: IPlugAUViewController.h:18