commit 02e29973db1a3546857566d8594a4671fe6c7ec1
parent 4c75016c67d09d04897c083b655253876266de20
Author: Matt Demanett <matt@demanett.net>
Date: Thu, 15 Apr 2021 23:07:06 -0400
ADDR-SEQ, et al: add "Wrap select at steps" mode. #173
Diffstat:
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/README-prerelease.md b/README-prerelease.md
@@ -952,9 +952,9 @@ As a sequential switch, a trigger at the clock input advances the input selectio
As a multiplexer, it routes an input to the output under control of the SELECT knob and CV. A -10-10V CV, divided into 16 equal divisions of 1.25V, controls the input selection. A CV between +/-1.25V does nothing; a voltage of 1.25-2.49V will add 1 step to the selection, a voltage between -1.25V and -2.49V will subtract one step, and so on. This value is summed with the knob setting; for example, setting the knob to 4 and inputting a 2.6V CV will send input 6 to the output. When the knob-plus-CV value exceeds 8, it wraps around.
-Both functions may be used simultaneously: the SELECT+CV value is added to the sequential/clocked value, wrapping around. Note that the STEPS value only affects the sequential value; for example, using a clock input and setting STEPS to 2 will yield an alternation between two adjacent inputs, but this pair can be selected with the SELECT knob or CV.
+Both functions may be used simultaneously: the SELECT+CV value is added to the sequential/clocked value, wrapping around. Note that by default the STEPS value only affects the sequential value; for example, using a clock input and setting STEPS to 2 will yield an alternation between two adjacent inputs, but this pair can be selected with the SELECT knob or CV. The context (right-click) menu option "Wrap select at steps" changes this, such that the SELECT+CV value wraps at the value of STEPS. In this case, for example, if STEPS is 2 and SELECT+CV is 1, the sequence will alternate between steps 1 and 2, but on a reset, the sequence will reset to step 2.
-On the context (right-click) menu, if option "Reverse step on negative clock" is enabled, negative or inverted clock pulses (e.g. a pulse from 0V to -5V) will step backwards. This is still affected by the FWD/REV switch; if the switch is at REV, then a positive clock steps backwards and a negative clock forwards. This negative-clock behavior can be used to achieve voltage control over the sequence direction (the utility module <a href="#inv">INV</a> can help here).
+If option "Reverse step on negative clock" is enabled, negative or inverted clock pulses (e.g. a pulse from 0V to -5V) will step backwards. This is still affected by the FWD/REV switch; if the switch is at REV, then a positive clock steps backwards and a negative clock forwards. This negative-clock behavior can be used to achieve voltage control over the sequence direction (the utility module <a href="#inv">INV</a> can help here).
If option "Select on clock mode" is selected, then the select value (knob and CV) is checked and used to modify the active step only when a clock is received, rather than continuously.
diff --git a/src/addressable_sequence.cpp b/src/addressable_sequence.cpp
@@ -5,6 +5,7 @@
#define SELECT_ON_CLOCK "select_on_clock"
#define TRIGGERED_SELECT "triggered_select"
#define REVERSE_ON_NEGATIVE_CLOCK "reverse_on_negative_clock"
+#define WRAP_SELECT_AT_STEPS "wrap_select_at_steps"
void AddressableSequenceModule::setInputIDs(int clockInputID, int selectInputID) {
_polyInputID = clockInputID;
@@ -35,6 +36,7 @@ json_t* AddressableSequenceModule::toJson(json_t* root) {
json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
json_object_set_new(root, TRIGGERED_SELECT, json_boolean(_triggeredSelect));
json_object_set_new(root, REVERSE_ON_NEGATIVE_CLOCK, json_boolean(_reverseOnNegativeClock));
+ json_object_set_new(root, WRAP_SELECT_AT_STEPS, json_boolean(_wrapSelectAtSteps));
return root;
}
@@ -58,6 +60,11 @@ void AddressableSequenceModule::fromJson(json_t* root) {
if (r) {
_reverseOnNegativeClock = json_is_true(r);
}
+
+ json_t* w = json_object_get(root, WRAP_SELECT_AT_STEPS);
+ if (w) {
+ _wrapSelectAtSteps = json_is_true(w);
+ }
}
int AddressableSequenceModule::channels() {
@@ -116,12 +123,13 @@ int AddressableSequenceModule::nextStep(
}
else {
select += clamp(selectInput.getPolyVoltage(c), -10.0f, 10.0f) * 0.1f * (float)(n - 1);
+ // select += (clamp(selectInput.getPolyVoltage(c), -9.99f, 9.99f) / 10.f) * (float)n;
if (!_selectOnClock || clock) {
_select[c] = select;
}
}
- int s = (_step[c] + (int)_select[c]) % n;
+ int s = (_step[c] + (int)_select[c]) % (_wrapSelectAtSteps ? steps : n);
if (s < 0) {
return n + s;
}
@@ -144,6 +152,7 @@ void AddressableSequenceBaseModuleWidget::contextMenu(Menu* menu) {
menu->addChild(new BoolOptionMenuItem("Reverse step on negative clock", [m]() { return &m->_reverseOnNegativeClock; }));
menu->addChild(new BoolOptionMenuItem("Triggered select mode", [m]() { return &m->_triggeredSelect; }));
+ menu->addChild(new BoolOptionMenuItem("Wrap select at steps", [m]() { return &m->_wrapSelectAtSteps; }));
}
diff --git a/src/addressable_sequence.hpp b/src/addressable_sequence.hpp
@@ -22,6 +22,7 @@ struct AddressableSequenceModule : BGModule {
bool _selectOnClock = false;
bool _triggeredSelect = false;
bool _reverseOnNegativeClock = false;
+ bool _wrapSelectAtSteps = false;
void setInputIDs(int clockInputID, int selectInputID);
void reset() override;