commit 3dce7a876ee0dc9a69fcb73913a7f59019f7183b
parent 0a8d3750a690c1715bfeeb0a01f16ddb55f7dc57
Author: Matt Demanett <matt@demanett.net>
Date: Wed, 30 May 2018 23:46:07 -0400
LFO/8FO: fix pulse width knobs, such that half knob yields true 50% pulse; RunningAverage DSP and test harness for debugging.
Diffstat:
6 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/src/EightFO.cpp b/src/EightFO.cpp
@@ -55,8 +55,9 @@ void EightFO::step() {
if (inputs[SAMPLE_PWM_INPUT].active) {
pw *= clamp(inputs[SAMPLE_PWM_INPUT].value / 5.0f, -1.0f, 1.0f);
}
- pw = (pw + 1.0f) / 2.0f;
pw *= 1.0f - 2.0f * _square.minPulseWidth;
+ pw *= 0.5f;
+ pw += 0.5f;
_square.setPulseWidth(pw);
_sampleSteps = 1;
}
diff --git a/src/LFO.cpp b/src/LFO.cpp
@@ -50,8 +50,9 @@ void LFO::step() {
if (inputs[PW_INPUT].active) {
pw *= clamp(inputs[PW_INPUT].value / 5.0f, -1.0f, 1.0f);
}
- pw = (pw + 1.0f) / 2.0f;
pw *= 1.0f - 2.0f * _square.minPulseWidth;
+ pw *= 0.5f;
+ pw += 0.5f;
_square.setPulseWidth(pw);
float sample = params[SAMPLE_PARAM].value;
diff --git a/src/Test.cpp b/src/Test.cpp
@@ -377,6 +377,12 @@ void Test::step() {
outputs[OUT_OUTPUT].value = _rms.next(inputs[IN_INPUT].value);
_pef.setSensitivity(sensitivity);
outputs[OUT2_OUTPUT].value = _pef.next(inputs[IN_INPUT].value);
+
+#elif RAVG
+ if (_reset.process(inputs[CV1_INPUT].value)) {
+ _average.reset();
+ }
+ outputs[OUT_OUTPUT].value = _average.next(inputs[IN_INPUT].value);
#endif
}
diff --git a/src/Test.hpp b/src/Test.hpp
@@ -22,8 +22,9 @@ extern Model* modelTest;
// #define FEEDBACK_PM 1
// #define EG 1
// #define TABLES 1
-#define SLEW 1
+// #define SLEW 1
// #define RMS 1
+#define RAVG 1
#include "pitch.hpp"
#ifdef LPF
@@ -75,6 +76,8 @@ extern Model* modelTest;
#include "dsp/signal.hpp"
#elif RMS
#include "dsp/signal.hpp"
+#elif RAVG
+#include "dsp/signal.hpp"
#else
#error what
#endif
@@ -190,6 +193,9 @@ struct Test : Module {
#elif RMS
RootMeanSquare _rms;
PucketteEnvelopeFollower _pef;
+#elif RAVG
+ RunningAverage _average;
+ SchmittTrigger _reset;
#endif
Test()
@@ -201,6 +207,8 @@ struct Test : Module {
, _cicDecimator(STAGES)
#elif TABLES
, _table(StaticBlepTable::table(), 44100.0, 1000.0)
+#elif RAVG
+ , _average(engineGetSampleRate(), 1.0f, 1000.0f)
#endif
{
onReset();
diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp
@@ -48,7 +48,7 @@ float Amplifier::next(float s) {
}
-void RootMeanSquare::setSampleRate(float sampleRate) {
+void RunningAverage::setSampleRate(float sampleRate) {
assert(sampleRate > 0.0f);
if (_sampleRate != sampleRate) {
_sampleRate = sampleRate;
@@ -64,7 +64,7 @@ void RootMeanSquare::setSampleRate(float sampleRate) {
}
}
-void RootMeanSquare::setSensitivity(float sensitivity) {
+void RunningAverage::setSensitivity(float sensitivity) {
assert(sensitivity >= 0.0f);
assert(sensitivity <= 1.0f);
if (_initialized) {
@@ -95,21 +95,32 @@ void RootMeanSquare::setSensitivity(float sensitivity) {
_sumN = std::max(_sensitivity * _bufferN, 1.0f);
_leadI = 0;
_trailI = _bufferN - _sumN;
- _sum = 0.0f;
+ _sum = 0.0;
}
}
-float RootMeanSquare::next(float sample) {
+void RunningAverage::reset() {
+ _sum = 0.0;
+ std::fill(_buffer, _buffer + _bufferN, 0.0);
+}
+
+float RunningAverage::next(float sample) {
_sum -= _buffer[_trailI];
++_trailI;
_trailI %= _bufferN;
- _sum += _buffer[_leadI] = sample * sample;
+ _sum += _buffer[_leadI] = sample;
++_leadI;
_leadI %= _bufferN;
+ return (float)_sum / (float)_sumN;
+}
+
+
+float RootMeanSquare::next(float sample) {
+ float a = RunningAverage::next(sample * sample);
if (_sum <= 0.0) {
return 0.0f;
}
- return sqrtf((float)_sum / (float)_sumN);
+ return sqrtf(a);
}
diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp
@@ -38,7 +38,7 @@ struct Amplifier {
float next(float s);
};
-struct RootMeanSquare {
+struct RunningAverage {
float _maxDelayMS;
float _sampleRate = -1.0f;
float _sensitivity = -1.0f;
@@ -51,11 +51,11 @@ struct RootMeanSquare {
int _trailI = 0;
double _sum = 0;
- RootMeanSquare(float sampleRate = 1000.0f, float sensitivity = 1.0f, float maxDelayMS = 300.0f) : _maxDelayMS(maxDelayMS) {
+ RunningAverage(float sampleRate = 1000.0f, float sensitivity = 1.0f, float maxDelayMS = 300.0f) : _maxDelayMS(maxDelayMS) {
setSampleRate(sampleRate);
setSensitivity(sensitivity);
}
- ~RootMeanSquare() {
+ virtual ~RunningAverage() {
if (_buffer) {
delete[] _buffer;
}
@@ -63,7 +63,17 @@ struct RootMeanSquare {
void setSampleRate(float sampleRate);
void setSensitivity(float sensitivity);
- float next(float sample);
+ void reset();
+ virtual float next(float sample);
+};
+
+struct RootMeanSquare : RunningAverage {
+ RootMeanSquare(float sampleRate = 1000.0f, float sensitivity = 1.0f, float maxDelayMS = 300.0f)
+ : RunningAverage(sampleRate, sensitivity, maxDelayMS)
+ {
+ }
+
+ virtual float next(float sample) override;
};
// Puckette 2007, "Theory and Technique"