BogaudioModules

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

commit efb795aa10dd281ad3b79c81aa72a43f404a510c
parent 9da7e5404558a17392e0c42126f73154a385ff75
Author: Matt Demanett <matt@demanett.net>
Date:   Sun, 15 May 2022 12:33:08 -0400

Switch matrix modules: fix randomization behavior to only set swtich to 0% or +/-100%, and to respect "Exclusive" options; fix labels on "Exclusive" options, which were reversed. #204

Diffstat:
MREADME-prerelease.md | 5+++++
Msrc/matrix_base.cpp | 56++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/matrix_base.hpp | 2++
3 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/README-prerelease.md b/README-prerelease.md @@ -860,6 +860,11 @@ Option "Average" sets the output to be the average of its inputs. The divisor f Two other options, "Exclusive switching by row" and "Exclusive switching by column", if enabled, allow only one switch to be enabled in a row, or column, respectively. Both options may be enabled at once. (These options do not work well with MIDI mapping via Rack's MIDI-MAP module; this is a known issue for which there is no good solution; but see the discussion [here](https://github.com/bogaudio/BogaudioModules/issues/112) for a potential workaround. The same problem may apply to other parameter-mapping methods.) +When randomizing the module from the context menu, the behavior changes based on the options: + - If neither "Exclusive" option is set, then randomizing the module sets each switch to 0% or 100% with equal probability (0%, 100%, and -100%, if inverting is enabled). + - If one "Exclusive" option is set, but not both, then on randomization exactly one switch per row (or column) is set to 100% (or -100% if inverting is enabled), all others 0%. + - If both exclusive options are set, on randomization one switch on the entire module is set to 100% (or -100%, if inverting is enabled), all others 0%. + Every switch applies a bit of slew limitation when it changes values, as an anti-popping measure. _Polyphony:_ <a href="#polyphony">polyphonic</a>, with polyphonic channels defined by input 1. diff --git a/src/matrix_base.cpp b/src/matrix_base.cpp @@ -249,6 +249,50 @@ void KnobMatrixModuleWidget::contextMenu(Menu* menu) { } +float SwitchMatrixModule::randomSwitchParamValue(bool allowZero) { + switch (_inverting) { + case NO_INVERTING: { + if (allowZero) { + return (float)(random::u32() % 2); + } + return 1.0f; + } + default: { + if (allowZero) { + return (float)(random::u32() % 3) - 1.0f; + } + return random::u32() % 2 == 0 ? -1.0f : 1.0f; + } + } +} + +void SwitchMatrixModule::onRandomize(const RandomizeEvent& e) { + if (_rowExclusive || _columnExclusive) { + for (ParamQuantity* pq : _switchParamQuantities) { + pq->setValue(0.0f); + } + + if (_rowExclusive && _columnExclusive) { + _switchParamQuantities[random::u32() % (_ins * _outs)]->setValue(randomSwitchParamValue(false)); + } + else if (_rowExclusive) { + for (int row = 0; row < _ins; ++row) { + _switchParamQuantities[row + ((random::u32() % _outs) * _ins)]->setValue(randomSwitchParamValue(false)); + } + } + else { + for (int col = 0; col < _outs; ++col) { + _switchParamQuantities[col * _ins + (random::u32() % _ins)]->setValue(randomSwitchParamValue(false)); + } + } + } + else { + for (ParamQuantity* pq : _switchParamQuantities) { + pq->setValue(randomSwitchParamValue()); + } + } +} + #define INVERTING "inverting" #define INVERTING_CLICK "click" #define INVERTING_PARAM "param" @@ -410,19 +454,19 @@ void SwitchMatrixModuleWidget::contextMenu(Menu* menu) { i->addItem(OptionMenuItem("On second click", [m]() { return m->_inverting == SwitchMatrixModule::CLICK_INVERTING; }, [m]() { m->setInverting(SwitchMatrixModule::CLICK_INVERTING); })); OptionsMenuItem::addToMenu(i, menu); - if (m->_ins > 1) { + if (m->_outs > 1) { std::string label("Exclusive switching"); - if (m->_outs > 1) { + if (m->_ins > 1) { label += " by rows"; } - menu->addChild(new OptionMenuItem(label.c_str(), [m]() { return m->_columnExclusive; }, [m]() { m->setColumnExclusive(!m->_columnExclusive); })); + menu->addChild(new OptionMenuItem(label.c_str(), [m]() { return m->_rowExclusive; }, [m]() { m->setRowExclusive(!m->_rowExclusive); })); } - if (m->_outs > 1) { + if (m->_ins > 1) { std::string label("Exclusive switching"); - if (m->_ins > 1) { + if (m->_outs > 1) { label += " by columns"; } - menu->addChild(new OptionMenuItem(label.c_str(), [m]() { return m->_rowExclusive; }, [m]() { m->setRowExclusive(!m->_rowExclusive); })); + menu->addChild(new OptionMenuItem(label.c_str(), [m]() { return m->_columnExclusive; }, [m]() { m->setColumnExclusive(!m->_columnExclusive); })); } } diff --git a/src/matrix_base.hpp b/src/matrix_base.hpp @@ -110,6 +110,8 @@ struct SwitchMatrixModule : MatrixModule { : MatrixModule(ins, outs, firstParamID, firstInputID, firstOutputID) {} + float randomSwitchParamValue(bool allowZero = true); + void onRandomize(const RandomizeEvent& e) override; json_t* saveToJson(json_t* root) override; void loadFromJson(json_t* root) override; void setInverting(Inverting inverting);