commit 1142112a3c28379b15c474ded4788ec1f06057b8
parent 6e4202622ab37924ff524866b5c971f4bc78daa4
Author: Matt Demanett <matt@demanett.net>
Date: Sat, 21 Apr 2018 22:30:50 -0400
Set time minimums and add linear mode to ADSR; add test.
Diffstat:
4 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/src/Test2.cpp b/src/Test2.cpp
@@ -52,6 +52,21 @@ void Test2::step() {
in = inputs[IN_INPUT].value;
}
outputs[OUT_OUTPUT].value = _filter.next(in);
+
+#elif ADSR_ENVELOPE
+ if (outputs[OUT_OUTPUT].active) {
+ _adsr.setSampleRate(engineGetSampleRate());
+ if (inputs[IN_INPUT].active) {
+ _trigger.process(inputs[IN_INPUT].value);
+ }
+ _adsr.setGate(_trigger.isHigh());
+ _adsr.setAttack(params[PARAM1A_PARAM].value * 10.0f);
+ _adsr.setDecay(params[PARAM1B_PARAM].value * 10.0f);
+ _adsr.setSustain(params[PARAM2A_PARAM].value);
+ _adsr.setRelease(params[PARAM2B_PARAM].value * 10.0f);
+ _adsr.setShape(params[PARAM3A_PARAM].value > 0.5f ? ADSR::LINEAR_SHAPE : ADSR::EXPONENTIAL_SHAPE);
+ outputs[OUT_OUTPUT].value = _adsr.next() * 10.0f;
+ }
#endif
}
diff --git a/src/Test2.hpp b/src/Test2.hpp
@@ -5,12 +5,15 @@
extern Model* modelTest2;
// #define COMPLEX_BIQUAD 1
-#define MULTIPOLE 1
+// #define MULTIPOLE 1
+#define ADSR_ENVELOPE 1
#ifdef COMPLEX_BIQUAD
#include "dsp/filter.hpp"
#elif MULTIPOLE
#include "dsp/filter.hpp"
+#elif ADSR_ENVELOPE
+#include "dsp/envelope.hpp"
#elif
#error what
#endif
@@ -56,6 +59,9 @@ struct Test2 : Module {
MultipoleFilter _filter;
const int maxSteps = 10;
int _steps = maxSteps;
+#elif ADSR_ENVELOPE
+ ADSR _adsr;
+ SchmittTrigger _trigger;
#endif
Test2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
diff --git a/src/dsp/envelope.cpp b/src/dsp/envelope.cpp
@@ -1,6 +1,7 @@
#include <assert.h>
#include <math.h>
#include <stdio.h>
+#include <algorithm>
#include "envelope.hpp"
@@ -26,12 +27,12 @@ void ADSR::setGate(bool high) {
void ADSR::setAttack(float seconds) {
assert(_attack >= 0.0f);
- _attack = seconds;
+ _attack = std::max(seconds, 0.001f);
}
void ADSR::setDecay(float seconds) {
assert(_decay >= 0.0f);
- _decay = seconds;
+ _decay = std::max(seconds, 0.001f);
}
void ADSR::setSustain(float level) {
@@ -42,7 +43,11 @@ void ADSR::setSustain(float level) {
void ADSR::setRelease(float seconds) {
assert(_release >= 0.0f);
- _release = seconds;
+ _release = std::max(seconds, 0.001f);
+}
+
+void ADSR::setShape(Shape shape) {
+ _shape = shape;
}
float ADSR::_next() {
@@ -107,13 +112,17 @@ float ADSR::_next() {
case ATTACK_STAGE: {
_stageProgress += _sampleTime;
_envelope = _stageProgress / _attack;
- _envelope = powf(_envelope, 0.5f);
+ if (_shape == EXPONENTIAL_SHAPE) {
+ _envelope = powf(_envelope, 0.5f);
+ }
break;
}
case DECAY_STAGE: {
_stageProgress += _sampleTime;
_envelope = _stageProgress / _decay;
- _envelope = powf(_envelope, 0.5f);
+ if (_shape == EXPONENTIAL_SHAPE) {
+ _envelope = powf(_envelope, 0.5f);
+ }
_envelope *= 1.0f - _sustain;
_envelope = 1.0f - _envelope;
break;
@@ -125,7 +134,9 @@ float ADSR::_next() {
case RELEASE_STAGE: {
_stageProgress += _sampleTime;
_envelope = _stageProgress / _release;
- _envelope = powf(_envelope, 0.5f);
+ if (_shape == EXPONENTIAL_SHAPE) {
+ _envelope = powf(_envelope, 0.5f);
+ }
_envelope *= _releaseLevel;
_envelope = _releaseLevel - _envelope;
break;
diff --git a/src/dsp/envelope.hpp b/src/dsp/envelope.hpp
@@ -30,18 +30,25 @@ struct ADSR : EnvelopeGenerator {
RELEASE_STAGE
};
+ enum Shape {
+ LINEAR_SHAPE,
+ EXPONENTIAL_SHAPE
+ };
+
Stage _stage = STOPPED_STAGE;
bool _gated = false;
float _attack = 0.0f;
float _decay = 0.0f;
float _sustain = 1.0f;
float _release = 0.0f;
+ Shape _shape;
float _stageProgress = 0.0f;
float _releaseLevel = 0.0f;
float _envelope = 0.0f;
- ADSR(float sampleRate = 1000.0f)
+ ADSR(Shape shape = EXPONENTIAL_SHAPE, float sampleRate = 1000.0f)
: EnvelopeGenerator(sampleRate)
+ , _shape(shape)
{
}
@@ -51,6 +58,7 @@ struct ADSR : EnvelopeGenerator {
void setDecay(float seconds);
void setSustain(float level);
void setRelease(float seconds);
+ void setShape(Shape shape);
virtual float _next() override;
};