OSDN Git Service

[RoastEx First] adsr.hpp Add.
authorMyun2 <myun2@nwhite.info>
Tue, 10 Aug 2010 18:05:23 +0000 (03:05 +0900)
committerMyun2 <myun2@nwhite.info>
Tue, 10 Aug 2010 18:05:23 +0000 (03:05 +0900)
roast_ex/include/roast/audio/adsr.hpp [new file with mode: 0644]

diff --git a/roast_ex/include/roast/audio/adsr.hpp b/roast_ex/include/roast/audio/adsr.hpp
new file mode 100644 (file)
index 0000000..0f0198c
--- /dev/null
@@ -0,0 +1,225 @@
+//     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__