mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
init
This commit is contained in:
commit
dca008e860
21 changed files with 3746 additions and 0 deletions
87
Source/DSP/Envelope.h
Normal file
87
Source/DSP/Envelope.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#pragma once
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
enum class ADSRStage { Idle = 0, Attack, Decay, Sustain, Release };
|
||||
|
||||
class ADSREnvelope {
|
||||
public:
|
||||
void prepare(double sr) {
|
||||
sampleRate = sr;
|
||||
stage = ADSRStage::Idle;
|
||||
level = 0.0f;
|
||||
}
|
||||
|
||||
void setAttack(float a) { attackTime = std::max(a, 0.001f); }
|
||||
void setDecay(float d) { decayTime = std::max(d, 0.001f); }
|
||||
void setSustain(float s) { sustainLevel = std::clamp(s, 0.0f, 1.0f); }
|
||||
void setRelease(float r) { releaseTime = std::max(r, 0.001f); }
|
||||
|
||||
void noteOn() {
|
||||
stage = ADSRStage::Attack;
|
||||
level = 0.0f;
|
||||
}
|
||||
|
||||
void noteOff() {
|
||||
if (stage != ADSRStage::Idle)
|
||||
stage = ADSRStage::Release;
|
||||
}
|
||||
|
||||
bool isActive() const { return stage != ADSRStage::Idle; }
|
||||
|
||||
float getNextSample() {
|
||||
switch (stage) {
|
||||
case ADSRStage::Idle:
|
||||
level = 0.0f;
|
||||
break;
|
||||
|
||||
case ADSRStage::Attack: {
|
||||
float attackInc = 1.0f / (attackTime * static_cast<float>(sampleRate));
|
||||
level += attackInc;
|
||||
if (level >= 1.0f) {
|
||||
level = 1.0f;
|
||||
stage = ADSRStage::Decay;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ADSRStage::Decay: {
|
||||
float decayInc = (1.0f - sustainLevel) / (decayTime * static_cast<float>(sampleRate));
|
||||
level -= decayInc;
|
||||
if (level <= sustainLevel) {
|
||||
level = sustainLevel;
|
||||
stage = ADSRStage::Sustain;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ADSRStage::Sustain:
|
||||
level = sustainLevel;
|
||||
break;
|
||||
|
||||
case ADSRStage::Release: {
|
||||
float releaseInc = level / (releaseTime * static_cast<float>(sampleRate));
|
||||
level -= releaseInc;
|
||||
if (level <= 0.0f) {
|
||||
level = 0.0f;
|
||||
stage = ADSRStage::Idle;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
float getCurrentLevel() const { return level; }
|
||||
ADSRStage getCurrentStage() const { return stage; }
|
||||
|
||||
private:
|
||||
double sampleRate = 44100.0;
|
||||
float attackTime = 0.01f;
|
||||
float decayTime = 0.3f;
|
||||
float sustainLevel = 0.7f;
|
||||
float releaseTime = 0.5f;
|
||||
float level = 0.0f;
|
||||
ADSRStage stage = ADSRStage::Idle;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue