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:
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);
}