--- /dev/null
+// Roast+ License
+
+/*
+ ADSR Class
+*/
+#ifndef __SFJP_ROAST_EX__special_audio__adsr_HPP__
+#define __SFJP_ROAST_EX__special_audio__adsr_HPP__
+
+namespace roast
+{
+ namespace special
+ {
+ namespace audio
+ {
+ // ADSR Class
+ template <typename TIME_T, typename RANGE_T=float, bool ENABLE_EX=true>
+ class adsr
+ {
+ public:
+ TIME_T m_time;
+ bool m_bOn;
+
+ // Paramators
+ TIME_T m_attackDelayTime;
+ TIME_T m_attackTime;
+ TIME_T m_decayTime;
+ RANGE_T m_sustainLevel;
+ TIME_T m_releaseTime;
+
+ // Memory
+ TIME_T m_offTime;
+ RANGE_T m_offLevel;
+
+ public:
+ // Constructor/Destructor
+ adsr(){
+ m_time = 0;
+ m_bOn = false;
+
+ m_attackTime = 0;
+ m_decayTime = 0;
+ m_sustainLevel = 1.0f;
+ m_releaseTime = 0;
+ m_attackDelayTime = 0;
+
+ m_offTime = 0;
+ m_offLevel = 1;
+ }
+ adsr(TIME_T in_attack, TIME_T in_decay, RANGE_T in_sustain, TIME_T in_release){
+ m_time = 0;
+ m_bOn = false;
+
+ m_attackTime = in_attack;
+ m_decayTime = in_decay;
+ m_sustainLevel = in_sustain;
+ m_releaseTime = in_release;
+ m_attackDelayTime = 0;
+
+ m_offTime = 0;
+ m_offLevel = 1;
+ }
+ //CMyun2Adsr(TIME_T in_time){ m_time = in_time; }
+ virtual ~adsr(){}
+
+ ///////////////////////////////////////////////////////
+
+ inline void setAttackTime(TIME_T in_time){ m_attackTime = in_time; }
+ inline void setAttackDelay(TIME_T in_time){ m_attackDelayTime = in_time; }
+ inline void setDecayTime(TIME_T in_time){ m_decayTime = in_time; }
+ inline void setSustainLevel(RANGE_T sustainLevel){ m_sustainLevel = sustainLevel; }
+ inline void setReleaseTime(TIME_T in_time){ m_releaseTime = in_time; }
+
+ inline void on(){
+ m_time = 0;
+ m_bOn = true;
+ m_offTime = 0;
+ }
+
+ inline void off(TIME_T t){
+ if ( m_bOn ){
+ // 2010/01/03 myun2 Memory Off Level. (for Release Level)
+ m_offLevel = get(t);
+
+ m_bOn = false;
+ m_offTime = t;
+ }
+ }
+
+ ///////////////////////////////////////////////////////
+
+ // Switch EX/No EX
+ inline TIME_T _get_t_switch(TIME_T t)
+ {
+ if ( ENABLE_EX )
+ return t - m_attackDelayTime;
+ else
+ return t;
+ }
+
+ inline RANGE_T get(TIME_T t){
+ // Note ON
+ if ( m_bOn )
+ {
+ TIME_T t2 = _get_t_switch(t);
+ if ( ENABLE_EX && t < m_attackDelayTime ){
+ // AttackDelay
+ return 0;
+ }
+ if ( t2 < m_attackTime ){
+ // Attack
+ return (RANGE_T) (t2 / m_attackTime);
+ }
+ else if ( (t2-m_attackTime) < m_decayTime ){
+ // Decay
+ return (RANGE_T) ((1.0f - (t2 - m_attackTime) / m_decayTime) * (1.0f-m_sustainLevel) + m_sustainLevel);
+ }
+ else{
+ // Sustain
+ return m_sustainLevel;
+ }
+ }
+ // Note OFF
+ else
+ {
+ //if ( m_offTime != 0 && m_releaseTime != 0 )
+ if ( (t-m_offTime) < m_releaseTime )
+ {
+ // Release
+ //return (RANGE_T) ((1.0f - (t-m_offTime) / m_releaseTime) * m_sustainLevel);
+ return (RANGE_T) ((1.0f - (t-m_offTime) / m_releaseTime) * m_offLevel); // 2010/01/03 myun2 Use off level.
+ }
+ else
+ return 0;
+ }
+ }
+
+ // Ended?
+ //bool isEnd(){ if ( !m_bOn &&
+ };
+
+ ///////////////////////////////////////////////////////////////////
+
+ // ADSR Timer Class
+ template <typename TIME_T, typename RANGE_T=float>
+ class adsr_timer : public adsr<TIME_T,RANGE_T>
+ {
+ private:
+ typedef adsr _BASE;
+ public:
+ TIME_T m_nowTime;
+ public:
+ // Constructor/Destructor
+ adsr_timer(){ m_nowTime=0; }
+ adsr_timer(TIME_T in_attack, TIME_T in_decay, RANGE_T in_sustain, TIME_T in_release)
+ : _BASE(in_attack,in_decay,in_sustain,in_release) { m_nowTime=0; }
+ virtual ~adsr_timer(){}
+
+ ///////////////////////////////////////////////////////
+
+ inline void on(){
+ _BASE::on();
+ m_nowTime = 0;
+ }
+
+ inline void off(){
+ _BASE::off(m_nowTime);
+ }
+
+ inline RANGE_T get(){
+ return _BASE::get(m_nowTime);
+ }
+
+ inline void addTime(TIME_T t){ m_nowTime += t; }
+ inline void countUp(TIME_T t){ m_nowTime += t; }
+
+ inline adsr_timer& operator += (TIME_T t){
+ addTime(t);
+ return *this;
+ }
+ };
+ }
+ }
+}
+
+/*
+Memo
+
+----------------------------------
+
+Attack:
+
+m_attackTime=1000
+
+t=300
+
+return 0.3;
+
+----------------------------------
+
+Decay:
+
+m_decayTime=500
+
+t=1200 -> 200
+
+m_sustainLevel=0.8
+
+0.5*0.2+0.8
+0.5*(1.0-0.8)+0.8
+Y*(1.0-X)+X
+
+----------------------------------
+
+Release:
+
+m_offTime=1800
+m_releaseTime=500
+
+t=2000
+
+return
+
+*/
+
+#endif//__SFJP_ROAST_EX__special_audio__adsr_HPP__