2017-04-27 04:31:01 +00:00
|
|
|
#include "b3ADSR.h"
|
|
|
|
//ADSR mostly copied/reimplemented from Stk, see
|
|
|
|
//http://github.com/thestk/stk
|
|
|
|
|
|
|
|
//! ADSR envelope states.
|
2017-04-27 15:42:28 +00:00
|
|
|
|
2017-04-27 04:31:01 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
ADSR_ATTACK, /*!< Attack */
|
|
|
|
ADSR_DECAY, /*!< Decay */
|
|
|
|
ADSR_SUSTAIN, /*!< Sustain */
|
|
|
|
ADSR_RELEASE, /*!< Release */
|
|
|
|
ADSR_IDLE /*!< Before attack / after release */
|
|
|
|
};
|
|
|
|
|
|
|
|
b3ADSR::b3ADSR()
|
|
|
|
{
|
|
|
|
m_target = 0.0;
|
|
|
|
m_value = 0.0;
|
2017-04-28 19:39:51 +00:00
|
|
|
m_attackRate = 0.001;
|
2017-04-27 04:31:01 +00:00
|
|
|
m_decayRate = 0.00001;
|
2017-04-28 18:35:00 +00:00
|
|
|
m_releaseRate = 0.0005;
|
2017-04-27 04:31:01 +00:00
|
|
|
m_sustainLevel = 0.5;
|
|
|
|
m_state = ADSR_IDLE;
|
2017-05-01 18:14:09 +00:00
|
|
|
m_autoKeyOff = false;
|
2017-04-27 04:31:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
b3ADSR::~b3ADSR()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
double b3ADSR::tick()
|
|
|
|
{
|
|
|
|
switch (m_state)
|
|
|
|
{
|
|
|
|
case ADSR_ATTACK:
|
|
|
|
m_value += m_attackRate;
|
|
|
|
if (m_value >= m_target)
|
|
|
|
{
|
|
|
|
m_value = m_target;
|
|
|
|
m_target = m_sustainLevel;
|
|
|
|
m_state = ADSR_DECAY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ADSR_DECAY:
|
|
|
|
if (m_value > m_sustainLevel)
|
|
|
|
{
|
|
|
|
m_value -= m_decayRate;
|
|
|
|
if (m_value <= m_sustainLevel)
|
|
|
|
{
|
|
|
|
m_value = m_sustainLevel;
|
|
|
|
m_state = ADSR_SUSTAIN;
|
2017-05-01 18:14:09 +00:00
|
|
|
if (m_autoKeyOff)
|
|
|
|
{
|
|
|
|
keyOff();
|
|
|
|
}
|
2017-04-27 04:31:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_value += m_decayRate; // attack target < sustain level
|
|
|
|
if (m_value >= m_sustainLevel)
|
|
|
|
{
|
|
|
|
m_value = m_sustainLevel;
|
|
|
|
m_state = ADSR_SUSTAIN;
|
2017-05-01 18:14:09 +00:00
|
|
|
if (m_autoKeyOff)
|
|
|
|
{
|
|
|
|
keyOff();
|
|
|
|
}
|
2017-04-27 04:31:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ADSR_RELEASE:
|
|
|
|
m_value -= m_releaseRate;
|
|
|
|
if (m_value <= 0.0)
|
|
|
|
{
|
|
|
|
m_value = 0.0;
|
|
|
|
m_state = ADSR_IDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool b3ADSR::isIdle() const
|
|
|
|
{
|
2017-04-28 18:35:00 +00:00
|
|
|
return m_state == ADSR_IDLE;
|
2017-04-27 04:31:01 +00:00
|
|
|
}
|
|
|
|
|
2017-05-01 18:14:09 +00:00
|
|
|
void b3ADSR::keyOn(bool autoKeyOff)
|
2017-04-27 04:31:01 +00:00
|
|
|
{
|
2017-05-01 18:14:09 +00:00
|
|
|
m_autoKeyOff = autoKeyOff;
|
2017-04-27 04:31:01 +00:00
|
|
|
if (m_target <= 0.0)
|
|
|
|
m_target = 1.0;
|
2018-09-23 21:17:31 +00:00
|
|
|
if (m_attackRate == 1)
|
2017-04-29 17:32:30 +00:00
|
|
|
{
|
|
|
|
m_value = 1.0;
|
|
|
|
}
|
2017-04-27 04:31:01 +00:00
|
|
|
m_state = ADSR_ATTACK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void b3ADSR::keyOff()
|
|
|
|
{
|
2017-05-01 18:14:09 +00:00
|
|
|
m_autoKeyOff = false;
|
2017-04-27 04:31:01 +00:00
|
|
|
m_target = 0.0;
|
|
|
|
m_state = ADSR_RELEASE;
|
|
|
|
}
|