You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.8 KiB
83 lines
1.8 KiB
4 years ago
|
#include "adsr.h"
|
||
|
#include <math.h>
|
||
|
|
||
|
using namespace daisysp;
|
||
|
|
||
|
float Adsr::Tau2Pole(float tau)
|
||
|
{
|
||
|
return expf(-1.0f / (tau * sample_rate_));
|
||
|
}
|
||
|
|
||
|
float Adsr::AdsrFilter()
|
||
|
{
|
||
|
y_ = b_ * x_ + a_ * y_;
|
||
|
return y_;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Adsr::Init(float sample_rate)
|
||
|
{
|
||
|
seg_time_[ADSR_SEG_ATTACK] = 0.1f;
|
||
|
seg_time_[ADSR_SEG_DECAY] = 0.1f;
|
||
|
sus_ = 0.7f;
|
||
|
seg_time_[ADSR_SEG_RELEASE] = 0.1f;
|
||
|
//timer_ = 0;
|
||
|
a_ = 0.0f;
|
||
|
b_ = 0.0f;
|
||
|
x_ = 0.0f;
|
||
|
y_ = 0.0f;
|
||
|
prev_ = 0.0f;
|
||
|
atk_time_ = seg_time_[ADSR_SEG_ATTACK] * sample_rate;
|
||
|
sample_rate_ = sample_rate;
|
||
|
}
|
||
|
|
||
|
float Adsr::Process(bool gate)
|
||
|
{
|
||
|
float pole, out;
|
||
|
out = 0.0f;
|
||
|
|
||
|
if(gate && mode_ != ADSR_SEG_DECAY)
|
||
|
{
|
||
|
mode_ = ADSR_SEG_ATTACK;
|
||
|
//timer_ = 0;
|
||
|
pole = Tau2Pole(seg_time_[ADSR_SEG_ATTACK] * 0.6f);
|
||
|
atk_time_ = seg_time_[ADSR_SEG_ATTACK] * sample_rate_;
|
||
|
a_ = pole;
|
||
|
b_ = 1.0f - pole;
|
||
|
}
|
||
|
else if(!gate && mode_ != ADSR_SEG_IDLE)
|
||
|
{
|
||
|
mode_ = ADSR_SEG_RELEASE;
|
||
|
pole = Tau2Pole(seg_time_[ADSR_SEG_RELEASE]);
|
||
|
a_ = pole;
|
||
|
b_ = 1.0f - pole;
|
||
|
}
|
||
|
|
||
|
x_ = (int)gate;
|
||
|
prev_ = (int)gate;
|
||
|
|
||
|
switch(mode_)
|
||
|
{
|
||
|
case ADSR_SEG_IDLE: out = 0.0f; break;
|
||
|
case ADSR_SEG_ATTACK:
|
||
|
out = AdsrFilter();
|
||
|
|
||
|
if(out > .99f)
|
||
|
{
|
||
|
mode_ = ADSR_SEG_DECAY;
|
||
|
pole = Tau2Pole(seg_time_[ADSR_SEG_DECAY]);
|
||
|
a_ = pole;
|
||
|
b_ = 1.0f - pole;
|
||
|
}
|
||
|
break;
|
||
|
case ADSR_SEG_DECAY:
|
||
|
case ADSR_SEG_RELEASE:
|
||
|
x_ *= sus_;
|
||
|
out = AdsrFilter();
|
||
|
if(out <= 0.01f)
|
||
|
mode_ = ADSR_SEG_IDLE;
|
||
|
default: break;
|
||
|
}
|
||
|
return out;
|
||
|
}
|