commit de4d71f50145de05dc07a86b3d05afb8e78602ae
parent 0869c830ff65f5243e0f7a9ef7f9a427d54083c9
Author: Matt Demanett <matt@demanett.net>
Date: Thu, 7 Jun 2018 22:09:12 -0400
Work-in-progress limiter DSP.
Diffstat:
5 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/src/Test2.cpp b/src/Test2.cpp
@@ -85,6 +85,14 @@ void Test2::step() {
_adsr.setShapes(attackShape, decayShape, decayShape);
outputs[OUT_OUTPUT].value = _adsr.next() * 10.0f;
}
+
+#elif LIMITER
+ float shape = params[PARAM1A_PARAM].value * 5.0f;
+ float knee = params[PARAM2A_PARAM].value * 10.0f;
+ float limit = params[PARAM2B_PARAM].value * 15.0f;
+ float scale = params[PARAM1B_PARAM].value * 2.0f + 1.0f;
+ _limiter.setParams(shape, knee, limit, scale);
+ outputs[OUT_OUTPUT].value = _limiter.next(inputs[IN_INPUT].value);
#endif
}
diff --git a/src/Test2.hpp b/src/Test2.hpp
@@ -6,7 +6,8 @@ extern Model* modelTest2;
// #define COMPLEX_BIQUAD 1
// #define MULTIPOLE 1
-#define ADSR_ENVELOPE 1
+// #define ADSR_ENVELOPE 1
+#define LIMITER 1
#ifdef COMPLEX_BIQUAD
#include "dsp/filter.hpp"
@@ -14,6 +15,8 @@ extern Model* modelTest2;
#include "dsp/filter.hpp"
#elif ADSR_ENVELOPE
#include "dsp/envelope.hpp"
+#elif LIMITER
+#include "dsp/signal.hpp"
#elif
#error what
#endif
@@ -62,6 +65,8 @@ struct Test2 : Module {
#elif ADSR_ENVELOPE
ADSR _adsr;
SchmittTrigger _trigger;
+#elif LIMITER
+ Limiter _limiter;
#endif
Test2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp
@@ -103,11 +103,13 @@ void SaturatingSawOscillator::setSaturation(float saturation) {
if (_saturation != saturation) {
assert(saturation >= 0.0f);
_saturation = saturation;
- if (_saturation < 1.0f) {
- _saturationNormalization = 1.0f / tanhf(_saturation * M_PI);
- }
- else {
- _saturationNormalization = 1.0f;
+ if (_saturation >= 0.1f) {
+ if (_saturation < 1.0f) {
+ _saturationNormalization = 1.0f / tanhf(_saturation * M_PI);
+ }
+ else {
+ _saturationNormalization = 1.0f;
+ }
}
}
}
diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp
@@ -361,3 +361,51 @@ float DelayLine::next(float sample) {
int DelayLine::delaySamples() {
return std::max((_time * _maxTimeMS / 1000.0f) * _sampleRate, 1.0f);
}
+
+
+void Limiter::setParams(float shape, float knee, float limit, float scale) {
+ assert(shape >= 0.0f);
+ assert(knee >= 0.0f);
+ assert(limit >= 0.0f);
+ assert(scale >= 1.0f);
+ _shape = shape;
+ _knee = knee;
+ _limit = std::max(knee, limit);
+ _scale = scale;
+
+ if (_shape >= 0.1f) {
+ if (_shape < 1.0f) {
+ _normalization = 1.0f / tanhf(_shape * M_PI);
+ }
+ else {
+ _normalization = 1.0f;
+ }
+ }
+}
+
+float Limiter::next(float sample) {
+ float out = abs(sample);
+ if (out > _knee) {
+ out -= _knee;
+ out /= _scale;
+ if (_shape >= 0.1f) {
+ // out /= _limit - _knee;
+ // out = _tanhf.value(out * _shape * M_PI) * _normalization;
+ // out *= _limit - _knee;
+ float x = out / (_limit - _knee);
+ x = _tanhf.value(x * _shape * M_PI) * _normalization;
+ x = std::min(x, 1.0f);
+ x *= _limit - _knee;
+ out = std::min(abs(sample) - _knee, x);
+ }
+ else {
+ out = std::min(out, _limit - _knee);
+ }
+ out += _knee;
+ }
+
+ if (sample < 0.0f) {
+ return -out;
+ }
+ return out;
+}
diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp
@@ -2,6 +2,7 @@
#include <math.h>
+#include "math.hpp"
#include "table.hpp"
namespace bogaudio {
@@ -205,5 +206,19 @@ struct DelayLine {
int delaySamples();
};
+struct Limiter {
+ float _shape;
+ float _knee;
+ float _limit;
+ float _scale;
+ float _normalization;
+ FastTanhf _tanhf;
+
+ Limiter() {}
+
+ void setParams(float shape = 1.0f, float knee = 5.0f, float limit = 10.0f, float scale = 2.0f);
+ float next(float sample);
+};
+
} // namespace dsp
} // namespace bogaudio