BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

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:
Msrc/Test2.cpp | 15+++++++++++++++
Msrc/Test2.hpp | 8+++++++-
Msrc/dsp/envelope.cpp | 23+++++++++++++++++------
Msrc/dsp/envelope.hpp | 10+++++++++-
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; };