+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
27 kReleasedToEndEarly = -3,
+
28 kReleasedToRetrigger = -2,
+
+
+
+
+
+
+
+
36 static constexpr T EARLY_RELEASE_TIME = 20.;
+
37 static constexpr T RETRIGGER_RELEASE_TIME = 3.;
+
38 static constexpr T MIN_ENV_TIME_MS = 0.022675736961451;
+
39 static constexpr T MAX_ENV_TIME_MS = 60000.;
+
40 static constexpr T ENV_VALUE_LOW = 0.000001;
+
41 static constexpr T ENV_VALUE_HIGH = 0.999;
+
+
+
+
45 bool mEnableDBGMSG =
false;
+
+
+
+
49 T mEarlyReleaseIncr = 0.;
+
50 T mRetriggerReleaseIncr = 0.;
+
+
+
+
+
+
+
+
+
59 T mNewStartLevel = 0.;
+
+
+
+
63 bool mReleased =
true;
+
64 bool mSustainEnabled =
true;
+
+
66 std::function<void()> mResetFunc =
nullptr;
+
67 std::function<void()> mEndReleaseFunc =
nullptr;
+
+
+
74 ADSREnvelope(
const char* name =
"", std::function<
void()> resetFunc =
nullptr,
bool sustainEnabled =
true)
+
+
76 , mResetFunc(resetFunc)
+
77 , mSustainEnabled(sustainEnabled)
+
+
+
+
+
+
+
+
+
+
90 mAttackIncr = CalcIncrFromTimeLinear(
Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
+
+
93 mDecayIncr = CalcIncrFromTimeExp(
Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
+
+
96 mReleaseIncr = CalcIncrFromTimeExp(
Clip(timeMS, MIN_ENV_TIME_MS, MAX_ENV_TIME_MS), mSampleRate);
+
+
+
+
+
+
+
+
+
+
107 return mStage != kIdle;
+
+
+
+
+
+
+
+
+
+
+
+
+
125 inline void Start(T level, T timeScalar = 1.)
+
+
+
+
+
130 mScalar = 1./timeScalar;
+
+
+
+
+
+
+
138 mReleaseLevel = mPrevResult;
+
+
+
+
+
146 inline void Retrigger(T newStartLevel, T timeScalar = 1.)
+
+
+
149 mNewStartLevel = newStartLevel;
+
150 mScalar = 1./timeScalar;
+
151 mReleaseLevel = mPrevResult;
+
152 mStage = kReleasedToRetrigger;
+
+
+
+
156 if (mEnableDBGMSG) DBGMSG(
"retrigger\n");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
174 if (mEnableDBGMSG) DBGMSG(
"hard kill\n");
+
+
+
+
+
+
+
181 mReleaseLevel = mPrevResult;
+
182 mStage = kReleasedToEndEarly;
+
+
+
+
+
187 if (mEnableDBGMSG) DBGMSG(
"soft kill\n");
+
+
+
+
+
+
+
+
198 mEarlyReleaseIncr = CalcIncrFromTimeLinear(EARLY_RELEASE_TIME, sr);
+
199 mRetriggerReleaseIncr = CalcIncrFromTimeLinear(RETRIGGER_RELEASE_TIME, sr);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
224 mEnvValue += (mAttackIncr * mScalar);
+
225 if (mEnvValue > ENV_VALUE_HIGH || mAttackIncr == 0.)
+
+
+
+
+
+
+
+
233 mEnvValue -= ((mDecayIncr*mEnvValue) * mScalar);
+
234 result = (mEnvValue * (1.-sustainLevel)) + sustainLevel;
+
235 if (mEnvValue < ENV_VALUE_LOW)
+
+
+
+
+
+
241 result = sustainLevel;
+
+
+
+
+
+
+
248 result = sustainLevel;
+
+
+
251 mEnvValue -= ((mReleaseIncr*mEnvValue) * mScalar);
+
252 if(mEnvValue < ENV_VALUE_LOW || mReleaseIncr == 0.)
+
+
+
+
+
+
+
+
260 result = mEnvValue * mReleaseLevel;
+
+
262 case kReleasedToRetrigger:
+
263 mEnvValue -= mRetriggerReleaseIncr;
+
264 if(mEnvValue < ENV_VALUE_LOW)
+
+
+
267 mLevel = mNewStartLevel;
+
+
+
+
+
+
+
+
275 result = mEnvValue * mReleaseLevel;
+
+
277 case kReleasedToEndEarly:
+
278 mEnvValue -= mEarlyReleaseIncr;
+
279 if(mEnvValue < ENV_VALUE_LOW)
+
+
+
+
+
+
+
+
+
+
289 result = mEnvValue * mReleaseLevel;
+
+
+
+
+
+
+
296 mPrevResult = result;
+
297 mPrevOutput = (result * mLevel);
+
+
+
+
+
302 inline T CalcIncrFromTimeLinear(T timeMS, T sr)
const
+
+
304 if (timeMS <= 0.)
return 0.;
+
305 else return (1./sr) / (timeMS/1000.);
+
+
+
308 inline T CalcIncrFromTimeExp(T timeMS, T sr)
const
+
+
+
+
312 if (timeMS <= 0.0)
return 0.;
+
+
+
315 r = -std::expm1(1000.0 * std::log(0.001) / (sr * timeMS));
+
316 if (!(r < 1.0)) r = 1.0;
+
+
+
+
+
+
+
+
+
Utility functions and macros.
+
+
+
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...
+
+
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,...
+
void Kill(bool hard)
Kill the envelope.
+
+
void Start(T level, T timeScalar=1.)
Trigger/Start the envelope.
+
void SetSampleRate(T sr)
Set the sample rate for processing, with updates the early release time and retrigger release time co...
+
void Release()
Release the envelope.
+
ADSREnvelope(const char *name="", std::function< void()> resetFunc=nullptr, bool sustainEnabled=true)
Constructs an ADSREnvelope object.
+
T Process(T sustainLevel=0.)
Process the envelope, returning the value according to the current envelope stage.
+
void SetStageTime(int stage, T timeMS)
Sets the time for a particular envelope stage.
+
void Retrigger(T newStartLevel, T timeScalar=1.)
Retrigger the envelope.
+
BEGIN_IPLUG_NAMESPACE T Clip(T x, T lo, T hi)
Clips the value x between lo and hi.
+