BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

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:
MREADME-prerelease.md | 4++--
Msrc/addressable_sequence.cpp | 11++++++++++-
Msrc/addressable_sequence.hpp | 1+
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;