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:
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);