commit a2033c875f36fccd2f5ab48cb51ce35b81faffca
parent 0f248d0263e23d4cc421d586d190790d821cc3d1
Author: Matt Demanett <matt@demanett.net>
Date: Sat, 4 May 2019 23:54:18 -0400
8:1, 1:8, ADDR-SEQ: comply with Rack standard that clocks should be ignored for 1ms after receiving a reset, since otherwise when they come in at nearly the same time the sequence effectively resets to step 2. #41 Thanks @MarcBoule
Diffstat:
8 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/src/AddrSeq.cpp b/src/AddrSeq.cpp
@@ -7,12 +7,23 @@ void AddrSeq::onReset() {
_reset.reset();
}
+void AddrSeq::onSampleRateChange() {
+ _timer.setParams(engineGetSampleRate(), 0.001f);
+}
+
void AddrSeq::step() {
+ bool reset = _reset.process(inputs[RESET_INPUT].value);
+ if (reset) {
+ _timer.reset();
+ }
+ bool timer = _timer.next();
+ bool clock = _clock.process(inputs[CLOCK_INPUT].value) && !timer;
+
int steps = clamp(params[STEPS_PARAM].value, 2.0f, 8.0f);
int reverse = 1 - 2 * (params[DIRECTION_PARAM].value == 0.0f);
- _step = (_step + reverse * _clock.process(inputs[CLOCK_INPUT].value)) % steps;
+ _step = (_step + reverse * clock) % steps;
_step += (_step < 0) * steps;
- _step -= _step * _reset.process(inputs[RESET_INPUT].value);
+ _step -= _step * reset;
int step = _step + (int)params[SELECT_PARAM].value;
step += (int)(clamp(inputs[SELECT_INPUT].value, 0.0f, 10.0f) * 0.1f * 8.0f);
step = step % 8;
diff --git a/src/AddrSeq.hpp b/src/AddrSeq.hpp
@@ -1,6 +1,9 @@
#pragma once
#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
extern Model* modelAddrSeq;
@@ -48,13 +51,16 @@ struct AddrSeq : Module {
Trigger _clock;
Trigger _reset;
+ Timer _timer;
int _step;
AddrSeq() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
onReset();
+ onSampleRateChange();
}
void onReset() override;
+ void onSampleRateChange() override;
void step() override;
};
diff --git a/src/EightOne.cpp b/src/EightOne.cpp
@@ -7,12 +7,23 @@ void EightOne::onReset() {
_reset.reset();
}
+void EightOne::onSampleRateChange() {
+ _timer.setParams(engineGetSampleRate(), 0.001f);
+}
+
void EightOne::step() {
+ bool reset = _reset.process(inputs[RESET_INPUT].value);
+ if (reset) {
+ _timer.reset();
+ }
+ bool timer = _timer.next();
+ bool clock = _clock.process(inputs[CLOCK_INPUT].value) && !timer;
+
int steps = clamp(params[STEPS_PARAM].value, 2.0f, 8.0f);
int reverse = 1 - 2 * (params[DIRECTION_PARAM].value == 0.0f);
- _step = (_step + reverse * _clock.process(inputs[CLOCK_INPUT].value)) % steps;
+ _step = (_step + reverse * clock) % steps;
_step += (_step < 0) * steps;
- _step -= _step * _reset.process(inputs[RESET_INPUT].value);
+ _step -= _step * reset;
int step = _step + (int)params[SELECT_PARAM].value;
step += (int)(clamp(inputs[SELECT_INPUT].value, 0.0f, 10.0f) * 0.1f * 8.0f);
step = step % 8;
diff --git a/src/EightOne.hpp b/src/EightOne.hpp
@@ -1,6 +1,9 @@
#pragma once
#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
extern Model* modelEightOne;
@@ -48,13 +51,16 @@ struct EightOne : Module {
Trigger _clock;
Trigger _reset;
+ Timer _timer;
int _step;
EightOne() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
onReset();
+ onSampleRateChange();
}
void onReset() override;
+ void onSampleRateChange() override;
void step() override;
};
diff --git a/src/OneEight.cpp b/src/OneEight.cpp
@@ -7,12 +7,23 @@ void OneEight::onReset() {
_reset.reset();
}
+void OneEight::onSampleRateChange() {
+ _timer.setParams(engineGetSampleRate(), 0.001f);
+}
+
void OneEight::step() {
+ bool reset = _reset.process(inputs[RESET_INPUT].value);
+ if (reset) {
+ _timer.reset();
+ }
+ bool timer = _timer.next();
+ bool clock = _clock.process(inputs[CLOCK_INPUT].value) && !timer;
+
int steps = clamp(params[STEPS_PARAM].value, 2.0f, 8.0f);
int reverse = 1 - 2 * (params[DIRECTION_PARAM].value == 0.0f);
- _step = (_step + reverse * _clock.process(inputs[CLOCK_INPUT].value)) % steps;
+ _step = (_step + reverse * clock) % steps;
_step += (_step < 0) * steps;
- _step -= _step * _reset.process(inputs[RESET_INPUT].value);
+ _step -= _step * reset;
int step = _step + (int)params[SELECT_PARAM].value;
step += (int)(clamp(inputs[SELECT_INPUT].value, 0.0f, 10.0f) * 0.1f * 8.0f);
step = step % 8;
diff --git a/src/OneEight.hpp b/src/OneEight.hpp
@@ -1,6 +1,9 @@
#pragma once
#include "bogaudio.hpp"
+#include "dsp/signal.hpp"
+
+using namespace bogaudio::dsp;
extern Model* modelOneEight;
@@ -48,13 +51,16 @@ struct OneEight : Module {
Trigger _clock;
Trigger _reset;
+ Timer _timer;
int _step;
OneEight() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
onReset();
+ onSampleRateChange();
}
void onReset() override;
+ void onSampleRateChange() override;
void step() override;
};
diff --git a/src/dsp/signal.cpp b/src/dsp/signal.cpp
@@ -495,3 +495,22 @@ float NoiseGate::compressionDb(float detectorDb, float thresholdDb, float ratio,
float compressionDb = differenceDb * ratio - differenceDb;
return std::min(compressionDb, -Amplifier::minDecibels);
}
+
+
+void Timer::setParams(float sampleRate, float time) {
+ assert(sampleRate > 0.0f);
+ assert(time > 0.0f);
+ // FIXME: if the timer is running, should set the duration to reflect the time elapsed so far, adjusting it for the delta samplerate.
+ _durationSteps = time * sampleRate;
+}
+
+void Timer::reset() {
+ _expired = false;
+ _countSteps = 0;
+}
+
+bool Timer::next() {
+ ++_countSteps;
+ _expired = _expired || _countSteps >= _durationSteps;
+ return !_expired;
+}
diff --git a/src/dsp/signal.hpp b/src/dsp/signal.hpp
@@ -238,5 +238,20 @@ struct NoiseGate {
float compressionDb(float detectorDb, float thresholdDb, float ratio, bool softKnee);
};
+struct Timer {
+ bool _expired;
+ int _countSteps;
+ int _durationSteps;
+
+ Timer(float sampleRate = 1000.0f, float time = 1.0f) {
+ setParams(sampleRate, time);
+ reset();
+ }
+
+ void setParams(float sampleRate = 1000.0f, float time = 1.0f);
+ void reset();
+ bool next();
+};
+
} // namespace dsp
} // namespace bogaudio