BogaudioModules

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

commit d571753e6242b7bffa220f9c5f825ae02d51c056
parent 47dcfa8baf66c54ba0b6302e13bfcfb9d669e160
Author: Matt Demanett <matt@demanett.net>
Date:   Wed,  7 Oct 2020 00:12:18 -0400

ADSR, others: fix decay and release stage shapes very slightly, for a cleaner / less abrupt onset of the stage, avoiding a pop when driving a VCA in some situations.

Diffstat:
Msrc/Test2.cpp | 2+-
Msrc/dsp/envelope.cpp | 15++++++++-------
Msrc/dsp/envelope.hpp | 9++++-----
Msrc/dsp/signal.hpp | 1+
4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/Test2.cpp b/src/Test2.cpp @@ -82,7 +82,7 @@ void Test2::processChannel(const ProcessArgs& args, int _c) { decayShape *= 2.0f; decayShape += 1.0f; } - _adsr.setShapes(attackShape, decayShape, decayShape); + _adsr.setShapes(attackShape, 1.0f / decayShape, 1.0f / decayShape); // FIXME: inversions here untested outputs[OUT_OUTPUT].setVoltage(_adsr.next() * 10.0f); } diff --git a/src/dsp/envelope.cpp b/src/dsp/envelope.cpp @@ -8,13 +8,15 @@ using namespace bogaudio::dsp; void EnvelopeGenerator::setSampleRate(float sampleRate) { - if (_sampleRate != sampleRate && sampleRate >= 1.0) { + assert(sampleRate >= 1.0f); + if (_sampleRate != sampleRate) { _sampleRate = sampleRate; _sampleTime = 1.0f / sampleRate; _sampleRateChanged(); } } + void ADSR::reset() { _stage = STOPPED_STAGE; _gated = false; @@ -51,7 +53,7 @@ void ADSR::setLinearShape(bool linear) { setShapes(1.0f, 1.0f, 1.0f); } else { - setShapes(0.5f, 0.5f, 0.5f); + setShapes(0.5f, 2.0f, 2.0f); } } @@ -106,7 +108,7 @@ float ADSR::_next() { } case RELEASE_STAGE: { _stage = ATTACK_STAGE; - _stageProgress = _attack * powf(_envelope, 1.0f / _releaseShape); + _stageProgress = _attack * powf(_envelope, _releaseShape); break; } } @@ -147,9 +149,9 @@ float ADSR::_next() { case DECAY_STAGE: { _stageProgress += _sampleTime; _envelope = std::min(1.0f, _stageProgress / _decay); - _envelope = powf(_envelope, _decayShape); + _envelope = powf(1.0f - _envelope, _decayShape); _envelope *= 1.0f - _sustain; - _envelope = 1.0f - _envelope; + _envelope += _sustain; break; } case SUSTAIN_STAGE: { @@ -159,9 +161,8 @@ float ADSR::_next() { case RELEASE_STAGE: { _stageProgress += _sampleTime; _envelope = std::min(1.0f, _stageProgress / _release); - _envelope = powf(_envelope, _releaseShape); + _envelope = powf(1.0f - _envelope, _releaseShape); _envelope *= _releaseLevel; - _envelope = _releaseLevel - _envelope; break; } } diff --git a/src/dsp/envelope.hpp b/src/dsp/envelope.hpp @@ -3,18 +3,17 @@ #include <stdlib.h> #include "base.hpp" +#include "signal.hpp" namespace bogaudio { namespace dsp { struct EnvelopeGenerator : Generator { - float _sampleRate; + float _sampleRate = -1.0f; float _sampleTime; - EnvelopeGenerator(float sampleRate = 1000.0f) - : _sampleRate(sampleRate > 1.0 ? sampleRate : 1.0) - , _sampleTime(1.0f / _sampleRate) - { + EnvelopeGenerator(float sampleRate = 1000.0f) { + setSampleRate(std::max(1.0f, sampleRate)); } void setSampleRate(float sampleRate); diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp @@ -106,6 +106,7 @@ struct SlewLimiter { } void setParams(float sampleRate = 1000.0f, float milliseconds = 1.0f, float range = 10.0f); + inline void setLast(float last) { _last = last; } inline float next(float sample) { return _last = next(sample, _last); }