commit 1a6789342ec35b4cd9c150e5c97d1e324dfefa69
parent 770ce08984f2ef60fdae75ef9e39b645d6c34625
Author: Matt Demanett <matt@demanett.net>
Date: Thu, 4 Feb 2021 22:40:30 -0500
DSP work for smooth LFOs.
Diffstat:
4 files changed, 100 insertions(+), 7 deletions(-)
diff --git a/src/Test.cpp b/src/Test.cpp
@@ -1,6 +1,27 @@
#include "Test.hpp"
+#ifdef LFO_SMOOTHER
+void Test::Smoother::setParams(float sampleRate, float frequency, float amount) {
+ if (_sampleRate != sampleRate || _frequency != frequency || _amount != amount) {
+ _sampleRate = sampleRate;
+ _frequency = frequency;
+ _amount = amount;
+
+ float millis = 1.0f / frequency;
+ millis /= 2.0f;
+ millis *= 1000.0f;
+ millis *= amount*amount * 25.0f;
+ _slewLimiter.setParams(_sampleRate, millis, 0.5f);
+ _integrator.setParams(clamp(0.1f - amount, 0.001f, 1.0f)); // FIXME!
+ }
+}
+
+float Test::Smoother::next(float sample) {
+ return _integrator.next(_slewLimiter.next(sample));
+}
+#endif
+
void Test::reset() {
}
@@ -443,12 +464,21 @@ void Test::processAll(const ProcessArgs& args) {
_last2 = 0.0f;
}
- // // "leaky integrator"
- // float alpha = params[PARAM1_PARAM].getValue();
- // alpha = clamp(1.0f - alpha*alpha, 0.00001f, 1.0f);
- // float sample = 5.0f * _noise1.next();
- // _last1 = alpha*_last1 + (1.0f - alpha)*sample;
- // outputs[OUT_OUTPUT].setVoltage(_last1);
+#elif INTEGRATOR
+ float alpha = params[PARAM1_PARAM].getValue();
+ alpha = clamp(alpha*alpha, 0.0f, 1.0f);
+ _integrator.setParams(alpha);
+
+ float sample = 0.0f;
+ if (inputs[IN_INPUT].isConnected()) {
+ sample = inputs[IN_INPUT].getVoltage();
+ }
+ else {
+ sample = 5.0f * _noise.next();
+ }
+
+ outputs[OUT_OUTPUT].setVoltage(_integrator.next(sample));
+ outputs[OUT2_OUTPUT].setVoltage(sample);
#elif RANDOMWALK
float change = params[PARAM1_PARAM].getValue();
@@ -464,6 +494,23 @@ void Test::processAll(const ProcessArgs& args) {
outputs[OUT_OUTPUT].setVoltage(_filter.next(in));
outputs[OUT2_OUTPUT].setVoltage(in);
+#elif LFO_SMOOTHER
+ float frequency = params[PARAM1_PARAM].getValue();
+ frequency *= 2.0f;
+ frequency -= 1.0f;
+ frequency *= 5.0f;
+ frequency += inputs[CV1_INPUT].getVoltage();
+ frequency = clamp(frequency, -5.0f, 5.0f);
+ frequency -= 7.0f;
+ frequency = cvToFrequency(frequency);
+
+ float amount = params[PARAM2_PARAM].getValue();
+ // amount *= amount;
+
+ _smoother.setParams(APP->engine->getSampleRate(), frequency, amount);
+ float in = inputs[IN_INPUT].getVoltage();
+ outputs[OUT_OUTPUT].setVoltage(_smoother.next(in));
+
#endif
}
diff --git a/src/Test.hpp b/src/Test.hpp
@@ -24,13 +24,15 @@ extern Model* modelTest;
// #define EG 1
// #define TABLES 1
// #define SLEW 1
-#define RMS 1
+// #define RMS 1
// #define FASTRMS 1
// #define RAVG 1
// #define SATURATOR 1
// #define BROWNIAN 1
+// #define INTEGRATOR 1
// #define RANDOMWALK 1
// #define DCBLOCKER 1
+#define LFO_SMOOTHER 1
#include "pitch.hpp"
#ifdef LPF
@@ -96,10 +98,15 @@ extern Model* modelTest;
#include "dsp/signal.hpp"
#elif BROWNIAN
#include "dsp/noise.hpp"
+#elif INTEGRATOR
+#include "dsp/noise.hpp"
#elif RANDOMWALK
#include "dsp/noise.hpp"
#elif DCBLOCKER
#include "dsp/filters/experiments.hpp"
+#elif LFO_SMOOTHER
+#include "dsp/signal.hpp"
+#include "dsp/pitch.hpp"
#else
#error what
#endif
@@ -235,11 +242,26 @@ struct Test : BGModule {
LowPassFilter _filter2;
float _last1 = 0.0f;
float _last2 = 0.0f;
+#elif INTEGRATOR
+ WhiteNoiseGenerator _noise;
+ Integrator _integrator;
#elif RANDOMWALK
RandomWalk _walk1;
RandomWalk _walk2;
#elif DCBLOCKER
DCBlocker _filter;
+#elif LFO_SMOOTHER
+ struct Smoother {
+ float _sampleRate = 0.0f;
+ float _frequency = 0.0f;
+ float _amount = 0.0f;
+ ShapedSlewLimiter _slewLimiter;
+ Integrator _integrator;
+
+ void setParams(float sampleRate, float frequency, float amount);
+ float next(float sample);
+ };
+ Smoother _smoother;
#endif
Test()
diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp
@@ -205,6 +205,18 @@ float ShapedSlewLimiter::next(float sample) {
}
+void Integrator::setParams(float alpha) {
+ assert(alpha >= 0.0f);
+ assert(alpha <= 1.0f);
+ _alpha = alpha;
+}
+
+float Integrator::next(float sample) {
+ // "leaky integrator"
+ return _last = (1.0f - _alpha)*_last + _alpha*sample;
+}
+
+
void CrossFader::setParams(float mix, float curve, bool linear) {
assert(mix >= -1.0f && mix <= 1.0f);
assert(curve >= -1.0f && curve <= 1.0f);
diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp
@@ -131,6 +131,18 @@ struct ShapedSlewLimiter {
float next(float sample);
};
+struct Integrator {
+ float _alpha = 0.0f;
+ float _last = 0.0f;
+
+ Integrator(float alpha = 1.0f) {
+ setParams(alpha);
+ }
+
+ void setParams(float alpha);
+ float next(float sample);
+};
+
struct CrossFader {
float _mix = 2.0f;
float _curve = 1.0f;