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