bullet3/examples/TinyAudio/b3ADSR.cpp

113 lines
1.7 KiB
C++
Raw Normal View History

#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
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;
m_attackRate = 0.001;
m_decayRate = 0.00001;
2017-04-28 18:35:00 +00:00
m_releaseRate = 0.0005;
m_sustainLevel = 0.5;
m_state = ADSR_IDLE;
m_autoKeyOff = false;
}
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;
if (m_autoKeyOff)
{
keyOff();
}
}
}
else
{
m_value += m_decayRate; // attack target < sustain level
if (m_value >= m_sustainLevel)
{
m_value = m_sustainLevel;
m_state = ADSR_SUSTAIN;
if (m_autoKeyOff)
{
keyOff();
}
}
}
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;
}
void b3ADSR::keyOn(bool autoKeyOff)
{
m_autoKeyOff = autoKeyOff;
if (m_target <= 0.0)
m_target = 1.0;
if (m_attackRate==1)
{
m_value = 1.0;
}
m_state = ADSR_ATTACK;
}
void b3ADSR::keyOff()
{
m_autoKeyOff = false;
m_target = 0.0;
m_state = ADSR_RELEASE;
}