Files
SeeSynth/src/ADSR.cpp
2023-09-17 02:26:44 +03:00

94 lines
2.2 KiB
C++

#include "ADSR.h"
#include "Logger.h"
#include "Settings.h"
ADSR::ADSR(/* args */) {
m_attack_time = 1.f;
m_decay_time = 0.4f;
m_sustain_level = 0.6f;
m_release_time = 0.8f;
m_ramp = new Ramp(0, SAMPLE_RATE);
}
ADSR::~ADSR() { delete m_ramp; }
bool ADSR::IsAttackElapsed() {
return m_state == sAttack && m_ramp->IsCompleted();
}
bool ADSR::IsDecayElapsed() {
return m_state == sDecay && m_ramp->IsCompleted();
}
bool ADSR::IsReleaseElapsed() {
return m_state == sRelease && m_ramp->IsCompleted();
}
void ADSR::RecheckState() {
switch (m_state) {
case sAttack:
if (IsAttackElapsed()) {
m_state = sDecay;
m_ramp->RampTo(m_sustain_level, m_decay_time);
}
break;
case sDecay:
if (IsDecayElapsed()) {
m_state = sSustain;
}
break;
case sRelease:
if (IsReleaseElapsed()) {
m_state = sOff;
}
break;
default:
break;
}
}
void ADSR::ProcessSample(float* sample) {
if (m_state == sOff) {
(*sample) = 0;
} else if (m_state == sAttack) {
(*sample) = (*sample) * m_ramp->Process();
} else if (m_state == sDecay) {
(*sample) = (*sample) * m_ramp->Process();
} else if (m_state == sSustain) {
(*sample) = (*sample) * m_sustain_level;
} else if (m_state == sRelease) {
(*sample) = (*sample) * m_ramp->Process();
}
}
void ADSR::Trigger() {
write_log("Set ADSR\n");
if (m_state == sOff) {
m_state = sAttack;
} else if (m_state == sRelease) {
m_state = sAttack;
};
m_ramp->RampTo(1, m_attack_time);
}
void ADSR::Release() {
write_log("Unset ADSR\n");
m_state = sRelease;
m_ramp->RampTo(0, m_release_time);
}
void ADSR::Process(std::vector<float>& samples) {
for (std::size_t i = 0; i < samples.size(); i++) {
RecheckState();
ProcessSample(&samples[i]);
}
}
void ADSR::SetParameters(float attack, float decay, float sustain,
float release) {
m_attack_time = attack;
m_decay_time = decay;
m_sustain_level = sustain;
m_release_time = release;
}