BogaudioModules

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

commit 5b143766a79d1ab0dd439d6df0cceabf7a0a7c17
parent 643798c60569e04d2f6b3196c20b2a3ac1b3e3fd
Author: Matt Demanett <matt@demanett.net>
Date:   Sun, 25 Jul 2021 21:52:43 -0400

Add unipolar mode for knob matrix mixers. #178

Diffstat:
MREADME-prerelease.md | 4+++-
Msrc/matrix_base.cpp | 28++++++++++++++++++++++++++++
Msrc/matrix_base.hpp | 2++
Msrc/widgets.cpp | 6+++++-
Msrc/widgets.hpp | 2++
5 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/README-prerelease.md b/README-prerelease.md @@ -665,7 +665,7 @@ _Polyphony:_ <a href="#polyphony">Polyphonic</a>, as on MATRIX44. A 4x4 channel matrix mixer. Each input can be routed with an independent level to each of the eight output mixes. MATRIX44 is expandable with <a href="matrix44cvm">MX44CVM</a>. -*Note that the matrix knobs are attenuverters, and default to zero.* That means there will be no output, regardless of the inputs, until some knobs are changed to non-zero values. +*Note that the matrix knobs are attenuverters, and default to zero.* That means there will be no output, regardless of the inputs, until some knobs are changed to non-zero values. The knobs can be set to unipolar mode, as below; they still default to zero. Saturation (soft clipping) limits each output to +/-12V. This can be changed to a hard clip at +/-12V on the context menu ("Output clipping") -- as described on UMIX, this is mode is better if you need to precisely sum CVs. @@ -675,6 +675,8 @@ Option "Average" sets the output to be the average of its inputs. The divisor f The knobs visually indicate their values with green/orange colors. This can be disabled on the context menu. +Option "Unipolar" sets the knobs to travel from zero to 100% over their full travel (which is to say that they can no longer be set to invert the input). The panel does not update; the tick at noon for each knob indicates 50% in this mode. + _Polyphony:_ <a href="#polyphony">Polyphonic</a>, with polyphonic channels defined by input 1. #### <a name="matrix44cvm"></a> MX44CVM diff --git a/src/matrix_base.cpp b/src/matrix_base.cpp @@ -177,19 +177,41 @@ void MatrixModuleWidget::contextMenu(Menu* menu) { #define INDICATOR_KNOBS "indicator_knobs" +#define UNIPOLAR "unipolar" json_t* KnobMatrixModule::toJson(json_t* root) { root = MatrixBaseModule::toJson(root); json_object_set_new(root, INDICATOR_KNOBS, json_boolean(_indicatorKnobs)); + json_object_set_new(root, UNIPOLAR, json_boolean(_unipolar)); return root; } void KnobMatrixModule::fromJson(json_t* root) { MatrixBaseModule::fromJson(root); + json_t* k = json_object_get(root, INDICATOR_KNOBS); if (k) { _indicatorKnobs = json_is_true(k); } + + json_t* u = json_object_get(root, UNIPOLAR); + if (u) { + _unipolar = json_is_true(u); + updateParamMinimumValues(); + } +} + +void KnobMatrixModule::updateParamMinimumValues() { + if (_unipolar) { + for (int i = 0, n = _ins * _outs; i < n; ++i) { + paramQuantities[i]->minValue = 0.0f; + params[i].value = std::max(params[i].value, 0.0f); + } + } else { + for (int i = 0, n = _ins * _outs; i < n; ++i) { + paramQuantities[i]->minValue = -1.0f; + } + } } @@ -197,6 +219,7 @@ void KnobMatrixModuleWidget::createKnob(math::Vec& position, KnobMatrixModule* m auto knob = dynamic_cast<IndicatorKnob19*>(createParam<IndicatorKnob19>(position, module, id)); if (module) { knob->setDrawColorsCallback([module]() { return module->_indicatorKnobs; }); + knob->setUnipolarCallback([module]() { return module->_unipolar; }); } addParam(knob); _knobs.push_back(knob); @@ -217,6 +240,11 @@ void KnobMatrixModuleWidget::contextMenu(Menu* menu) { [m]() { return m->_indicatorKnobs; }, [m, this]() { m->_indicatorKnobs = !m->_indicatorKnobs; this->redrawKnobs(); } )); + menu->addChild(new OptionMenuItem( + "Unipolar", + [m]() { return m->_unipolar; }, + [m, this]() { m->_unipolar = !m->_unipolar; m->updateParamMinimumValues(); this->redrawKnobs(); } + )); } diff --git a/src/matrix_base.hpp b/src/matrix_base.hpp @@ -73,6 +73,7 @@ struct MatrixModuleWidget : MatrixBaseModuleWidget { struct KnobMatrixModule : MatrixModule { bool _indicatorKnobs = true; + bool _unipolar = false; KnobMatrixModule() {} // call configMatrixModule() KnobMatrixModule(int ins, int outs, int firstParamID, int firstInputID, int firstOutputID) @@ -81,6 +82,7 @@ struct KnobMatrixModule : MatrixModule { json_t* toJson(json_t* root) override; void fromJson(json_t* root) override; + void updateParamMinimumValues(); }; struct KnobMatrixModuleWidget : MatrixModuleWidget { diff --git a/src/widgets.cpp b/src/widgets.cpp @@ -92,7 +92,11 @@ Knob68::Knob68() : BGKnob("knob_68px", 68) { void IndicatorKnob::IKWidget::setAngle(float a) { assert(a >= -1.0f && a <= 1.0f); - _angle = a * 0.83f * M_PI; + const float range = 0.83f * M_PI; + _angle = a * range; + if (_unipolarCB && _unipolarCB()) { + _angle = 2.0f * _angle - range; + } if (a < 0.0f) { _color.r = 1.0f; // 0xff _color.g = 0.6f; // 0x99 diff --git a/src/widgets.hpp b/src/widgets.hpp @@ -66,6 +66,7 @@ struct IndicatorKnob : Knob, SkinnableWidget { NVGcolor _rim = nvgRGBA(0x33, 0x33, 0x33, 0xff); NVGcolor _center = nvgRGBA(0xee, 0xee, 0xee, 0xff); std::function<bool()> _drawColorsCB; + std::function<bool()> _unipolarCB; void setAngle(float a); void draw(const DrawArgs& args) override; @@ -79,6 +80,7 @@ struct IndicatorKnob : Knob, SkinnableWidget { void onHover(const event::Hover& e) override; void onChange(const event::Change& e) override; inline void setDrawColorsCallback(std::function<bool()> fn) { w->_drawColorsCB = fn; } + inline void setUnipolarCallback(std::function<bool()> fn) { w->_unipolarCB = fn; } void redraw(); void skinChanged(const std::string& skin) override; };