BogaudioModules

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

commit b6a29bb716446b9016b783a2552dd6503661eb9c
parent fe0d05f7dd38737381b45cd42519b6af21e54840
Author: Matt Demanett <matt@demanett.net>
Date:   Sun, 12 Apr 2020 22:52:05 -0400

SWITCH, INV: add option to persist latched state in the patch. #109

Diffstat:
Msrc/Inv.cpp | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/Inv.hpp | 7++++++-
Msrc/Switch.cpp | 39+++++++++++++++++++++++++++++++++++++++
Msrc/Switch.hpp | 3+++
4 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/src/Inv.cpp b/src/Inv.cpp @@ -1,6 +1,10 @@ #include "Inv.hpp" +#define SAVE_LATCHED_TO_PATCH "save_latched_to_patch" +#define LATCHED_STATE1 "latched_state1" +#define LATCHED_STATE2 "latched_state2" + void Inv::reset() { for (int c = 0; c < maxChannels; ++c) { _trigger[0][c].reset(); @@ -8,17 +12,73 @@ void Inv::reset() { } } +json_t* Inv::dataToJson() { + json_t* root = json_object(); + json_object_set_new(root, SAVE_LATCHED_TO_PATCH, json_boolean(_saveLatchedToPatch)); + if (_saveLatchedToPatch) { + if (_latch[0]) { + json_t* a = json_array(); + for (int c = 0; c < maxChannels; ++c) { + json_array_append_new(a, json_boolean(_latchedHigh[0][c])); + } + json_object_set_new(root, LATCHED_STATE1, a); + } + + if (_latch[1]) { + json_t* a = json_array(); + for (int c = 0; c < maxChannels; ++c) { + json_array_append_new(a, json_boolean(_latchedHigh[1][c])); + } + json_object_set_new(root, LATCHED_STATE2, a); + } + } + return root; +} + +void Inv::dataFromJson(json_t* root) { + json_t* sl = json_object_get(root, SAVE_LATCHED_TO_PATCH); + if (sl) { + _saveLatchedToPatch = json_is_true(sl); + if (_saveLatchedToPatch) { + json_t* a1 = json_object_get(root, LATCHED_STATE1); + if (a1 && json_array_size(a1) == maxChannels) { + for (int c = 0; c < maxChannels; ++c) { + json_t* ls = json_array_get(a1, c); + if (ls && json_is_true(ls)) { + _latchedHigh[0][c] = true; + } + } + } + + json_t* a2 = json_object_get(root, LATCHED_STATE2); + if (a2 && json_array_size(a2) == maxChannels) { + for (int c = 0; c < maxChannels; ++c) { + json_t* ls = json_array_get(a2, c); + if (ls && json_is_true(ls)) { + _latchedHigh[1][c] = true; + } + } + } + } + } +} + +void Inv::modulate() { + _latch[0] = params[LATCH1_PARAM].getValue() > 0.5f; + _latch[1] = params[LATCH2_PARAM].getValue() > 0.5f; +} + void Inv::processAll(const ProcessArgs& args) { - processDualChannel(0); - processDualChannel(1); + processDual(0); + processDual(1); } -void Inv::processDualChannel(int i) { +void Inv::processDual(int i) { int channels = inputs[IN1_INPUT + 2 * i].getChannels(); outputs[OUT1_OUTPUT + i].setChannels(channels); for (int c = 0; c < channels; ++c) { bool triggered = _trigger[i][c].process(params[GATE1_PARAM + 2 * i].getValue() + inputs[GATE1_INPUT + 2 * i].getPolyVoltage(c)); - if (params[LATCH1_PARAM + 2 * i].getValue() > 0.5f) { + if (_latch[i]) { if (triggered) { _latchedHigh[i][c] = !_latchedHigh[i][c]; } @@ -80,6 +140,13 @@ struct InvWidget : ModuleWidget { addOutput(createOutput<Port24>(out1OutputPosition, module, Inv::OUT1_OUTPUT)); addOutput(createOutput<Port24>(out2OutputPosition, module, Inv::OUT2_OUTPUT)); } + + void appendContextMenu(Menu* menu) override { + auto m = dynamic_cast<Inv*>(module); + assert(m); + menu->addChild(new MenuLabel()); + menu->addChild(new BoolOptionMenuItem("Save latched state to patch", [m]() { return &m->_saveLatchedToPatch; })); + } }; Model* modelInv = createModel<Inv, InvWidget>("Bogaudio-Inv", "INV", "Dual signal inverter", "Logic", "Dual", "Polyphonic"); diff --git a/src/Inv.hpp b/src/Inv.hpp @@ -29,7 +29,9 @@ struct Inv : BGModule { NUM_OUTPUTS }; + bool _saveLatchedToPatch = false; Trigger _trigger[2][maxChannels]; + bool _latch[2] {}; bool _latchedHigh[2][maxChannels] {{},{}}; Inv() { @@ -41,8 +43,11 @@ struct Inv : BGModule { } void reset() override; + json_t* dataToJson() override; + void dataFromJson(json_t* root) override; + void modulate() override; void processAll(const ProcessArgs& args) override; - void processDualChannel(int i); + void processDual(int i); }; } // namespace bogaudio diff --git a/src/Switch.cpp b/src/Switch.cpp @@ -1,12 +1,44 @@ #include "Switch.hpp" +#define SAVE_LATCHED_TO_PATCH "save_latched_to_patch" +#define LATCHED_STATE "latched_state" + void bogaudio::Switch::reset() { for (int i = 0; i < _channels; ++i) { _trigger[i].reset(); } } +json_t* bogaudio::Switch::dataToJson() { + json_t* root = json_object(); + json_object_set_new(root, SAVE_LATCHED_TO_PATCH, json_boolean(_saveLatchedToPatch)); + if (_saveLatchedToPatch && _latch) { + json_t* a = json_array(); + for (int c = 0; c < maxChannels; ++c) { + json_array_append_new(a, json_boolean(_latchedHigh[c])); + } + json_object_set_new(root, LATCHED_STATE, a); + } + return root; +} + +void bogaudio::Switch::dataFromJson(json_t* root) { + json_t* sl = json_object_get(root, SAVE_LATCHED_TO_PATCH); + if (sl) { + _saveLatchedToPatch = json_is_true(sl); + json_t* a = json_object_get(root, LATCHED_STATE); + if (_saveLatchedToPatch && a && json_array_size(a) == maxChannels) { + for (int c = 0; c < maxChannels; ++c) { + json_t* ls = json_array_get(a, c); + if (ls && json_is_true(ls)) { + _latchedHigh[c] = true; + } + } + } + } +} + int bogaudio::Switch::channels() { return inputs[GATE_INPUT].getChannels(); } @@ -140,6 +172,13 @@ struct SwitchWidget : ModuleWidget { addChild(createLight<SmallLight<GreenLight>>(high2LightPosition, module, bogaudio::Switch::HIGH2_LIGHT)); addChild(createLight<SmallLight<GreenLight>>(low2LightPosition, module, bogaudio::Switch::LOW2_LIGHT)); } + + void appendContextMenu(Menu* menu) override { + auto m = dynamic_cast<bogaudio::Switch*>(module); + assert(m); + menu->addChild(new MenuLabel()); + menu->addChild(new BoolOptionMenuItem("Save latched state to patch", [m]() { return &m->_saveLatchedToPatch; })); + } }; Model* modelSwitch = bogaudio::createModel<bogaudio::Switch, SwitchWidget>("Bogaudio-Switch", "SWITCH", "2-way signal router", "Switch", "Polyphonic"); diff --git a/src/Switch.hpp b/src/Switch.hpp @@ -36,6 +36,7 @@ struct Switch : BGModule { NUM_LIGHTS }; + bool _saveLatchedToPatch = false; Trigger _trigger[maxChannels]; bool _latchedHigh[maxChannels] {}; bool _latch = false; @@ -51,6 +52,8 @@ struct Switch : BGModule { } void reset() override; + json_t* dataToJson() override; + void dataFromJson(json_t* root) override; int channels() override; void channelsChanged(int before, int after) override; void modulate() override;