commit b4808db9fd141ff66a5dc1edb4089985e19666f7
parent 71b217f2c7f46a299291cdac848b6635ce673606
Author: Matt Demanett <matt@demanett.net>
Date: Mon, 15 Jul 2019 00:58:18 -0400
Refactoring: simplify TriggerOnLoad* and DisableOutputLimit*; factor modules that have a "select on clock" behavior in similar way.
Diffstat:
29 files changed, 326 insertions(+), 402 deletions(-)
diff --git a/src/AddrSeq.cpp b/src/AddrSeq.cpp
@@ -1,7 +1,6 @@
#include "AddrSeq.hpp"
-#define SELECT_ON_CLOCK "select_on_clock"
#define RANGE_OFFSET "range_offset"
#define RANGE_SCALE "range_scale"
@@ -39,18 +38,14 @@ void AddrSeq::onSampleRateChange() {
}
json_t* AddrSeq::dataToJson() {
- json_t* root = json_object();
- json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
+ json_t* root = SelectOnClockModule::dataToJson();
json_object_set_new(root, RANGE_OFFSET, json_real(_rangeOffset));
json_object_set_new(root, RANGE_SCALE, json_real(_rangeScale));
return root;
}
void AddrSeq::dataFromJson(json_t* root) {
- json_t* s = json_object_get(root, SELECT_ON_CLOCK);
- if (s) {
- _selectOnClock = json_is_true(s);
- }
+ SelectOnClockModule::dataFromJson(root);
json_t* ro = json_object_get(root, RANGE_OFFSET);
if (ro) {
@@ -94,23 +89,6 @@ void AddrSeq::process(const ProcessArgs& args) {
outputs[OUT_OUTPUT].setVoltage(out);
}
-struct SelectOnClockMenuItem : MenuItem {
- AddrSeq* _module;
-
- SelectOnClockMenuItem(AddrSeq* module, const char* label)
- : _module(module)
- {
- this->text = label;
- }
-
- void onAction(const event::Action& e) override {
- _module->_selectOnClock = !_module->_selectOnClock;
- }
-
- void step() override {
- rightText = _module->_selectOnClock ? "✔" : "";
- }
-};
struct AddrSeqRangeMenuItem : MenuItem {
AddrSeq* _module;
@@ -134,7 +112,7 @@ struct AddrSeqRangeMenuItem : MenuItem {
}
};
-struct AddrSeqWidget : ModuleWidget {
+struct AddrSeqWidget : SelectOnClockModuleWidget {
static constexpr int hp = 6;
AddrSeqWidget(AddrSeq* module) {
@@ -217,11 +195,11 @@ struct AddrSeqWidget : ModuleWidget {
}
void appendContextMenu(Menu* menu) override {
+ SelectOnClockModuleWidget::appendContextMenu(menu);
+
AddrSeq* m = dynamic_cast<AddrSeq*>(module);
assert(m);
menu->addChild(new MenuLabel());
- menu->addChild(new SelectOnClockMenuItem(m, "Select on clock"));
- menu->addChild(new MenuLabel());
menu->addChild(new AddrSeqRangeMenuItem(m, "Range: +/-10V", 0.0f, 10.0f));
menu->addChild(new AddrSeqRangeMenuItem(m, "Range: +/-5V", 0.0f, 5.0f));
menu->addChild(new AddrSeqRangeMenuItem(m, "Range: +/-3V", 0.0f, 3.0f));
diff --git a/src/AddrSeq.hpp b/src/AddrSeq.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "select_on_clock.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -9,7 +10,7 @@ extern Model* modelAddrSeq;
namespace bogaudio {
-struct AddrSeq : Module {
+struct AddrSeq : SelectOnClockModule {
enum ParamsIds {
STEPS_PARAM,
DIRECTION_PARAM,
@@ -53,7 +54,6 @@ struct AddrSeq : Module {
Trigger _reset;
bogaudio::dsp::Timer _timer;
int _step;
- bool _selectOnClock = false;
int _select = 0;
float _rangeOffset = 0.0f;
float _rangeScale = 10.0f;
diff --git a/src/DADSRH.cpp b/src/DADSRH.cpp
@@ -1,7 +1,7 @@
#include "DADSRH.hpp"
-struct DADSRHWidget : ModuleWidget {
+struct DADSRHWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 10;
DADSRHWidget(DADSRH* module) {
@@ -94,13 +94,6 @@ struct DADSRHWidget : ModuleWidget {
addChild(createLight<TinyLight<GreenLight>>(releaseShape2LightPosition, module, DADSRH::RELEASE_SHAPE2_LIGHT));
addChild(createLight<TinyLight<GreenLight>>(releaseShape3LightPosition, module, DADSRH::RELEASE_SHAPE3_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- DADSRH* dadsrh = dynamic_cast<DADSRH*>(module);
- assert(dadsrh);
- menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(dadsrh, "Resume loop on load"));
- }
};
Model* modelDADSRH = bogaudio::createModel<DADSRH, DADSRHWidget>("Bogaudio-DADSRH", "DADSR(H)", "advanced envelope", "Envelope generator");
diff --git a/src/DADSRH.hpp b/src/DADSRH.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
#include "dadsrh_core.hpp"
extern Model* modelDADSRH;
@@ -56,65 +57,10 @@ struct DADSRH : TriggerOnLoadModule {
NUM_LIGHTS
};
- DADSRHCore _core;
+ DADSRHCore* _core;
- DADSRH() : TriggerOnLoadModule(
- NUM_PARAMS,
- NUM_INPUTS,
- NUM_OUTPUTS,
- NUM_LIGHTS
- )
- , _core(
- params[DELAY_PARAM],
- params[ATTACK_PARAM],
- params[DECAY_PARAM],
- params[SUSTAIN_PARAM],
- params[RELEASE_PARAM],
- params[HOLD_PARAM],
- params[ATTACK_SHAPE_PARAM],
- params[DECAY_SHAPE_PARAM],
- params[RELEASE_SHAPE_PARAM],
- params[TRIGGER_PARAM],
- params[MODE_PARAM],
- params[LOOP_PARAM],
- params[SPEED_PARAM],
- params[RETRIGGER_PARAM],
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- inputs[TRIGGER_INPUT],
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- outputs[ENV_OUTPUT],
- outputs[INV_OUTPUT],
- outputs[TRIGGER_OUTPUT],
-
- lights[DELAY_LIGHT],
- lights[ATTACK_LIGHT],
- lights[DECAY_LIGHT],
- lights[SUSTAIN_LIGHT],
- lights[RELEASE_LIGHT],
- lights[ATTACK_SHAPE1_LIGHT],
- lights[ATTACK_SHAPE2_LIGHT],
- lights[ATTACK_SHAPE3_LIGHT],
- lights[DECAY_SHAPE1_LIGHT],
- lights[DECAY_SHAPE2_LIGHT],
- lights[DECAY_SHAPE3_LIGHT],
- lights[RELEASE_SHAPE1_LIGHT],
- lights[RELEASE_SHAPE2_LIGHT],
- lights[RELEASE_SHAPE3_LIGHT],
-
- _triggerOnLoad,
- _shouldTriggerOnLoad
- ) {
+ DADSRH() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", " s");
configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", " s");
configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", " s");
@@ -130,19 +76,74 @@ struct DADSRH : TriggerOnLoadModule {
configParam(SPEED_PARAM, 0.0f, 1.0f, 1.0f, "Speed");
configParam(RETRIGGER_PARAM, 0.0f, 1.0f, 1.0f, "Retrigger");
+ _core = new DADSRHCore(
+ params[DELAY_PARAM],
+ params[ATTACK_PARAM],
+ params[DECAY_PARAM],
+ params[SUSTAIN_PARAM],
+ params[RELEASE_PARAM],
+ params[HOLD_PARAM],
+ params[ATTACK_SHAPE_PARAM],
+ params[DECAY_SHAPE_PARAM],
+ params[RELEASE_SHAPE_PARAM],
+ params[TRIGGER_PARAM],
+ params[MODE_PARAM],
+ params[LOOP_PARAM],
+ params[SPEED_PARAM],
+ params[RETRIGGER_PARAM],
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ inputs[TRIGGER_INPUT],
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ outputs[ENV_OUTPUT],
+ outputs[INV_OUTPUT],
+ outputs[TRIGGER_OUTPUT],
+
+ lights[DELAY_LIGHT],
+ lights[ATTACK_LIGHT],
+ lights[DECAY_LIGHT],
+ lights[SUSTAIN_LIGHT],
+ lights[RELEASE_LIGHT],
+ lights[ATTACK_SHAPE1_LIGHT],
+ lights[ATTACK_SHAPE2_LIGHT],
+ lights[ATTACK_SHAPE3_LIGHT],
+ lights[DECAY_SHAPE1_LIGHT],
+ lights[DECAY_SHAPE2_LIGHT],
+ lights[DECAY_SHAPE3_LIGHT],
+ lights[RELEASE_SHAPE1_LIGHT],
+ lights[RELEASE_SHAPE2_LIGHT],
+ lights[RELEASE_SHAPE3_LIGHT],
+
+ _triggerOnLoad,
+ _shouldTriggerOnLoad
+ );
+
onReset();
}
+ virtual ~DADSRH() {
+ delete _core;
+ }
void onReset() override {
- _core.reset();
+ _core->reset();
}
void process(const ProcessArgs& args) override {
- _core.step();
+ _core->step();
}
bool shouldTriggerOnNextLoad() override {
- return _core._stage != _core.STOPPED_STAGE;
+ return _core->_stage != _core->STOPPED_STAGE;
}
};
diff --git a/src/DADSRHPlus.cpp b/src/DADSRHPlus.cpp
@@ -1,7 +1,7 @@
#include "DADSRHPlus.hpp"
-struct DADSRHPlusWidget : ModuleWidget {
+struct DADSRHPlusWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 15;
DADSRHPlusWidget(DADSRHPlus* module) {
@@ -116,13 +116,6 @@ struct DADSRHPlusWidget : ModuleWidget {
addChild(createLight<TinyLight<GreenLight>>(releaseShape2LightPosition, module, DADSRHPlus::RELEASE_SHAPE2_LIGHT));
addChild(createLight<TinyLight<GreenLight>>(releaseShape3LightPosition, module, DADSRHPlus::RELEASE_SHAPE3_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- DADSRHPlus* dadsrhPlus = dynamic_cast<DADSRHPlus*>(module);
- assert(dadsrhPlus);
- menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(dadsrhPlus, "Resume loop on load"));
- }
};
Model* modelDADSRHPlus = bogaudio::createModel<DADSRHPlus, DADSRHPlusWidget>("Bogaudio-DADSRHPlus", "DADSR(H)+", "advanced envelope", "Envelope generator");
diff --git a/src/DADSRHPlus.hpp b/src/DADSRHPlus.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
#include "dadsrh_core.hpp"
extern Model* modelDADSRHPlus;
@@ -67,65 +68,10 @@ struct DADSRHPlus : TriggerOnLoadModule {
NUM_LIGHTS
};
- DADSRHCore _core;
+ DADSRHCore* _core;
- DADSRHPlus() : TriggerOnLoadModule(
- NUM_PARAMS,
- NUM_INPUTS,
- NUM_OUTPUTS,
- NUM_LIGHTS
- )
- , _core(
- params[DELAY_PARAM],
- params[ATTACK_PARAM],
- params[DECAY_PARAM],
- params[SUSTAIN_PARAM],
- params[RELEASE_PARAM],
- params[HOLD_PARAM],
- params[ATTACK_SHAPE_PARAM],
- params[DECAY_SHAPE_PARAM],
- params[RELEASE_SHAPE_PARAM],
- params[TRIGGER_PARAM],
- params[MODE_PARAM],
- params[LOOP_PARAM],
- params[SPEED_PARAM],
- params[RETRIGGER_PARAM],
-
- &inputs[DELAY_INPUT],
- &inputs[ATTACK_INPUT],
- &inputs[DECAY_INPUT],
- &inputs[SUSTAIN_INPUT],
- &inputs[RELEASE_INPUT],
- &inputs[HOLD_INPUT],
- inputs[TRIGGER_INPUT],
-
- &outputs[DELAY_OUTPUT],
- &outputs[ATTACK_OUTPUT],
- &outputs[DECAY_OUTPUT],
- &outputs[SUSTAIN_OUTPUT],
- &outputs[RELEASE_OUTPUT],
- outputs[ENV_OUTPUT],
- outputs[INV_OUTPUT],
- outputs[TRIGGER_OUTPUT],
-
- lights[DELAY_LIGHT],
- lights[ATTACK_LIGHT],
- lights[DECAY_LIGHT],
- lights[SUSTAIN_LIGHT],
- lights[RELEASE_LIGHT],
- lights[ATTACK_SHAPE1_LIGHT],
- lights[ATTACK_SHAPE2_LIGHT],
- lights[ATTACK_SHAPE3_LIGHT],
- lights[DECAY_SHAPE1_LIGHT],
- lights[DECAY_SHAPE2_LIGHT],
- lights[DECAY_SHAPE3_LIGHT],
- lights[RELEASE_SHAPE1_LIGHT],
- lights[RELEASE_SHAPE2_LIGHT],
- lights[RELEASE_SHAPE3_LIGHT],
-
- _triggerOnLoad,
- _shouldTriggerOnLoad
- ) {
+ DADSRHPlus() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", " s");
configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", " s");
configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", " s");
@@ -141,19 +87,73 @@ struct DADSRHPlus : TriggerOnLoadModule {
configParam(SPEED_PARAM, 0.0f, 1.0f, 1.0f, "Speed");
configParam(RETRIGGER_PARAM, 0.0f, 1.0f, 1.0f, "Retrigger");
+ _core = new DADSRHCore(
+ params[DELAY_PARAM],
+ params[ATTACK_PARAM],
+ params[DECAY_PARAM],
+ params[SUSTAIN_PARAM],
+ params[RELEASE_PARAM],
+ params[HOLD_PARAM],
+ params[ATTACK_SHAPE_PARAM],
+ params[DECAY_SHAPE_PARAM],
+ params[RELEASE_SHAPE_PARAM],
+ params[TRIGGER_PARAM],
+ params[MODE_PARAM],
+ params[LOOP_PARAM],
+ params[SPEED_PARAM],
+ params[RETRIGGER_PARAM],
+
+ &inputs[DELAY_INPUT],
+ &inputs[ATTACK_INPUT],
+ &inputs[DECAY_INPUT],
+ &inputs[SUSTAIN_INPUT],
+ &inputs[RELEASE_INPUT],
+ &inputs[HOLD_INPUT],
+ inputs[TRIGGER_INPUT],
+
+ &outputs[DELAY_OUTPUT],
+ &outputs[ATTACK_OUTPUT],
+ &outputs[DECAY_OUTPUT],
+ &outputs[SUSTAIN_OUTPUT],
+ &outputs[RELEASE_OUTPUT],
+ outputs[ENV_OUTPUT],
+ outputs[INV_OUTPUT],
+ outputs[TRIGGER_OUTPUT],
+
+ lights[DELAY_LIGHT],
+ lights[ATTACK_LIGHT],
+ lights[DECAY_LIGHT],
+ lights[SUSTAIN_LIGHT],
+ lights[RELEASE_LIGHT],
+ lights[ATTACK_SHAPE1_LIGHT],
+ lights[ATTACK_SHAPE2_LIGHT],
+ lights[ATTACK_SHAPE3_LIGHT],
+ lights[DECAY_SHAPE1_LIGHT],
+ lights[DECAY_SHAPE2_LIGHT],
+ lights[DECAY_SHAPE3_LIGHT],
+ lights[RELEASE_SHAPE1_LIGHT],
+ lights[RELEASE_SHAPE2_LIGHT],
+ lights[RELEASE_SHAPE3_LIGHT],
+
+ _triggerOnLoad,
+ _shouldTriggerOnLoad
+ );
onReset();
}
+ virtual ~DADSRHPlus() {
+ delete _core;
+ }
void onReset() override {
- _core.reset();
+ _core->reset();
}
void process(const ProcessArgs& args) override {
- _core.step();
+ _core->step();
}
bool shouldTriggerOnNextLoad() override {
- return _core._stage != _core.STOPPED_STAGE;
+ return _core->_stage != _core->STOPPED_STAGE;
}
};
diff --git a/src/DGate.cpp b/src/DGate.cpp
@@ -69,7 +69,7 @@ bool DGate::stepStage(Param& knob) {
return _stageProgress > t;
}
-struct DGateWidget : ModuleWidget {
+struct DGateWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 3;
DGateWidget(DGate* module) {
@@ -114,13 +114,6 @@ struct DGateWidget : ModuleWidget {
addChild(createLight<TinyLight<GreenLight>>(delayLightPosition, module, DGate::DELAY_LIGHT));
addChild(createLight<TinyLight<GreenLight>>(gateLightPosition, module, DGate::GATE_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- DGate* dgate = dynamic_cast<DGate*>(module);
- assert(dgate);
- menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(dgate, "Resume loop on load"));
- }
};
Model* modelDGate = bogaudio::createModel<DGate, DGateWidget>("Bogaudio-DGate", "DGate", "trigger-to-gate with delay", "Utility");
diff --git a/src/DGate.hpp b/src/DGate.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
extern Model* modelDGate;
@@ -44,7 +45,8 @@ struct DGate : TriggerOnLoadModule {
Stage _stage;
float _stageProgress;
- DGate() : TriggerOnLoadModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ DGate() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<EnvelopeSegmentParamQuantity>(DELAY_PARAM, 0.0f, 1.0f, 0.0f, "Delay", " s");
configParam<EnvelopeSegmentParamQuantity>(GATE_PARAM, 0.0f, 1.0f, 0.31623f, "Gate", " s");
configParam(LOOP_PARAM, 0.0f, 1.0f, 1.0f, "Loop");
diff --git a/src/EightOne.cpp b/src/EightOne.cpp
@@ -1,8 +1,6 @@
#include "EightOne.hpp"
-#define SELECT_ON_CLOCK "select_on_clock"
-
void EightOne::onReset() {
_step = 0;
_clock.reset();
@@ -13,19 +11,6 @@ void EightOne::onSampleRateChange() {
_timer.setParams(APP->engine->getSampleRate(), 0.001f);
}
-json_t* EightOne::dataToJson() {
- json_t* root = json_object();
- json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
- return root;
-}
-
-void EightOne::dataFromJson(json_t* root) {
- json_t* s = json_object_get(root, SELECT_ON_CLOCK);
- if (s) {
- _selectOnClock = json_is_true(s);
- }
-}
-
void EightOne::process(const ProcessArgs& args) {
bool reset = _reset.process(inputs[RESET_INPUT].getVoltage());
if (reset) {
@@ -55,25 +40,7 @@ void EightOne::process(const ProcessArgs& args) {
outputs[OUT_OUTPUT].setVoltage(out);
}
-struct SelectOnClockMenuItem : MenuItem {
- EightOne* _module;
-
- SelectOnClockMenuItem(EightOne* module, const char* label)
- : _module(module)
- {
- this->text = label;
- }
-
- void onAction(const event::Action& e) override {
- _module->_selectOnClock = !_module->_selectOnClock;
- }
-
- void step() override {
- rightText = _module->_selectOnClock ? "✔" : "";
- }
-};
-
-struct EightOneWidget : ModuleWidget {
+struct EightOneWidget : SelectOnClockModuleWidget {
static constexpr int hp = 6;
EightOneWidget(EightOne* module) {
@@ -154,13 +121,6 @@ struct EightOneWidget : ModuleWidget {
addChild(createLight<SmallLight<GreenLight>>(in7LightPosition, module, EightOne::IN7_LIGHT));
addChild(createLight<SmallLight<GreenLight>>(in8LightPosition, module, EightOne::IN8_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- EightOne* m = dynamic_cast<EightOne*>(module);
- assert(m);
- menu->addChild(new MenuLabel());
- menu->addChild(new SelectOnClockMenuItem(m, "Select on clock"));
- }
};
Model* modelEightOne = bogaudio::createModel<EightOne, EightOneWidget>("Bogaudio-EightOne", "8:1", "demux & sequential switch", "Switch");
diff --git a/src/EightOne.hpp b/src/EightOne.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "select_on_clock.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -9,7 +10,7 @@ extern Model* modelEightOne;
namespace bogaudio {
-struct EightOne : Module {
+struct EightOne : SelectOnClockModule {
enum ParamsIds {
STEPS_PARAM,
DIRECTION_PARAM,
@@ -53,7 +54,6 @@ struct EightOne : Module {
Trigger _reset;
bogaudio::dsp::Timer _timer;
int _step;
- bool _selectOnClock = false;
int _select = 0;
EightOne() {
@@ -68,8 +68,6 @@ struct EightOne : Module {
void onReset() override;
void onSampleRateChange() override;
- json_t* dataToJson() override;
- void dataFromJson(json_t* root) override;
void process(const ProcessArgs& args) override;
};
diff --git a/src/Manual.cpp b/src/Manual.cpp
@@ -29,7 +29,7 @@ void Manual::process(const ProcessArgs& args) {
_firstStep = false;
}
-struct ManualWidget : ModuleWidget {
+struct ManualWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 3;
ManualWidget(Manual* module) {
@@ -72,10 +72,10 @@ struct ManualWidget : ModuleWidget {
}
void appendContextMenu(Menu* menu) override {
- Manual* manual = dynamic_cast<Manual*>(module);
- assert(manual);
+ TriggerOnLoadModule* m = dynamic_cast<TriggerOnLoadModule*>(module);
+ assert(m);
menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(manual, "Trigger on load"));
+ menu->addChild(new TriggerOnLoadMenuItem(m, "Trigger on load"));
}
};
diff --git a/src/Manual.hpp b/src/Manual.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
extern Model* modelManual;
@@ -36,7 +37,8 @@ struct Manual : TriggerOnLoadModule {
Trigger _trigger;
rack::dsp::PulseGenerator _pulse;
- Manual() : TriggerOnLoadModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ Manual() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam(TRIGGER_PARAM, 0.0f, 1.0f, 0.0f, "Trigger");
_triggerOnLoad = false;
onReset();
diff --git a/src/Offset.cpp b/src/Offset.cpp
@@ -27,7 +27,8 @@ float Offset::knobValue(const Param& knob, Input& cv) const {
struct OffsetWidget : DisableOutputLimitModuleWidget {
static constexpr int hp = 3;
- OffsetWidget(Offset* module) : DisableOutputLimitModuleWidget(module) {
+ OffsetWidget(Offset* module) {
+ setModule(module);
box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
{
diff --git a/src/Offset.hpp b/src/Offset.hpp
@@ -26,7 +26,8 @@ struct Offset : DisableOutputLimitModule {
NUM_OUTPUTS
};
- Offset() : DisableOutputLimitModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {
+ Offset() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
configParam(OFFSET_PARAM, -1.0f, 1.0f, 0.0f, "Offset", " V", 0.0f, 5.0f);
configParam(SCALE_PARAM, -1.0f, 1.0f, 0.316f, "Scale", "%", 0.0f, 100.0f);
}
diff --git a/src/OneEight.cpp b/src/OneEight.cpp
@@ -1,8 +1,6 @@
#include "OneEight.hpp"
-#define SELECT_ON_CLOCK "select_on_clock"
-
void OneEight::onReset() {
_step = 0;
_clock.reset();
@@ -13,19 +11,6 @@ void OneEight::onSampleRateChange() {
_timer.setParams(APP->engine->getSampleRate(), 0.001f);
}
-json_t* OneEight::dataToJson() {
- json_t* root = json_object();
- json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
- return root;
-}
-
-void OneEight::dataFromJson(json_t* root) {
- json_t* s = json_object_get(root, SELECT_ON_CLOCK);
- if (s) {
- _selectOnClock = json_is_true(s);
- }
-}
-
void OneEight::process(const ProcessArgs& args) {
bool reset = _reset.process(inputs[RESET_INPUT].getVoltage());
if (reset) {
@@ -54,25 +39,7 @@ void OneEight::process(const ProcessArgs& args) {
}
}
-struct SelectOnClockMenuItem : MenuItem {
- OneEight* _module;
-
- SelectOnClockMenuItem(OneEight* module, const char* label)
- : _module(module)
- {
- this->text = label;
- }
-
- void onAction(const event::Action& e) override {
- _module->_selectOnClock = !_module->_selectOnClock;
- }
-
- void step() override {
- rightText = _module->_selectOnClock ? "✔" : "";
- }
-};
-
-struct OneEightWidget : ModuleWidget {
+struct OneEightWidget : SelectOnClockModuleWidget {
static constexpr int hp = 6;
OneEightWidget(OneEight* module) {
@@ -153,13 +120,6 @@ struct OneEightWidget : ModuleWidget {
addChild(createLight<SmallLight<GreenLight>>(out7LightPosition, module, OneEight::OUT7_LIGHT));
addChild(createLight<SmallLight<GreenLight>>(out8LightPosition, module, OneEight::OUT8_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- OneEight* m = dynamic_cast<OneEight*>(module);
- assert(m);
- menu->addChild(new MenuLabel());
- menu->addChild(new SelectOnClockMenuItem(m, "Select on clock"));
- }
};
Model* modelOneEight = bogaudio::createModel<OneEight, OneEightWidget>("Bogaudio-OneEight", "1:8", "mux & sequential switch", "Switch");
diff --git a/src/OneEight.hpp b/src/OneEight.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "select_on_clock.hpp"
#include "dsp/signal.hpp"
using namespace bogaudio::dsp;
@@ -9,7 +10,7 @@ extern Model* modelOneEight;
namespace bogaudio {
-struct OneEight : Module {
+struct OneEight : SelectOnClockModule {
enum ParamsIds {
STEPS_PARAM,
DIRECTION_PARAM,
@@ -53,7 +54,6 @@ struct OneEight : Module {
Trigger _reset;
bogaudio::dsp::Timer _timer;
int _step;
- bool _selectOnClock = false;
int _select = 0;
OneEight() {
@@ -68,8 +68,6 @@ struct OneEight : Module {
void onReset() override;
void onSampleRateChange() override;
- json_t* dataToJson() override;
- void dataFromJson(json_t* root) override;
void process(const ProcessArgs& args) override;
};
diff --git a/src/Shaper.cpp b/src/Shaper.cpp
@@ -1,7 +1,7 @@
#include "Shaper.hpp"
-struct ShaperWidget : ModuleWidget {
+struct ShaperWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 10;
ShaperWidget(Shaper* module) {
@@ -70,13 +70,6 @@ struct ShaperWidget : ModuleWidget {
addChild(createLight<TinyLight<GreenLight>>(decayLightPosition, module, Shaper::DECAY_LIGHT));
addChild(createLight<TinyLight<GreenLight>>(offLightPosition, module, Shaper::OFF_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- Shaper* shaper = dynamic_cast<Shaper*>(module);
- assert(shaper);
- menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(shaper, "Resume loop on load"));
- }
};
Model* modelShaper = bogaudio::createModel<Shaper, ShaperWidget>("Bogaudio-Shaper", "Shaper", "envelope and amplifier", "Envelope generator", "VCA");
diff --git a/src/Shaper.hpp b/src/Shaper.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
#include "shaper_core.hpp"
extern Model* modelShaper;
@@ -43,52 +44,10 @@ struct Shaper : TriggerOnLoadModule {
NUM_LIGHTS
};
- ShaperCore _core;
+ ShaperCore* _core;
- Shaper() : TriggerOnLoadModule(
- NUM_PARAMS,
- NUM_INPUTS,
- NUM_OUTPUTS,
- NUM_LIGHTS
- )
- , _core(
- params[ATTACK_PARAM],
- params[ON_PARAM],
- params[DECAY_PARAM],
- params[OFF_PARAM],
- params[ENV_PARAM],
- params[SIGNAL_PARAM],
- params[TRIGGER_PARAM],
- params[SPEED_PARAM],
- params[LOOP_PARAM],
-
- inputs[SIGNAL_INPUT],
- inputs[TRIGGER_INPUT],
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-
- outputs[SIGNAL_OUTPUT],
- outputs[ENV_OUTPUT],
- outputs[INV_OUTPUT],
- outputs[TRIGGER_OUTPUT],
- NULL,
- NULL,
- NULL,
- NULL,
-
- lights[ATTACK_LIGHT],
- lights[ON_LIGHT],
- lights[DECAY_LIGHT],
- lights[OFF_LIGHT],
-
- _triggerOnLoad,
- _shouldTriggerOnLoad
- )
- {
+ Shaper() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", " s");
configParam<EnvelopeSegmentParamQuantity>(ON_PARAM, 0.0f, 1.0f, 0.31623f, "On", " s");
configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", " s");
@@ -99,19 +58,59 @@ struct Shaper : TriggerOnLoadModule {
configParam(SPEED_PARAM, 0.0f, 1.0f, 1.0f, "Speed");
configParam(LOOP_PARAM, 0.0f, 1.0f, 1.0f, "Loop");
+ _core = new ShaperCore(
+ params[ATTACK_PARAM],
+ params[ON_PARAM],
+ params[DECAY_PARAM],
+ params[OFF_PARAM],
+ params[ENV_PARAM],
+ params[SIGNAL_PARAM],
+ params[TRIGGER_PARAM],
+ params[SPEED_PARAM],
+ params[LOOP_PARAM],
+
+ inputs[SIGNAL_INPUT],
+ inputs[TRIGGER_INPUT],
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ outputs[SIGNAL_OUTPUT],
+ outputs[ENV_OUTPUT],
+ outputs[INV_OUTPUT],
+ outputs[TRIGGER_OUTPUT],
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ lights[ATTACK_LIGHT],
+ lights[ON_LIGHT],
+ lights[DECAY_LIGHT],
+ lights[OFF_LIGHT],
+
+ _triggerOnLoad,
+ _shouldTriggerOnLoad
+ );
onReset();
}
+ virtual ~Shaper() {
+ delete _core;
+ }
void onReset() override {
- _core.reset();
+ _core->reset();
}
void process(const ProcessArgs& args) override {
- _core.step();
+ _core->step();
}
bool shouldTriggerOnNextLoad() override {
- return _core._stage != _core.STOPPED_STAGE;
+ return _core->_stage != _core->STOPPED_STAGE;
}
};
diff --git a/src/ShaperPlus.cpp b/src/ShaperPlus.cpp
@@ -1,7 +1,7 @@
#include "ShaperPlus.hpp"
-struct ShaperPlusWidget : ModuleWidget {
+struct ShaperPlusWidget : TriggerOnLoadModuleWidget {
static constexpr int hp = 15;
ShaperPlusWidget(ShaperPlus* module) {
@@ -92,13 +92,6 @@ struct ShaperPlusWidget : ModuleWidget {
addChild(createLight<TinyLight<GreenLight>>(decayLightPosition, module, ShaperPlus::DECAY_LIGHT));
addChild(createLight<TinyLight<GreenLight>>(offLightPosition, module, ShaperPlus::OFF_LIGHT));
}
-
- void appendContextMenu(Menu* menu) override {
- ShaperPlus* shaperPlus = dynamic_cast<ShaperPlus*>(module);
- assert(shaperPlus);
- menu->addChild(new MenuLabel());
- menu->addChild(new TriggerOnLoadMenuItem(shaperPlus, "Resume loop on load"));
- }
};
Model* modelShaperPlus = bogaudio::createModel<ShaperPlus, ShaperPlusWidget>("Bogaudio-ShaperPlus", "Shaper+", "envelope and amplifier", "Envelope generator", "VCA");
diff --git a/src/ShaperPlus.hpp b/src/ShaperPlus.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "bogaudio.hpp"
+#include "trigger_on_load.hpp"
#include "shaper_core.hpp"
extern Model* modelShaperPlus;
@@ -50,52 +51,10 @@ struct ShaperPlus : TriggerOnLoadModule {
NUM_LIGHTS
};
- ShaperCore _core;
+ ShaperCore* _core;
- ShaperPlus() : TriggerOnLoadModule(
- NUM_PARAMS,
- NUM_INPUTS,
- NUM_OUTPUTS,
- NUM_LIGHTS
- )
- , _core(
- params[ATTACK_PARAM],
- params[ON_PARAM],
- params[DECAY_PARAM],
- params[OFF_PARAM],
- params[ENV_PARAM],
- params[SIGNAL_PARAM],
- params[TRIGGER_PARAM],
- params[SPEED_PARAM],
- params[LOOP_PARAM],
-
- inputs[SIGNAL_INPUT],
- inputs[TRIGGER_INPUT],
- &inputs[ATTACK_INPUT],
- &inputs[ON_INPUT],
- &inputs[DECAY_INPUT],
- &inputs[OFF_INPUT],
- &inputs[ENV_INPUT],
- &inputs[SIGNALCV_INPUT],
-
- outputs[SIGNAL_OUTPUT],
- outputs[ENV_OUTPUT],
- outputs[INV_OUTPUT],
- outputs[TRIGGER_OUTPUT],
- &outputs[ATTACK_OUTPUT],
- &outputs[ON_OUTPUT],
- &outputs[DECAY_OUTPUT],
- &outputs[OFF_OUTPUT],
-
- lights[ATTACK_LIGHT],
- lights[ON_LIGHT],
- lights[DECAY_LIGHT],
- lights[OFF_LIGHT],
-
- _triggerOnLoad,
- _shouldTriggerOnLoad
- )
- {
+ ShaperPlus() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.14142f, "Attack", " s");
configParam<EnvelopeSegmentParamQuantity>(ON_PARAM, 0.0f, 1.0f, 0.31623f, "On", " s");
configParam<EnvelopeSegmentParamQuantity>(DECAY_PARAM, 0.0f, 1.0f, 0.31623f, "Decay", " s");
@@ -106,19 +65,59 @@ struct ShaperPlus : TriggerOnLoadModule {
configParam(SPEED_PARAM, 0.0f, 1.0f, 1.0f, "Speed");
configParam(LOOP_PARAM, 0.0f, 1.0f, 1.0f, "Loop");
+ _core = new ShaperCore(
+ params[ATTACK_PARAM],
+ params[ON_PARAM],
+ params[DECAY_PARAM],
+ params[OFF_PARAM],
+ params[ENV_PARAM],
+ params[SIGNAL_PARAM],
+ params[TRIGGER_PARAM],
+ params[SPEED_PARAM],
+ params[LOOP_PARAM],
+
+ inputs[SIGNAL_INPUT],
+ inputs[TRIGGER_INPUT],
+ &inputs[ATTACK_INPUT],
+ &inputs[ON_INPUT],
+ &inputs[DECAY_INPUT],
+ &inputs[OFF_INPUT],
+ &inputs[ENV_INPUT],
+ &inputs[SIGNALCV_INPUT],
+
+ outputs[SIGNAL_OUTPUT],
+ outputs[ENV_OUTPUT],
+ outputs[INV_OUTPUT],
+ outputs[TRIGGER_OUTPUT],
+ &outputs[ATTACK_OUTPUT],
+ &outputs[ON_OUTPUT],
+ &outputs[DECAY_OUTPUT],
+ &outputs[OFF_OUTPUT],
+
+ lights[ATTACK_LIGHT],
+ lights[ON_LIGHT],
+ lights[DECAY_LIGHT],
+ lights[OFF_LIGHT],
+
+ _triggerOnLoad,
+ _shouldTriggerOnLoad
+ );
onReset();
}
+ virtual ~ShaperPlus() {
+ delete _core;
+ }
void onReset() override {
- _core.reset();
+ _core->reset();
}
void process(const ProcessArgs& args) override {
- _core.step();
+ _core->step();
}
bool shouldTriggerOnNextLoad() override {
- return _core._stage != _core.STOPPED_STAGE;
+ return _core->_stage != _core->STOPPED_STAGE;
}
};
diff --git a/src/Sums.cpp b/src/Sums.cpp
@@ -35,7 +35,8 @@ void Sums::process(const ProcessArgs& args) {
struct SumsWidget : DisableOutputLimitModuleWidget {
static constexpr int hp = 3;
- SumsWidget(Sums* module) : DisableOutputLimitModuleWidget(module) {
+ SumsWidget(Sums* module) {
+ setModule(module);
box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
{
diff --git a/src/Sums.hpp b/src/Sums.hpp
@@ -32,7 +32,8 @@ struct Sums : DisableOutputLimitModule {
NUM_LIGHTS
};
- Sums() : DisableOutputLimitModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ Sums() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
}
void process(const ProcessArgs& args) override;
diff --git a/src/VCM.cpp b/src/VCM.cpp
@@ -45,7 +45,8 @@ float VCM::channelStep(Input& input, Param& knob, Input& cv, Amplifier& amplifie
struct VCMWidget : DisableOutputLimitModuleWidget {
static constexpr int hp = 10;
- VCMWidget(VCM* module) : DisableOutputLimitModuleWidget(module) {
+ VCMWidget(VCM* module) {
+ setModule(module);
box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
{
diff --git a/src/VCM.hpp b/src/VCM.hpp
@@ -53,7 +53,8 @@ struct VCM : DisableOutputLimitModule {
bool isLinear() override;
};
- VCM() : DisableOutputLimitModule(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
+ VCM() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam<LevelParamQuantity>(LEVEL1_PARAM, 0.0f, 1.0f, 0.8f, "Level 1");
configParam<LevelParamQuantity>(LEVEL2_PARAM, 0.0f, 1.0f, 0.8f, "Level 2");
configParam<LevelParamQuantity>(LEVEL3_PARAM, 0.0f, 1.0f, 0.8f, "Level 3");
diff --git a/src/bogaudio.hpp b/src/bogaudio.hpp
@@ -11,7 +11,6 @@
#include "param_quantities.hpp"
#include "rack_overrides.hpp"
-#include "trigger_on_load.hpp"
#include "widgets.hpp"
#include "utils.hpp"
diff --git a/src/disable_output_limit.hpp b/src/disable_output_limit.hpp
@@ -7,10 +7,6 @@ namespace bogaudio {
struct DisableOutputLimitModule : Module {
bool _disableOutputLimit = false;
- DisableOutputLimitModule(int numParams, int numInputs, int numOutputs, int numLights = 0) {
- config(numParams, numInputs, numOutputs, numLights);
- }
-
json_t* dataToJson() override;
void dataFromJson(json_t* root) override;
};
@@ -34,10 +30,6 @@ struct DisableOutputLimitMenuItem : MenuItem {
};
struct DisableOutputLimitModuleWidget : ModuleWidget {
- DisableOutputLimitModuleWidget(Module* module) {
- setModule(module);
- }
-
void appendContextMenu(Menu* menu) override {
DisableOutputLimitModule* dolm = dynamic_cast<DisableOutputLimitModule*>(module);
assert(dolm);
diff --git a/src/select_on_clock.cpp b/src/select_on_clock.cpp
@@ -0,0 +1,17 @@
+
+#include "select_on_clock.hpp"
+
+#define SELECT_ON_CLOCK "select_on_clock"
+
+json_t* SelectOnClockModule::dataToJson() {
+ json_t* root = json_object();
+ json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
+ return root;
+}
+
+void SelectOnClockModule::dataFromJson(json_t* root) {
+ json_t* s = json_object_get(root, SELECT_ON_CLOCK);
+ if (s) {
+ _selectOnClock = json_is_true(s);
+ }
+}
diff --git a/src/select_on_clock.hpp b/src/select_on_clock.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "bogaudio.hpp"
+
+using namespace rack;
+
+namespace bogaudio {
+
+struct SelectOnClockModule : Module {
+ bool _selectOnClock = false;
+
+ json_t* dataToJson() override;
+ void dataFromJson(json_t* root) override;
+};
+
+struct SelectOnClockMenuItem : MenuItem {
+ SelectOnClockModule* _module;
+
+ SelectOnClockMenuItem(SelectOnClockModule* module, const char* label)
+ : _module(module)
+ {
+ this->text = label;
+ }
+
+ void onAction(const event::Action& e) override {
+ _module->_selectOnClock = !_module->_selectOnClock;
+ }
+
+ void step() override {
+ rightText = _module->_selectOnClock ? "✔" : "";
+ }
+};
+
+struct SelectOnClockModuleWidget : ModuleWidget {
+ void appendContextMenu(Menu* menu) override {
+ SelectOnClockModule* m = dynamic_cast<SelectOnClockModule*>(module);
+ assert(m);
+ menu->addChild(new MenuLabel());
+ menu->addChild(new SelectOnClockMenuItem(m, "Select on clock"));
+ }
+};
+
+} // namespace bogaudio
diff --git a/src/trigger_on_load.hpp b/src/trigger_on_load.hpp
@@ -10,10 +10,6 @@ struct TriggerOnLoadModule : Module {
bool _triggerOnLoad = true;
bool _shouldTriggerOnLoad = true;
- TriggerOnLoadModule(int numParams, int numInputs, int numOutputs, int numLights) {
- config(numParams, numInputs, numOutputs, numLights);
- }
-
json_t* dataToJson() override;
void dataFromJson(json_t* root) override;
@@ -38,4 +34,13 @@ struct TriggerOnLoadMenuItem : MenuItem {
}
};
+struct TriggerOnLoadModuleWidget : ModuleWidget {
+ void appendContextMenu(Menu* menu) override {
+ TriggerOnLoadModule* m = dynamic_cast<TriggerOnLoadModule*>(module);
+ assert(m);
+ menu->addChild(new MenuLabel());
+ menu->addChild(new TriggerOnLoadMenuItem(m, "Resume loop on load"));
+ }
+};
+
} // namespace bogaudio