commit c8da607e9cf326c20a7c2639535f48c4361a5a30
parent 8ebc14df5044e2320340912fc9a86115bb49f7cf
Author: Matt Demanett <matt@demanett.net>
Date: Wed, 24 Jun 2020 22:03:54 -0400
Reorganize code for modules with expanders.
Diffstat:
M | src/Mix4.cpp | | | 210 | ------------------------------------------------------------------------------- |
M | src/Mix4.hpp | | | 125 | +------------------------------------------------------------------------------ |
A | src/Mix4_shared.hpp | | | 14 | ++++++++++++++ |
A | src/Mix4x.cpp | | | 211 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/Mix4x.hpp | | | 124 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/Mix8.cpp | | | 282 | ------------------------------------------------------------------------------- |
M | src/Mix8.hpp | | | 193 | +------------------------------------------------------------------------------ |
A | src/Mix8_shared.hpp | | | 14 | ++++++++++++++ |
A | src/Mix8x.cpp | | | 283 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/Mix8x.hpp | | | 191 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/Pgmr.cpp | | | 212 | ------------------------------------------------------------------------------- |
M | src/Pgmr.hpp | | | 184 | +------------------------------------------------------------------------------ |
A | src/PgmrX.cpp | | | 137 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/PgmrX.hpp | | | 99 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/Pgmr_shared.cpp | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/Pgmr_shared.hpp | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/bogaudio.cpp | | | 3 | +++ |
17 files changed, 1255 insertions(+), 1203 deletions(-)
diff --git a/src/Mix4.cpp b/src/Mix4.cpp
@@ -265,213 +265,3 @@ struct Mix4Widget : ModuleWidget {
};
Model* modelMix4 = bogaudio::createModel<Mix4, Mix4Widget>("Bogaudio-Mix4", "MIX4", "4-channel mixer and panner", "Mixer", "Panning");
-
-
-void Mix4x::sampleRateChange() {
- float sr = APP->engine->getSampleRate();
- for (int i = 0; i < 4; ++i) {
- _channels[i]->setSampleRate(sr);
- }
- _returnASL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
- _returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
-}
-
-void Mix4x::modulate() {
- for (int i = 0; i < 4; ++i) {
- _channels[i]->modulate();
- }
-}
-
-void Mix4x::processAll(const ProcessArgs& args) {
- if (!baseConnected()) {
- outputs[SEND_A_OUTPUT].setVoltage(0.0f);
- outputs[SEND_B_OUTPUT].setVoltage(0.0f);
- return;
- }
-
- Mix4ExpanderMessage* from = fromBase();
- Mix4ExpanderMessage* to = toBase();
- float sendA = 0.0f;
- float sendB = 0.0f;
- bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
- bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
- for (int i = 0; i < 4; ++i) {
- if (from->active[i]) {
- _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
- to->postEQ[i] = _channels[i]->postEQ;
- sendA += _channels[i]->sendA;
- sendB += _channels[i]->sendB;
- }
- else {
- to->postEQ[i] = from->preFader[i];
- }
- }
- outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
- outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
-
- bool lAActive = inputs[L_A_INPUT].isConnected();
- bool rAActive = inputs[R_A_INPUT].isConnected();
- if (lAActive || rAActive) {
- float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
- if (inputs[LEVEL_A_INPUT].isConnected()) {
- levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- levelA = 1.0f - levelA;
- levelA *= Amplifier::minDecibels;
- _returnAAmp.setLevel(_returnASL.next(levelA));
- if (lAActive) {
- to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
- }
- else {
- to->returnA[0] = 0.0f;
- }
- if (rAActive) {
- to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
- }
- else {
- to->returnA[1] = to->returnA[0];
- }
- }
-
- bool lBActive = inputs[L_B_INPUT].isConnected();
- bool rBActive = inputs[R_B_INPUT].isConnected();
- if (lBActive || rBActive) {
- float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
- levelB = 1.0f - levelB;
- levelB *= Amplifier::minDecibels;
- _returnBAmp.setLevel(_returnBSL.next(levelB));
- if (lBActive) {
- to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
- }
- else {
- to->returnB[0] = 0.0f;
- }
- if (rBActive) {
- to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
- }
- else {
- to->returnB[1] = to->returnB[0];
- }
- }
-}
-
-struct Mix4xWidget : ModuleWidget {
- static constexpr int hp = 15;
-
- Mix4xWidget(Mix4x* module) {
- setModule(module);
- box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
-
- {
- SvgPanel *panel = new SvgPanel();
- panel->box.size = box.size;
- panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Mix4x.svg")));
- addChild(panel);
- }
-
- addChild(createWidget<ScrewSilver>(Vec(15, 0)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 0)));
- addChild(createWidget<ScrewSilver>(Vec(15, 365)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365)));
-
- // generated by svg_widgets.rb
- auto low1ParamPosition = Vec(18.5, 43.0);
- auto mid1ParamPosition = Vec(18.5, 89.0);
- auto high1ParamPosition = Vec(18.5, 135.0);
- auto a1ParamPosition = Vec(18.5, 180.0);
- auto preA1ParamPosition = Vec(30.0, 208.0);
- auto b1ParamPosition = Vec(18.5, 236.0);
- auto preB1ParamPosition = Vec(30.0, 264.0);
- auto low2ParamPosition = Vec(61.5, 43.0);
- auto mid2ParamPosition = Vec(61.5, 89.0);
- auto high2ParamPosition = Vec(61.5, 135.0);
- auto a2ParamPosition = Vec(61.5, 180.0);
- auto preA2ParamPosition = Vec(73.0, 208.0);
- auto b2ParamPosition = Vec(61.5, 236.0);
- auto preB2ParamPosition = Vec(73.0, 264.0);
- auto low3ParamPosition = Vec(104.5, 43.0);
- auto mid3ParamPosition = Vec(104.5, 89.0);
- auto high3ParamPosition = Vec(104.5, 135.0);
- auto a3ParamPosition = Vec(104.5, 180.0);
- auto preA3ParamPosition = Vec(116.0, 208.0);
- auto b3ParamPosition = Vec(104.5, 236.0);
- auto preB3ParamPosition = Vec(116.0, 264.0);
- auto low4ParamPosition = Vec(147.5, 43.0);
- auto mid4ParamPosition = Vec(147.5, 89.0);
- auto high4ParamPosition = Vec(147.5, 135.0);
- auto a4ParamPosition = Vec(147.5, 180.0);
- auto preA4ParamPosition = Vec(159.0, 208.0);
- auto b4ParamPosition = Vec(147.5, 236.0);
- auto preB4ParamPosition = Vec(159.0, 264.0);
- auto levelAParamPosition = Vec(190.5, 138.0);
- auto levelBParamPosition = Vec(190.5, 328.0);
-
- auto a1InputPosition = Vec(14.5, 290.0);
- auto b1InputPosition = Vec(14.5, 325.0);
- auto a2InputPosition = Vec(57.5, 290.0);
- auto b2InputPosition = Vec(57.5, 325.0);
- auto a3InputPosition = Vec(100.5, 290.0);
- auto b3InputPosition = Vec(100.5, 325.0);
- auto a4InputPosition = Vec(143.5, 290.0);
- auto b4InputPosition = Vec(143.5, 325.0);
- auto lAInputPosition = Vec(186.5, 62.0);
- auto rAInputPosition = Vec(186.5, 97.0);
- auto levelAInputPosition = Vec(186.5, 170.0);
- auto lBInputPosition = Vec(186.5, 252.0);
- auto rBInputPosition = Vec(186.5, 287.0);
-
- auto sendAOutputPosition = Vec(186.5, 24.0);
- auto sendBOutputPosition = Vec(186.5, 214.0);
- // end generated by svg_widgets.rb
-
- addParam(createParam<Knob16>(low1ParamPosition, module, Mix4x::LOW1_PARAM));
- addParam(createParam<Knob16>(mid1ParamPosition, module, Mix4x::MID1_PARAM));
- addParam(createParam<Knob16>(high1ParamPosition, module, Mix4x::HIGH1_PARAM));
- addParam(createParam<Knob16>(a1ParamPosition, module, Mix4x::A1_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA1ParamPosition, module, Mix4x::PRE_A1_PARAM));
- addParam(createParam<Knob16>(b1ParamPosition, module, Mix4x::B1_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB1ParamPosition, module, Mix4x::PRE_B1_PARAM));
- addParam(createParam<Knob16>(low2ParamPosition, module, Mix4x::LOW2_PARAM));
- addParam(createParam<Knob16>(mid2ParamPosition, module, Mix4x::MID2_PARAM));
- addParam(createParam<Knob16>(high2ParamPosition, module, Mix4x::HIGH2_PARAM));
- addParam(createParam<Knob16>(a2ParamPosition, module, Mix4x::A2_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA2ParamPosition, module, Mix4x::PRE_A2_PARAM));
- addParam(createParam<Knob16>(b2ParamPosition, module, Mix4x::B2_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB2ParamPosition, module, Mix4x::PRE_B2_PARAM));
- addParam(createParam<Knob16>(low3ParamPosition, module, Mix4x::LOW3_PARAM));
- addParam(createParam<Knob16>(mid3ParamPosition, module, Mix4x::MID3_PARAM));
- addParam(createParam<Knob16>(high3ParamPosition, module, Mix4x::HIGH3_PARAM));
- addParam(createParam<Knob16>(a3ParamPosition, module, Mix4x::A3_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA3ParamPosition, module, Mix4x::PRE_A3_PARAM));
- addParam(createParam<Knob16>(b3ParamPosition, module, Mix4x::B3_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB3ParamPosition, module, Mix4x::PRE_B3_PARAM));
- addParam(createParam<Knob16>(low4ParamPosition, module, Mix4x::LOW4_PARAM));
- addParam(createParam<Knob16>(mid4ParamPosition, module, Mix4x::MID4_PARAM));
- addParam(createParam<Knob16>(high4ParamPosition, module, Mix4x::HIGH4_PARAM));
- addParam(createParam<Knob16>(a4ParamPosition, module, Mix4x::A4_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA4ParamPosition, module, Mix4x::PRE_A4_PARAM));
- addParam(createParam<Knob16>(b4ParamPosition, module, Mix4x::B4_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB4ParamPosition, module, Mix4x::PRE_B4_PARAM));
- addParam(createParam<Knob16>(levelAParamPosition, module, Mix4x::LEVEL_A_PARAM));
- addParam(createParam<Knob16>(levelBParamPosition, module, Mix4x::LEVEL_B_PARAM));
-
- addInput(createInput<Port24>(a1InputPosition, module, Mix4x::A1_INPUT));
- addInput(createInput<Port24>(b1InputPosition, module, Mix4x::B1_INPUT));
- addInput(createInput<Port24>(a2InputPosition, module, Mix4x::A2_INPUT));
- addInput(createInput<Port24>(b2InputPosition, module, Mix4x::B2_INPUT));
- addInput(createInput<Port24>(a3InputPosition, module, Mix4x::A3_INPUT));
- addInput(createInput<Port24>(b3InputPosition, module, Mix4x::B3_INPUT));
- addInput(createInput<Port24>(a4InputPosition, module, Mix4x::A4_INPUT));
- addInput(createInput<Port24>(b4InputPosition, module, Mix4x::B4_INPUT));
- addInput(createInput<Port24>(lAInputPosition, module, Mix4x::L_A_INPUT));
- addInput(createInput<Port24>(rAInputPosition, module, Mix4x::R_A_INPUT));
- addInput(createInput<Port24>(levelAInputPosition, module, Mix4x::LEVEL_A_INPUT));
- addInput(createInput<Port24>(lBInputPosition, module, Mix4x::L_B_INPUT));
- addInput(createInput<Port24>(rBInputPosition, module, Mix4x::R_B_INPUT));
-
- addOutput(createOutput<Port24>(sendAOutputPosition, module, Mix4x::SEND_A_OUTPUT));
- addOutput(createOutput<Port24>(sendBOutputPosition, module, Mix4x::SEND_B_OUTPUT));
- }
-};
-
-Model* modelMix4x = createModel<Mix4x, Mix4xWidget>("Bogaudio-Mix4x", "MIX4X", "Expander for MIX4, adds EQs and sends", "Mixer", "Expander");
diff --git a/src/Mix4.hpp b/src/Mix4.hpp
@@ -1,20 +1,11 @@
#pragma once
-#include "bogaudio.hpp"
-#include "mixer_expander.hpp"
-#include "dsp/signal.hpp"
+#include "Mix4_shared.hpp"
using namespace bogaudio::dsp;
-extern Model* modelMix4;
-extern Model* modelMix4x;
-
namespace bogaudio {
-struct Mix4x;
-
-typedef MixerExpanderMessage<4> Mix4ExpanderMessage;
-
struct Mix4 : ExpandableModule<Mix4ExpanderMessage, BGModule> {
enum ParamsIds {
LEVEL1_PARAM,
@@ -109,118 +100,4 @@ struct Mix4 : ExpandableModule<Mix4ExpanderMessage, BGModule> {
void processAll(const ProcessArgs& args) override;
};
-struct Mix4x : ExpanderModule<Mix4ExpanderMessage, BGModule> {
- enum ParamsIds {
- LOW1_PARAM,
- MID1_PARAM,
- HIGH1_PARAM,
- A1_PARAM,
- PRE_A1_PARAM,
- B1_PARAM,
- PRE_B1_PARAM,
- LOW2_PARAM,
- MID2_PARAM,
- HIGH2_PARAM,
- A2_PARAM,
- PRE_A2_PARAM,
- B2_PARAM,
- PRE_B2_PARAM,
- LOW3_PARAM,
- MID3_PARAM,
- HIGH3_PARAM,
- A3_PARAM,
- PRE_A3_PARAM,
- B3_PARAM,
- PRE_B3_PARAM,
- LOW4_PARAM,
- MID4_PARAM,
- HIGH4_PARAM,
- A4_PARAM,
- PRE_A4_PARAM,
- B4_PARAM,
- PRE_B4_PARAM,
- LEVEL_A_PARAM,
- LEVEL_B_PARAM,
- NUM_PARAMS
- };
-
- enum InputsIds {
- A1_INPUT,
- B1_INPUT,
- A2_INPUT,
- B2_INPUT,
- A3_INPUT,
- B3_INPUT,
- A4_INPUT,
- B4_INPUT,
- L_A_INPUT,
- R_A_INPUT,
- LEVEL_A_INPUT,
- L_B_INPUT,
- R_B_INPUT,
- NUM_INPUTS
- };
-
- enum OutputsIds {
- SEND_A_OUTPUT,
- SEND_B_OUTPUT,
- NUM_OUTPUTS
- };
-
- MixerExpanderChannel* _channels[4] {};
- Saturator _saturatorA, _saturatorB;
- Amplifier _returnAAmp, _returnBAmp;
- bogaudio::dsp::SlewLimiter _returnASL, _returnBSL;
-
- Mix4x() {
- config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
- configParam<EQParamQuantity>(LOW1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 low", " dB");
- configParam<EQParamQuantity>(MID1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 mid", " dB");
- configParam<EQParamQuantity>(HIGH1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 high", " dB");
- configParam<AmplifierParamQuantity>(A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send");
- configParam(PRE_A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send pre/post");
- configParam<AmplifierParamQuantity>(B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send");
- configParam(PRE_B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send pre/post");
- configParam<EQParamQuantity>(LOW2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 low", " dB");
- configParam<EQParamQuantity>(MID2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 mid", " dB");
- configParam<EQParamQuantity>(HIGH2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 high", " dB");
- configParam<AmplifierParamQuantity>(A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send");
- configParam(PRE_A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send pre/post");
- configParam<AmplifierParamQuantity>(B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send");
- configParam(PRE_B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send pre/post");
- configParam<EQParamQuantity>(LOW3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 low", " dB");
- configParam<EQParamQuantity>(MID3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 mid", " dB");
- configParam<EQParamQuantity>(HIGH3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 high", " dB");
- configParam<AmplifierParamQuantity>(A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send");
- configParam(PRE_A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send pre/post");
- configParam<AmplifierParamQuantity>(B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send");
- configParam(PRE_B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send pre/post");
- configParam<EQParamQuantity>(LOW4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 low", " dB");
- configParam<EQParamQuantity>(MID4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 mid", " dB");
- configParam<EQParamQuantity>(HIGH4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 high", " dB");
- configParam<AmplifierParamQuantity>(A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send");
- configParam(PRE_A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send pre/post");
- configParam<AmplifierParamQuantity>(B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send");
- configParam(PRE_B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send pre/post");
- configParam<AmplifierParamQuantity>(LEVEL_A_PARAM, 0.0f, 1.0f, 0.8f, "A return level");
- configParam<AmplifierParamQuantity>(LEVEL_B_PARAM, 0.0f, 1.0f, 0.8f, "B return level");
-
- _channels[0] = new MixerExpanderChannel(params[LOW1_PARAM], params[MID1_PARAM], params[HIGH1_PARAM], params[A1_PARAM], params[B1_PARAM], params[PRE_A1_PARAM], params[PRE_B1_PARAM], inputs[A1_INPUT], inputs[B1_INPUT]);
- _channels[1] = new MixerExpanderChannel(params[LOW2_PARAM], params[MID2_PARAM], params[HIGH2_PARAM], params[A2_PARAM], params[B2_PARAM], params[PRE_A2_PARAM], params[PRE_B2_PARAM], inputs[A2_INPUT], inputs[B2_INPUT]);
- _channels[2] = new MixerExpanderChannel(params[LOW3_PARAM], params[MID3_PARAM], params[HIGH3_PARAM], params[A3_PARAM], params[B3_PARAM], params[PRE_A3_PARAM], params[PRE_B3_PARAM], inputs[A3_INPUT], inputs[B3_INPUT]);
- _channels[3] = new MixerExpanderChannel(params[LOW4_PARAM], params[MID4_PARAM], params[HIGH4_PARAM], params[A4_PARAM], params[B4_PARAM], params[PRE_A4_PARAM], params[PRE_B4_PARAM], inputs[A4_INPUT], inputs[B4_INPUT]);
-
- setBaseModel(modelMix4);
- }
- virtual ~Mix4x() {
- for (int i = 0; i < 4; ++i) {
- delete _channels[i];
- }
- }
-
- void sampleRateChange() override;
- void modulate() override;
- void processAll(const ProcessArgs& args) override;
-};
-
} // namespace bogaudio
diff --git a/src/Mix4_shared.hpp b/src/Mix4_shared.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "mixer_expander.hpp"
+#include "dsp/signal.hpp"
+
+extern Model* modelMix4;
+extern Model* modelMix4x;
+
+namespace bogaudio {
+
+typedef MixerExpanderMessage<4> Mix4ExpanderMessage;
+
+} // namespace bogaudio
diff --git a/src/Mix4x.cpp b/src/Mix4x.cpp
@@ -0,0 +1,211 @@
+
+#include "Mix4x.hpp"
+
+void Mix4x::sampleRateChange() {
+ float sr = APP->engine->getSampleRate();
+ for (int i = 0; i < 4; ++i) {
+ _channels[i]->setSampleRate(sr);
+ }
+ _returnASL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+ _returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+}
+
+void Mix4x::modulate() {
+ for (int i = 0; i < 4; ++i) {
+ _channels[i]->modulate();
+ }
+}
+
+void Mix4x::processAll(const ProcessArgs& args) {
+ if (!baseConnected()) {
+ outputs[SEND_A_OUTPUT].setVoltage(0.0f);
+ outputs[SEND_B_OUTPUT].setVoltage(0.0f);
+ return;
+ }
+
+ Mix4ExpanderMessage* from = fromBase();
+ Mix4ExpanderMessage* to = toBase();
+ float sendA = 0.0f;
+ float sendB = 0.0f;
+ bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
+ bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
+ for (int i = 0; i < 4; ++i) {
+ if (from->active[i]) {
+ _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
+ to->postEQ[i] = _channels[i]->postEQ;
+ sendA += _channels[i]->sendA;
+ sendB += _channels[i]->sendB;
+ }
+ else {
+ to->postEQ[i] = from->preFader[i];
+ }
+ }
+ outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
+ outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
+
+ bool lAActive = inputs[L_A_INPUT].isConnected();
+ bool rAActive = inputs[R_A_INPUT].isConnected();
+ if (lAActive || rAActive) {
+ float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[LEVEL_A_INPUT].isConnected()) {
+ levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ levelA = 1.0f - levelA;
+ levelA *= Amplifier::minDecibels;
+ _returnAAmp.setLevel(_returnASL.next(levelA));
+ if (lAActive) {
+ to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[0] = 0.0f;
+ }
+ if (rAActive) {
+ to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[1] = to->returnA[0];
+ }
+ }
+
+ bool lBActive = inputs[L_B_INPUT].isConnected();
+ bool rBActive = inputs[R_B_INPUT].isConnected();
+ if (lBActive || rBActive) {
+ float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
+ levelB = 1.0f - levelB;
+ levelB *= Amplifier::minDecibels;
+ _returnBAmp.setLevel(_returnBSL.next(levelB));
+ if (lBActive) {
+ to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[0] = 0.0f;
+ }
+ if (rBActive) {
+ to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[1] = to->returnB[0];
+ }
+ }
+}
+
+struct Mix4xWidget : ModuleWidget {
+ static constexpr int hp = 15;
+
+ Mix4xWidget(Mix4x* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+
+ {
+ SvgPanel *panel = new SvgPanel();
+ panel->box.size = box.size;
+ panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Mix4x.svg")));
+ addChild(panel);
+ }
+
+ addChild(createWidget<ScrewSilver>(Vec(15, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(15, 365)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365)));
+
+ // generated by svg_widgets.rb
+ auto low1ParamPosition = Vec(18.5, 43.0);
+ auto mid1ParamPosition = Vec(18.5, 89.0);
+ auto high1ParamPosition = Vec(18.5, 135.0);
+ auto a1ParamPosition = Vec(18.5, 180.0);
+ auto preA1ParamPosition = Vec(30.0, 208.0);
+ auto b1ParamPosition = Vec(18.5, 236.0);
+ auto preB1ParamPosition = Vec(30.0, 264.0);
+ auto low2ParamPosition = Vec(61.5, 43.0);
+ auto mid2ParamPosition = Vec(61.5, 89.0);
+ auto high2ParamPosition = Vec(61.5, 135.0);
+ auto a2ParamPosition = Vec(61.5, 180.0);
+ auto preA2ParamPosition = Vec(73.0, 208.0);
+ auto b2ParamPosition = Vec(61.5, 236.0);
+ auto preB2ParamPosition = Vec(73.0, 264.0);
+ auto low3ParamPosition = Vec(104.5, 43.0);
+ auto mid3ParamPosition = Vec(104.5, 89.0);
+ auto high3ParamPosition = Vec(104.5, 135.0);
+ auto a3ParamPosition = Vec(104.5, 180.0);
+ auto preA3ParamPosition = Vec(116.0, 208.0);
+ auto b3ParamPosition = Vec(104.5, 236.0);
+ auto preB3ParamPosition = Vec(116.0, 264.0);
+ auto low4ParamPosition = Vec(147.5, 43.0);
+ auto mid4ParamPosition = Vec(147.5, 89.0);
+ auto high4ParamPosition = Vec(147.5, 135.0);
+ auto a4ParamPosition = Vec(147.5, 180.0);
+ auto preA4ParamPosition = Vec(159.0, 208.0);
+ auto b4ParamPosition = Vec(147.5, 236.0);
+ auto preB4ParamPosition = Vec(159.0, 264.0);
+ auto levelAParamPosition = Vec(190.5, 138.0);
+ auto levelBParamPosition = Vec(190.5, 328.0);
+
+ auto a1InputPosition = Vec(14.5, 290.0);
+ auto b1InputPosition = Vec(14.5, 325.0);
+ auto a2InputPosition = Vec(57.5, 290.0);
+ auto b2InputPosition = Vec(57.5, 325.0);
+ auto a3InputPosition = Vec(100.5, 290.0);
+ auto b3InputPosition = Vec(100.5, 325.0);
+ auto a4InputPosition = Vec(143.5, 290.0);
+ auto b4InputPosition = Vec(143.5, 325.0);
+ auto lAInputPosition = Vec(186.5, 62.0);
+ auto rAInputPosition = Vec(186.5, 97.0);
+ auto levelAInputPosition = Vec(186.5, 170.0);
+ auto lBInputPosition = Vec(186.5, 252.0);
+ auto rBInputPosition = Vec(186.5, 287.0);
+
+ auto sendAOutputPosition = Vec(186.5, 24.0);
+ auto sendBOutputPosition = Vec(186.5, 214.0);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<Knob16>(low1ParamPosition, module, Mix4x::LOW1_PARAM));
+ addParam(createParam<Knob16>(mid1ParamPosition, module, Mix4x::MID1_PARAM));
+ addParam(createParam<Knob16>(high1ParamPosition, module, Mix4x::HIGH1_PARAM));
+ addParam(createParam<Knob16>(a1ParamPosition, module, Mix4x::A1_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA1ParamPosition, module, Mix4x::PRE_A1_PARAM));
+ addParam(createParam<Knob16>(b1ParamPosition, module, Mix4x::B1_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB1ParamPosition, module, Mix4x::PRE_B1_PARAM));
+ addParam(createParam<Knob16>(low2ParamPosition, module, Mix4x::LOW2_PARAM));
+ addParam(createParam<Knob16>(mid2ParamPosition, module, Mix4x::MID2_PARAM));
+ addParam(createParam<Knob16>(high2ParamPosition, module, Mix4x::HIGH2_PARAM));
+ addParam(createParam<Knob16>(a2ParamPosition, module, Mix4x::A2_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA2ParamPosition, module, Mix4x::PRE_A2_PARAM));
+ addParam(createParam<Knob16>(b2ParamPosition, module, Mix4x::B2_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB2ParamPosition, module, Mix4x::PRE_B2_PARAM));
+ addParam(createParam<Knob16>(low3ParamPosition, module, Mix4x::LOW3_PARAM));
+ addParam(createParam<Knob16>(mid3ParamPosition, module, Mix4x::MID3_PARAM));
+ addParam(createParam<Knob16>(high3ParamPosition, module, Mix4x::HIGH3_PARAM));
+ addParam(createParam<Knob16>(a3ParamPosition, module, Mix4x::A3_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA3ParamPosition, module, Mix4x::PRE_A3_PARAM));
+ addParam(createParam<Knob16>(b3ParamPosition, module, Mix4x::B3_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB3ParamPosition, module, Mix4x::PRE_B3_PARAM));
+ addParam(createParam<Knob16>(low4ParamPosition, module, Mix4x::LOW4_PARAM));
+ addParam(createParam<Knob16>(mid4ParamPosition, module, Mix4x::MID4_PARAM));
+ addParam(createParam<Knob16>(high4ParamPosition, module, Mix4x::HIGH4_PARAM));
+ addParam(createParam<Knob16>(a4ParamPosition, module, Mix4x::A4_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA4ParamPosition, module, Mix4x::PRE_A4_PARAM));
+ addParam(createParam<Knob16>(b4ParamPosition, module, Mix4x::B4_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB4ParamPosition, module, Mix4x::PRE_B4_PARAM));
+ addParam(createParam<Knob16>(levelAParamPosition, module, Mix4x::LEVEL_A_PARAM));
+ addParam(createParam<Knob16>(levelBParamPosition, module, Mix4x::LEVEL_B_PARAM));
+
+ addInput(createInput<Port24>(a1InputPosition, module, Mix4x::A1_INPUT));
+ addInput(createInput<Port24>(b1InputPosition, module, Mix4x::B1_INPUT));
+ addInput(createInput<Port24>(a2InputPosition, module, Mix4x::A2_INPUT));
+ addInput(createInput<Port24>(b2InputPosition, module, Mix4x::B2_INPUT));
+ addInput(createInput<Port24>(a3InputPosition, module, Mix4x::A3_INPUT));
+ addInput(createInput<Port24>(b3InputPosition, module, Mix4x::B3_INPUT));
+ addInput(createInput<Port24>(a4InputPosition, module, Mix4x::A4_INPUT));
+ addInput(createInput<Port24>(b4InputPosition, module, Mix4x::B4_INPUT));
+ addInput(createInput<Port24>(lAInputPosition, module, Mix4x::L_A_INPUT));
+ addInput(createInput<Port24>(rAInputPosition, module, Mix4x::R_A_INPUT));
+ addInput(createInput<Port24>(levelAInputPosition, module, Mix4x::LEVEL_A_INPUT));
+ addInput(createInput<Port24>(lBInputPosition, module, Mix4x::L_B_INPUT));
+ addInput(createInput<Port24>(rBInputPosition, module, Mix4x::R_B_INPUT));
+
+ addOutput(createOutput<Port24>(sendAOutputPosition, module, Mix4x::SEND_A_OUTPUT));
+ addOutput(createOutput<Port24>(sendBOutputPosition, module, Mix4x::SEND_B_OUTPUT));
+ }
+};
+
+Model* modelMix4x = createModel<Mix4x, Mix4xWidget>("Bogaudio-Mix4x", "MIX4X", "Expander for MIX4, adds EQs and sends", "Mixer", "Expander");
diff --git a/src/Mix4x.hpp b/src/Mix4x.hpp
@@ -0,0 +1,124 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "Mix4_shared.hpp"
+
+using namespace bogaudio::dsp;
+
+namespace bogaudio {
+
+struct Mix4x : ExpanderModule<Mix4ExpanderMessage, BGModule> {
+ enum ParamsIds {
+ LOW1_PARAM,
+ MID1_PARAM,
+ HIGH1_PARAM,
+ A1_PARAM,
+ PRE_A1_PARAM,
+ B1_PARAM,
+ PRE_B1_PARAM,
+ LOW2_PARAM,
+ MID2_PARAM,
+ HIGH2_PARAM,
+ A2_PARAM,
+ PRE_A2_PARAM,
+ B2_PARAM,
+ PRE_B2_PARAM,
+ LOW3_PARAM,
+ MID3_PARAM,
+ HIGH3_PARAM,
+ A3_PARAM,
+ PRE_A3_PARAM,
+ B3_PARAM,
+ PRE_B3_PARAM,
+ LOW4_PARAM,
+ MID4_PARAM,
+ HIGH4_PARAM,
+ A4_PARAM,
+ PRE_A4_PARAM,
+ B4_PARAM,
+ PRE_B4_PARAM,
+ LEVEL_A_PARAM,
+ LEVEL_B_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ A1_INPUT,
+ B1_INPUT,
+ A2_INPUT,
+ B2_INPUT,
+ A3_INPUT,
+ B3_INPUT,
+ A4_INPUT,
+ B4_INPUT,
+ L_A_INPUT,
+ R_A_INPUT,
+ LEVEL_A_INPUT,
+ L_B_INPUT,
+ R_B_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ SEND_A_OUTPUT,
+ SEND_B_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ MixerExpanderChannel* _channels[4] {};
+ Saturator _saturatorA, _saturatorB;
+ Amplifier _returnAAmp, _returnBAmp;
+ bogaudio::dsp::SlewLimiter _returnASL, _returnBSL;
+
+ Mix4x() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configParam<EQParamQuantity>(LOW1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 low", " dB");
+ configParam<EQParamQuantity>(MID1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 mid", " dB");
+ configParam<EQParamQuantity>(HIGH1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 high", " dB");
+ configParam<AmplifierParamQuantity>(A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send");
+ configParam(PRE_A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send pre/post");
+ configParam<AmplifierParamQuantity>(B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send");
+ configParam(PRE_B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send pre/post");
+ configParam<EQParamQuantity>(LOW2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 low", " dB");
+ configParam<EQParamQuantity>(MID2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 mid", " dB");
+ configParam<EQParamQuantity>(HIGH2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 high", " dB");
+ configParam<AmplifierParamQuantity>(A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send");
+ configParam(PRE_A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send pre/post");
+ configParam<AmplifierParamQuantity>(B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send");
+ configParam(PRE_B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send pre/post");
+ configParam<EQParamQuantity>(LOW3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 low", " dB");
+ configParam<EQParamQuantity>(MID3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 mid", " dB");
+ configParam<EQParamQuantity>(HIGH3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 high", " dB");
+ configParam<AmplifierParamQuantity>(A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send");
+ configParam(PRE_A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send pre/post");
+ configParam<AmplifierParamQuantity>(B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send");
+ configParam(PRE_B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send pre/post");
+ configParam<EQParamQuantity>(LOW4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 low", " dB");
+ configParam<EQParamQuantity>(MID4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 mid", " dB");
+ configParam<EQParamQuantity>(HIGH4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 high", " dB");
+ configParam<AmplifierParamQuantity>(A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send");
+ configParam(PRE_A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send pre/post");
+ configParam<AmplifierParamQuantity>(B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send");
+ configParam(PRE_B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send pre/post");
+ configParam<AmplifierParamQuantity>(LEVEL_A_PARAM, 0.0f, 1.0f, 0.8f, "A return level");
+ configParam<AmplifierParamQuantity>(LEVEL_B_PARAM, 0.0f, 1.0f, 0.8f, "B return level");
+
+ _channels[0] = new MixerExpanderChannel(params[LOW1_PARAM], params[MID1_PARAM], params[HIGH1_PARAM], params[A1_PARAM], params[B1_PARAM], params[PRE_A1_PARAM], params[PRE_B1_PARAM], inputs[A1_INPUT], inputs[B1_INPUT]);
+ _channels[1] = new MixerExpanderChannel(params[LOW2_PARAM], params[MID2_PARAM], params[HIGH2_PARAM], params[A2_PARAM], params[B2_PARAM], params[PRE_A2_PARAM], params[PRE_B2_PARAM], inputs[A2_INPUT], inputs[B2_INPUT]);
+ _channels[2] = new MixerExpanderChannel(params[LOW3_PARAM], params[MID3_PARAM], params[HIGH3_PARAM], params[A3_PARAM], params[B3_PARAM], params[PRE_A3_PARAM], params[PRE_B3_PARAM], inputs[A3_INPUT], inputs[B3_INPUT]);
+ _channels[3] = new MixerExpanderChannel(params[LOW4_PARAM], params[MID4_PARAM], params[HIGH4_PARAM], params[A4_PARAM], params[B4_PARAM], params[PRE_A4_PARAM], params[PRE_B4_PARAM], inputs[A4_INPUT], inputs[B4_INPUT]);
+
+ setBaseModel(modelMix4);
+ }
+ virtual ~Mix4x() {
+ for (int i = 0; i < 4; ++i) {
+ delete _channels[i];
+ }
+ }
+
+ void sampleRateChange() override;
+ void modulate() override;
+ void processAll(const ProcessArgs& args) override;
+};
+
+} // namespace bogaudio
diff --git a/src/Mix8.cpp b/src/Mix8.cpp
@@ -319,285 +319,3 @@ struct Mix8Widget : ModuleWidget {
};
Model* modelMix8 = bogaudio::createModel<Mix8, Mix8Widget>("Bogaudio-Mix8", "MIX8", "8-channel mixer and panner", "Mixer", "Panning");
-
-
-void Mix8x::sampleRateChange() {
- float sr = APP->engine->getSampleRate();
- for (int i = 0; i < 8; ++i) {
- _channels[i]->setSampleRate(sr);
- }
- _returnASL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
- _returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
-}
-
-void Mix8x::modulate() {
- for (int i = 0; i < 8; ++i) {
- _channels[i]->modulate();
- }
-}
-
-void Mix8x::processAll(const ProcessArgs& args) {
- if (!baseConnected()) {
- outputs[SEND_A_OUTPUT].setVoltage(0.0f);
- outputs[SEND_B_OUTPUT].setVoltage(0.0f);
- return;
- }
-
- Mix8ExpanderMessage* from = fromBase();
- Mix8ExpanderMessage* to = toBase();
- float sendA = 0.0f;
- float sendB = 0.0f;
- bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
- bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
- for (int i = 0; i < 8; ++i) {
- if (from->active[i]) {
- _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
- to->postEQ[i] = _channels[i]->postEQ;
- sendA += _channels[i]->sendA;
- sendB += _channels[i]->sendB;
- }
- else {
- to->postEQ[i] = from->preFader[i];
- }
- }
- outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
- outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
-
- bool lAActive = inputs[L_A_INPUT].isConnected();
- bool rAActive = inputs[R_A_INPUT].isConnected();
- if (lAActive || rAActive) {
- float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
- if (inputs[LEVEL_A_INPUT].isConnected()) {
- levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
- }
- levelA = 1.0f - levelA;
- levelA *= Amplifier::minDecibels;
- _returnAAmp.setLevel(_returnASL.next(levelA));
- if (lAActive) {
- to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
- }
- else {
- to->returnA[0] = 0.0f;
- }
- if (rAActive) {
- to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
- }
- else {
- to->returnA[1] = to->returnA[0];
- }
- }
-
- bool lBActive = inputs[L_B_INPUT].isConnected();
- bool rBActive = inputs[R_B_INPUT].isConnected();
- if (lBActive || rBActive) {
- float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
- levelB = 1.0f - levelB;
- levelB *= Amplifier::minDecibels;
- _returnBAmp.setLevel(_returnBSL.next(levelB));
- if (lBActive) {
- to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
- }
- else {
- to->returnB[0] = 0.0f;
- }
- if (rBActive) {
- to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
- }
- else {
- to->returnB[1] = to->returnB[0];
- }
- }
-}
-
-struct Mix8xWidget : ModuleWidget {
- static constexpr int hp = 27;
-
- Mix8xWidget(Mix8x* module) {
- setModule(module);
- box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
-
- {
- SvgPanel *panel = new SvgPanel();
- panel->box.size = box.size;
- panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Mix8x.svg")));
- addChild(panel);
- }
-
- addChild(createWidget<ScrewSilver>(Vec(15, 0)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 0)));
- addChild(createWidget<ScrewSilver>(Vec(15, 365)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365)));
-
- // generated by svg_widgets.rb
- auto low1ParamPosition = Vec(18.5, 43.0);
- auto mid1ParamPosition = Vec(18.5, 89.0);
- auto high1ParamPosition = Vec(18.5, 135.0);
- auto a1ParamPosition = Vec(18.5, 180.0);
- auto preA1ParamPosition = Vec(30.0, 208.0);
- auto b1ParamPosition = Vec(18.5, 236.0);
- auto preB1ParamPosition = Vec(30.0, 264.0);
- auto low2ParamPosition = Vec(62.5, 43.0);
- auto mid2ParamPosition = Vec(62.5, 89.0);
- auto high2ParamPosition = Vec(62.5, 135.0);
- auto a2ParamPosition = Vec(62.5, 180.0);
- auto preA2ParamPosition = Vec(74.0, 208.0);
- auto b2ParamPosition = Vec(62.5, 236.0);
- auto preB2ParamPosition = Vec(74.0, 264.0);
- auto low3ParamPosition = Vec(106.5, 43.0);
- auto mid3ParamPosition = Vec(106.5, 89.0);
- auto high3ParamPosition = Vec(106.5, 135.0);
- auto a3ParamPosition = Vec(106.5, 180.0);
- auto preA3ParamPosition = Vec(118.0, 208.0);
- auto b3ParamPosition = Vec(106.5, 236.0);
- auto preB3ParamPosition = Vec(118.0, 264.0);
- auto low4ParamPosition = Vec(150.5, 43.0);
- auto mid4ParamPosition = Vec(150.5, 89.0);
- auto high4ParamPosition = Vec(150.5, 135.0);
- auto a4ParamPosition = Vec(150.5, 180.0);
- auto preA4ParamPosition = Vec(162.0, 208.0);
- auto b4ParamPosition = Vec(150.5, 236.0);
- auto preB4ParamPosition = Vec(162.0, 264.0);
- auto low5ParamPosition = Vec(194.5, 43.0);
- auto mid5ParamPosition = Vec(194.5, 89.0);
- auto high5ParamPosition = Vec(194.5, 135.0);
- auto a5ParamPosition = Vec(194.5, 180.0);
- auto preA5ParamPosition = Vec(206.0, 208.0);
- auto b5ParamPosition = Vec(194.5, 236.0);
- auto preB5ParamPosition = Vec(206.0, 264.0);
- auto low6ParamPosition = Vec(238.5, 43.0);
- auto mid6ParamPosition = Vec(238.5, 89.0);
- auto high6ParamPosition = Vec(238.5, 135.0);
- auto a6ParamPosition = Vec(238.5, 180.0);
- auto preA6ParamPosition = Vec(250.0, 208.0);
- auto b6ParamPosition = Vec(238.5, 236.0);
- auto preB6ParamPosition = Vec(250.0, 264.0);
- auto low7ParamPosition = Vec(282.5, 43.0);
- auto mid7ParamPosition = Vec(282.5, 89.0);
- auto high7ParamPosition = Vec(282.5, 135.0);
- auto a7ParamPosition = Vec(282.5, 180.0);
- auto preA7ParamPosition = Vec(294.0, 208.0);
- auto b7ParamPosition = Vec(282.5, 236.0);
- auto preB7ParamPosition = Vec(294.0, 264.0);
- auto low8ParamPosition = Vec(326.5, 43.0);
- auto mid8ParamPosition = Vec(326.5, 89.0);
- auto high8ParamPosition = Vec(326.5, 135.0);
- auto a8ParamPosition = Vec(326.5, 180.0);
- auto preA8ParamPosition = Vec(338.0, 208.0);
- auto b8ParamPosition = Vec(326.5, 236.0);
- auto preB8ParamPosition = Vec(338.0, 264.0);
- auto levelAParamPosition = Vec(370.5, 138.0);
- auto levelBParamPosition = Vec(370.5, 328.0);
-
- auto a1InputPosition = Vec(14.5, 290.0);
- auto b1InputPosition = Vec(14.5, 325.0);
- auto a2InputPosition = Vec(58.5, 290.0);
- auto b2InputPosition = Vec(58.5, 325.0);
- auto a3InputPosition = Vec(102.5, 290.0);
- auto b3InputPosition = Vec(102.5, 325.0);
- auto a4InputPosition = Vec(146.5, 290.0);
- auto b4InputPosition = Vec(146.5, 325.0);
- auto a5InputPosition = Vec(190.5, 290.0);
- auto b5InputPosition = Vec(190.5, 325.0);
- auto a6InputPosition = Vec(234.5, 290.0);
- auto b6InputPosition = Vec(234.5, 325.0);
- auto a7InputPosition = Vec(278.5, 290.0);
- auto b7InputPosition = Vec(278.5, 325.0);
- auto a8InputPosition = Vec(322.5, 290.0);
- auto b8InputPosition = Vec(322.5, 325.0);
- auto lAInputPosition = Vec(366.5, 62.0);
- auto rAInputPosition = Vec(366.5, 97.0);
- auto levelAInputPosition = Vec(366.5, 170.0);
- auto lBInputPosition = Vec(366.5, 252.0);
- auto rBInputPosition = Vec(366.5, 287.0);
-
- auto sendAOutputPosition = Vec(366.5, 24.0);
- auto sendBOutputPosition = Vec(366.5, 214.0);
- // end generated by svg_widgets.rb
-
- addParam(createParam<Knob16>(low1ParamPosition, module, Mix8x::LOW1_PARAM));
- addParam(createParam<Knob16>(mid1ParamPosition, module, Mix8x::MID1_PARAM));
- addParam(createParam<Knob16>(high1ParamPosition, module, Mix8x::HIGH1_PARAM));
- addParam(createParam<Knob16>(a1ParamPosition, module, Mix8x::A1_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA1ParamPosition, module, Mix8x::PRE_A1_PARAM));
- addParam(createParam<Knob16>(b1ParamPosition, module, Mix8x::B1_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB1ParamPosition, module, Mix8x::PRE_B1_PARAM));
- addParam(createParam<Knob16>(low2ParamPosition, module, Mix8x::LOW2_PARAM));
- addParam(createParam<Knob16>(mid2ParamPosition, module, Mix8x::MID2_PARAM));
- addParam(createParam<Knob16>(high2ParamPosition, module, Mix8x::HIGH2_PARAM));
- addParam(createParam<Knob16>(a2ParamPosition, module, Mix8x::A2_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA2ParamPosition, module, Mix8x::PRE_A2_PARAM));
- addParam(createParam<Knob16>(b2ParamPosition, module, Mix8x::B2_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB2ParamPosition, module, Mix8x::PRE_B2_PARAM));
- addParam(createParam<Knob16>(low3ParamPosition, module, Mix8x::LOW3_PARAM));
- addParam(createParam<Knob16>(mid3ParamPosition, module, Mix8x::MID3_PARAM));
- addParam(createParam<Knob16>(high3ParamPosition, module, Mix8x::HIGH3_PARAM));
- addParam(createParam<Knob16>(a3ParamPosition, module, Mix8x::A3_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA3ParamPosition, module, Mix8x::PRE_A3_PARAM));
- addParam(createParam<Knob16>(b3ParamPosition, module, Mix8x::B3_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB3ParamPosition, module, Mix8x::PRE_B3_PARAM));
- addParam(createParam<Knob16>(low4ParamPosition, module, Mix8x::LOW4_PARAM));
- addParam(createParam<Knob16>(mid4ParamPosition, module, Mix8x::MID4_PARAM));
- addParam(createParam<Knob16>(high4ParamPosition, module, Mix8x::HIGH4_PARAM));
- addParam(createParam<Knob16>(a4ParamPosition, module, Mix8x::A4_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA4ParamPosition, module, Mix8x::PRE_A4_PARAM));
- addParam(createParam<Knob16>(b4ParamPosition, module, Mix8x::B4_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB4ParamPosition, module, Mix8x::PRE_B4_PARAM));
- addParam(createParam<Knob16>(low5ParamPosition, module, Mix8x::LOW5_PARAM));
- addParam(createParam<Knob16>(mid5ParamPosition, module, Mix8x::MID5_PARAM));
- addParam(createParam<Knob16>(high5ParamPosition, module, Mix8x::HIGH5_PARAM));
- addParam(createParam<Knob16>(a5ParamPosition, module, Mix8x::A5_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA5ParamPosition, module, Mix8x::PRE_A5_PARAM));
- addParam(createParam<Knob16>(b5ParamPosition, module, Mix8x::B5_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB5ParamPosition, module, Mix8x::PRE_B5_PARAM));
- addParam(createParam<Knob16>(low6ParamPosition, module, Mix8x::LOW6_PARAM));
- addParam(createParam<Knob16>(mid6ParamPosition, module, Mix8x::MID6_PARAM));
- addParam(createParam<Knob16>(high6ParamPosition, module, Mix8x::HIGH6_PARAM));
- addParam(createParam<Knob16>(a6ParamPosition, module, Mix8x::A6_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA6ParamPosition, module, Mix8x::PRE_A6_PARAM));
- addParam(createParam<Knob16>(b6ParamPosition, module, Mix8x::B6_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB6ParamPosition, module, Mix8x::PRE_B6_PARAM));
- addParam(createParam<Knob16>(low7ParamPosition, module, Mix8x::LOW7_PARAM));
- addParam(createParam<Knob16>(mid7ParamPosition, module, Mix8x::MID7_PARAM));
- addParam(createParam<Knob16>(high7ParamPosition, module, Mix8x::HIGH7_PARAM));
- addParam(createParam<Knob16>(a7ParamPosition, module, Mix8x::A7_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA7ParamPosition, module, Mix8x::PRE_A7_PARAM));
- addParam(createParam<Knob16>(b7ParamPosition, module, Mix8x::B7_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB7ParamPosition, module, Mix8x::PRE_B7_PARAM));
- addParam(createParam<Knob16>(low8ParamPosition, module, Mix8x::LOW8_PARAM));
- addParam(createParam<Knob16>(mid8ParamPosition, module, Mix8x::MID8_PARAM));
- addParam(createParam<Knob16>(high8ParamPosition, module, Mix8x::HIGH8_PARAM));
- addParam(createParam<Knob16>(a8ParamPosition, module, Mix8x::A8_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preA8ParamPosition, module, Mix8x::PRE_A8_PARAM));
- addParam(createParam<Knob16>(b8ParamPosition, module, Mix8x::B8_PARAM));
- addParam(createParam<IndicatorButtonGreen9>(preB8ParamPosition, module, Mix8x::PRE_B8_PARAM));
- addParam(createParam<Knob16>(levelAParamPosition, module, Mix8x::LEVEL_A_PARAM));
- addParam(createParam<Knob16>(levelBParamPosition, module, Mix8x::LEVEL_B_PARAM));
-
- addInput(createInput<Port24>(a1InputPosition, module, Mix8x::A1_INPUT));
- addInput(createInput<Port24>(b1InputPosition, module, Mix8x::B1_INPUT));
- addInput(createInput<Port24>(a2InputPosition, module, Mix8x::A2_INPUT));
- addInput(createInput<Port24>(b2InputPosition, module, Mix8x::B2_INPUT));
- addInput(createInput<Port24>(a3InputPosition, module, Mix8x::A3_INPUT));
- addInput(createInput<Port24>(b3InputPosition, module, Mix8x::B3_INPUT));
- addInput(createInput<Port24>(a4InputPosition, module, Mix8x::A4_INPUT));
- addInput(createInput<Port24>(b4InputPosition, module, Mix8x::B4_INPUT));
- addInput(createInput<Port24>(a5InputPosition, module, Mix8x::A5_INPUT));
- addInput(createInput<Port24>(b5InputPosition, module, Mix8x::B5_INPUT));
- addInput(createInput<Port24>(a6InputPosition, module, Mix8x::A6_INPUT));
- addInput(createInput<Port24>(b6InputPosition, module, Mix8x::B6_INPUT));
- addInput(createInput<Port24>(a7InputPosition, module, Mix8x::A7_INPUT));
- addInput(createInput<Port24>(b7InputPosition, module, Mix8x::B7_INPUT));
- addInput(createInput<Port24>(a8InputPosition, module, Mix8x::A8_INPUT));
- addInput(createInput<Port24>(b8InputPosition, module, Mix8x::B8_INPUT));
- addInput(createInput<Port24>(lAInputPosition, module, Mix8x::L_A_INPUT));
- addInput(createInput<Port24>(rAInputPosition, module, Mix8x::R_A_INPUT));
- addInput(createInput<Port24>(levelAInputPosition, module, Mix8x::LEVEL_A_INPUT));
- addInput(createInput<Port24>(lBInputPosition, module, Mix8x::L_B_INPUT));
- addInput(createInput<Port24>(rBInputPosition, module, Mix8x::R_B_INPUT));
-
- addOutput(createOutput<Port24>(sendAOutputPosition, module, Mix8x::SEND_A_OUTPUT));
- addOutput(createOutput<Port24>(sendBOutputPosition, module, Mix8x::SEND_B_OUTPUT));
- }
-};
-
-Model* modelMix8x = createModel<Mix8x, Mix8xWidget>("Bogaudio-Mix8x", "MIX8X", "Expander for MIX8, adds EQs and sends", "Mixer", "Expander");
diff --git a/src/Mix8.hpp b/src/Mix8.hpp
@@ -1,20 +1,11 @@
#pragma once
-#include "bogaudio.hpp"
-#include "mixer_expander.hpp"
-#include "dsp/signal.hpp"
+#include "Mix8_shared.hpp"
using namespace bogaudio::dsp;
-extern Model* modelMix8;
-extern Model* modelMix8x;
-
namespace bogaudio {
-struct Mix8x;
-
-typedef MixerExpanderMessage<8> Mix8ExpanderMessage;
-
struct Mix8 : ExpandableModule<Mix8ExpanderMessage, BGModule> {
enum ParamsIds {
LEVEL1_PARAM,
@@ -149,186 +140,4 @@ struct Mix8 : ExpandableModule<Mix8ExpanderMessage, BGModule> {
void processAll(const ProcessArgs& args) override;
};
-struct Mix8x : ExpanderModule<Mix8ExpanderMessage, BGModule> {
- enum ParamsIds {
- LOW1_PARAM,
- MID1_PARAM,
- HIGH1_PARAM,
- A1_PARAM,
- PRE_A1_PARAM,
- B1_PARAM,
- PRE_B1_PARAM,
- LOW2_PARAM,
- MID2_PARAM,
- HIGH2_PARAM,
- A2_PARAM,
- PRE_A2_PARAM,
- B2_PARAM,
- PRE_B2_PARAM,
- LOW3_PARAM,
- MID3_PARAM,
- HIGH3_PARAM,
- A3_PARAM,
- PRE_A3_PARAM,
- B3_PARAM,
- PRE_B3_PARAM,
- LOW4_PARAM,
- MID4_PARAM,
- HIGH4_PARAM,
- A4_PARAM,
- PRE_A4_PARAM,
- B4_PARAM,
- PRE_B4_PARAM,
- LOW5_PARAM,
- MID5_PARAM,
- HIGH5_PARAM,
- A5_PARAM,
- PRE_A5_PARAM,
- B5_PARAM,
- PRE_B5_PARAM,
- LOW6_PARAM,
- MID6_PARAM,
- HIGH6_PARAM,
- A6_PARAM,
- PRE_A6_PARAM,
- B6_PARAM,
- PRE_B6_PARAM,
- LOW7_PARAM,
- MID7_PARAM,
- HIGH7_PARAM,
- A7_PARAM,
- PRE_A7_PARAM,
- B7_PARAM,
- PRE_B7_PARAM,
- LOW8_PARAM,
- MID8_PARAM,
- HIGH8_PARAM,
- A8_PARAM,
- PRE_A8_PARAM,
- B8_PARAM,
- PRE_B8_PARAM,
- LEVEL_A_PARAM,
- LEVEL_B_PARAM,
- NUM_PARAMS
- };
-
- enum InputsIds {
- A1_INPUT,
- B1_INPUT,
- A2_INPUT,
- B2_INPUT,
- A3_INPUT,
- B3_INPUT,
- A4_INPUT,
- B4_INPUT,
- A5_INPUT,
- B5_INPUT,
- A6_INPUT,
- B6_INPUT,
- A7_INPUT,
- B7_INPUT,
- A8_INPUT,
- B8_INPUT,
- L_A_INPUT,
- R_A_INPUT,
- LEVEL_A_INPUT,
- L_B_INPUT,
- R_B_INPUT,
- NUM_INPUTS
- };
-
- enum OutputsIds {
- SEND_A_OUTPUT,
- SEND_B_OUTPUT,
- NUM_OUTPUTS
- };
-
- MixerExpanderChannel* _channels[8] {};
- Saturator _saturatorA, _saturatorB;
- Amplifier _returnAAmp, _returnBAmp;
- bogaudio::dsp::SlewLimiter _returnASL, _returnBSL;
-
- Mix8x() {
- config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
- configParam<EQParamQuantity>(LOW1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 low", " dB");
- configParam<EQParamQuantity>(MID1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 mid", " dB");
- configParam<EQParamQuantity>(HIGH1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 high", " dB");
- configParam<AmplifierParamQuantity>(A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send");
- configParam(PRE_A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send pre/post");
- configParam<AmplifierParamQuantity>(B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send");
- configParam(PRE_B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send pre/post");
- configParam<EQParamQuantity>(LOW2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 low", " dB");
- configParam<EQParamQuantity>(MID2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 mid", " dB");
- configParam<EQParamQuantity>(HIGH2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 high", " dB");
- configParam<AmplifierParamQuantity>(A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send");
- configParam(PRE_A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send pre/post");
- configParam<AmplifierParamQuantity>(B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send");
- configParam(PRE_B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send pre/post");
- configParam<EQParamQuantity>(LOW3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 low", " dB");
- configParam<EQParamQuantity>(MID3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 mid", " dB");
- configParam<EQParamQuantity>(HIGH3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 high", " dB");
- configParam<AmplifierParamQuantity>(A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send");
- configParam(PRE_A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send pre/post");
- configParam<AmplifierParamQuantity>(B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send");
- configParam(PRE_B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send pre/post");
- configParam<EQParamQuantity>(LOW4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 low", " dB");
- configParam<EQParamQuantity>(MID4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 mid", " dB");
- configParam<EQParamQuantity>(HIGH4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 high", " dB");
- configParam<AmplifierParamQuantity>(A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send");
- configParam(PRE_A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send pre/post");
- configParam<AmplifierParamQuantity>(B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send");
- configParam(PRE_B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send pre/post");
- configParam<EQParamQuantity>(LOW5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 low", " dB");
- configParam<EQParamQuantity>(MID5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 mid", " dB");
- configParam<EQParamQuantity>(HIGH5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 high", " dB");
- configParam<AmplifierParamQuantity>(A5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 A send");
- configParam(PRE_A5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 A send pre/post");
- configParam<AmplifierParamQuantity>(B5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 B send");
- configParam(PRE_B5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 B send pre/post");
- configParam<EQParamQuantity>(LOW6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 low", " dB");
- configParam<EQParamQuantity>(MID6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 mid", " dB");
- configParam<EQParamQuantity>(HIGH6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 high", " dB");
- configParam<AmplifierParamQuantity>(A6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 A send");
- configParam(PRE_A6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 A send pre/post");
- configParam<AmplifierParamQuantity>(B6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 B send");
- configParam(PRE_B6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 B send pre/post");
- configParam<EQParamQuantity>(LOW7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 low", " dB");
- configParam<EQParamQuantity>(MID7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 mid", " dB");
- configParam<EQParamQuantity>(HIGH7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 high", " dB");
- configParam<AmplifierParamQuantity>(A7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 A send");
- configParam(PRE_A7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 A send pre/post");
- configParam<AmplifierParamQuantity>(B7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 B send");
- configParam(PRE_B7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 B send pre/post");
- configParam<EQParamQuantity>(LOW8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 low", " dB");
- configParam<EQParamQuantity>(MID8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 mid", " dB");
- configParam<EQParamQuantity>(HIGH8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 high", " dB");
- configParam<AmplifierParamQuantity>(A8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 A send");
- configParam(PRE_A8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 A send pre/post");
- configParam<AmplifierParamQuantity>(B8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 B send");
- configParam(PRE_B8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 B send pre/post");
- configParam<AmplifierParamQuantity>(LEVEL_A_PARAM, 0.0f, 1.0f, 0.8f, "A return level");
- configParam<AmplifierParamQuantity>(LEVEL_B_PARAM, 0.0f, 1.0f, 0.8f, "B return level");
-
- _channels[0] = new MixerExpanderChannel(params[LOW1_PARAM], params[MID1_PARAM], params[HIGH1_PARAM], params[A1_PARAM], params[B1_PARAM], params[PRE_A1_PARAM], params[PRE_B1_PARAM], inputs[A1_INPUT], inputs[B1_INPUT]);
- _channels[1] = new MixerExpanderChannel(params[LOW2_PARAM], params[MID2_PARAM], params[HIGH2_PARAM], params[A2_PARAM], params[B2_PARAM], params[PRE_A2_PARAM], params[PRE_B2_PARAM], inputs[A2_INPUT], inputs[B2_INPUT]);
- _channels[2] = new MixerExpanderChannel(params[LOW3_PARAM], params[MID3_PARAM], params[HIGH3_PARAM], params[A3_PARAM], params[B3_PARAM], params[PRE_A3_PARAM], params[PRE_B3_PARAM], inputs[A3_INPUT], inputs[B3_INPUT]);
- _channels[3] = new MixerExpanderChannel(params[LOW4_PARAM], params[MID4_PARAM], params[HIGH4_PARAM], params[A4_PARAM], params[B4_PARAM], params[PRE_A4_PARAM], params[PRE_B4_PARAM], inputs[A4_INPUT], inputs[B4_INPUT]);
- _channels[4] = new MixerExpanderChannel(params[LOW5_PARAM], params[MID5_PARAM], params[HIGH5_PARAM], params[A5_PARAM], params[B5_PARAM], params[PRE_A5_PARAM], params[PRE_B5_PARAM], inputs[A5_INPUT], inputs[B5_INPUT]);
- _channels[5] = new MixerExpanderChannel(params[LOW6_PARAM], params[MID6_PARAM], params[HIGH6_PARAM], params[A6_PARAM], params[B6_PARAM], params[PRE_A6_PARAM], params[PRE_B6_PARAM], inputs[A6_INPUT], inputs[B6_INPUT]);
- _channels[6] = new MixerExpanderChannel(params[LOW7_PARAM], params[MID7_PARAM], params[HIGH7_PARAM], params[A7_PARAM], params[B7_PARAM], params[PRE_A7_PARAM], params[PRE_B7_PARAM], inputs[A7_INPUT], inputs[B7_INPUT]);
- _channels[7] = new MixerExpanderChannel(params[LOW8_PARAM], params[MID8_PARAM], params[HIGH8_PARAM], params[A8_PARAM], params[B8_PARAM], params[PRE_A8_PARAM], params[PRE_B8_PARAM], inputs[A8_INPUT], inputs[B8_INPUT]);
-
- setBaseModel(modelMix8);
- }
- virtual ~Mix8x() {
- for (int i = 0; i < 8; ++i) {
- delete _channels[i];
- }
- }
-
- void sampleRateChange() override;
- void modulate() override;
- void processAll(const ProcessArgs& args) override;
-};
-
} // namespace bogaudio
diff --git a/src/Mix8_shared.hpp b/src/Mix8_shared.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "mixer_expander.hpp"
+#include "dsp/signal.hpp"
+
+extern Model* modelMix8;
+extern Model* modelMix8x;
+
+namespace bogaudio {
+
+typedef MixerExpanderMessage<8> Mix8ExpanderMessage;
+
+} // namespace bogaudio
diff --git a/src/Mix8x.cpp b/src/Mix8x.cpp
@@ -0,0 +1,283 @@
+
+#include "Mix8x.hpp"
+
+void Mix8x::sampleRateChange() {
+ float sr = APP->engine->getSampleRate();
+ for (int i = 0; i < 8; ++i) {
+ _channels[i]->setSampleRate(sr);
+ }
+ _returnASL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+ _returnBSL.setParams(sr, MixerChannel::levelSlewTimeMS, MixerChannel::maxDecibels - MixerChannel::minDecibels);
+}
+
+void Mix8x::modulate() {
+ for (int i = 0; i < 8; ++i) {
+ _channels[i]->modulate();
+ }
+}
+
+void Mix8x::processAll(const ProcessArgs& args) {
+ if (!baseConnected()) {
+ outputs[SEND_A_OUTPUT].setVoltage(0.0f);
+ outputs[SEND_B_OUTPUT].setVoltage(0.0f);
+ return;
+ }
+
+ Mix8ExpanderMessage* from = fromBase();
+ Mix8ExpanderMessage* to = toBase();
+ float sendA = 0.0f;
+ float sendB = 0.0f;
+ bool sendAActive = outputs[SEND_A_OUTPUT].isConnected();
+ bool sendBActive = outputs[SEND_B_OUTPUT].isConnected();
+ for (int i = 0; i < 8; ++i) {
+ if (from->active[i]) {
+ _channels[i]->next(from->preFader[i], from->postFader[i], sendAActive, sendBActive);
+ to->postEQ[i] = _channels[i]->postEQ;
+ sendA += _channels[i]->sendA;
+ sendB += _channels[i]->sendB;
+ }
+ else {
+ to->postEQ[i] = from->preFader[i];
+ }
+ }
+ outputs[SEND_A_OUTPUT].setVoltage(_saturatorA.next(sendA));
+ outputs[SEND_B_OUTPUT].setVoltage(_saturatorA.next(sendB));
+
+ bool lAActive = inputs[L_A_INPUT].isConnected();
+ bool rAActive = inputs[R_A_INPUT].isConnected();
+ if (lAActive || rAActive) {
+ float levelA = clamp(params[LEVEL_A_PARAM].getValue(), 0.0f, 1.0f);
+ if (inputs[LEVEL_A_INPUT].isConnected()) {
+ levelA *= clamp(inputs[LEVEL_A_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
+ }
+ levelA = 1.0f - levelA;
+ levelA *= Amplifier::minDecibels;
+ _returnAAmp.setLevel(_returnASL.next(levelA));
+ if (lAActive) {
+ to->returnA[0] = _returnAAmp.next(inputs[L_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[0] = 0.0f;
+ }
+ if (rAActive) {
+ to->returnA[1] = _returnAAmp.next(inputs[R_A_INPUT].getVoltage());
+ }
+ else {
+ to->returnA[1] = to->returnA[0];
+ }
+ }
+
+ bool lBActive = inputs[L_B_INPUT].isConnected();
+ bool rBActive = inputs[R_B_INPUT].isConnected();
+ if (lBActive || rBActive) {
+ float levelB = clamp(params[LEVEL_B_PARAM].getValue(), 0.0f, 1.0f);
+ levelB = 1.0f - levelB;
+ levelB *= Amplifier::minDecibels;
+ _returnBAmp.setLevel(_returnBSL.next(levelB));
+ if (lBActive) {
+ to->returnB[0] = _returnBAmp.next(inputs[L_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[0] = 0.0f;
+ }
+ if (rBActive) {
+ to->returnB[1] = _returnBAmp.next(inputs[R_B_INPUT].getVoltage());
+ }
+ else {
+ to->returnB[1] = to->returnB[0];
+ }
+ }
+}
+
+struct Mix8xWidget : ModuleWidget {
+ static constexpr int hp = 27;
+
+ Mix8xWidget(Mix8x* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+
+ {
+ SvgPanel *panel = new SvgPanel();
+ panel->box.size = box.size;
+ panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Mix8x.svg")));
+ addChild(panel);
+ }
+
+ addChild(createWidget<ScrewSilver>(Vec(15, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(15, 365)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365)));
+
+ // generated by svg_widgets.rb
+ auto low1ParamPosition = Vec(18.5, 43.0);
+ auto mid1ParamPosition = Vec(18.5, 89.0);
+ auto high1ParamPosition = Vec(18.5, 135.0);
+ auto a1ParamPosition = Vec(18.5, 180.0);
+ auto preA1ParamPosition = Vec(30.0, 208.0);
+ auto b1ParamPosition = Vec(18.5, 236.0);
+ auto preB1ParamPosition = Vec(30.0, 264.0);
+ auto low2ParamPosition = Vec(62.5, 43.0);
+ auto mid2ParamPosition = Vec(62.5, 89.0);
+ auto high2ParamPosition = Vec(62.5, 135.0);
+ auto a2ParamPosition = Vec(62.5, 180.0);
+ auto preA2ParamPosition = Vec(74.0, 208.0);
+ auto b2ParamPosition = Vec(62.5, 236.0);
+ auto preB2ParamPosition = Vec(74.0, 264.0);
+ auto low3ParamPosition = Vec(106.5, 43.0);
+ auto mid3ParamPosition = Vec(106.5, 89.0);
+ auto high3ParamPosition = Vec(106.5, 135.0);
+ auto a3ParamPosition = Vec(106.5, 180.0);
+ auto preA3ParamPosition = Vec(118.0, 208.0);
+ auto b3ParamPosition = Vec(106.5, 236.0);
+ auto preB3ParamPosition = Vec(118.0, 264.0);
+ auto low4ParamPosition = Vec(150.5, 43.0);
+ auto mid4ParamPosition = Vec(150.5, 89.0);
+ auto high4ParamPosition = Vec(150.5, 135.0);
+ auto a4ParamPosition = Vec(150.5, 180.0);
+ auto preA4ParamPosition = Vec(162.0, 208.0);
+ auto b4ParamPosition = Vec(150.5, 236.0);
+ auto preB4ParamPosition = Vec(162.0, 264.0);
+ auto low5ParamPosition = Vec(194.5, 43.0);
+ auto mid5ParamPosition = Vec(194.5, 89.0);
+ auto high5ParamPosition = Vec(194.5, 135.0);
+ auto a5ParamPosition = Vec(194.5, 180.0);
+ auto preA5ParamPosition = Vec(206.0, 208.0);
+ auto b5ParamPosition = Vec(194.5, 236.0);
+ auto preB5ParamPosition = Vec(206.0, 264.0);
+ auto low6ParamPosition = Vec(238.5, 43.0);
+ auto mid6ParamPosition = Vec(238.5, 89.0);
+ auto high6ParamPosition = Vec(238.5, 135.0);
+ auto a6ParamPosition = Vec(238.5, 180.0);
+ auto preA6ParamPosition = Vec(250.0, 208.0);
+ auto b6ParamPosition = Vec(238.5, 236.0);
+ auto preB6ParamPosition = Vec(250.0, 264.0);
+ auto low7ParamPosition = Vec(282.5, 43.0);
+ auto mid7ParamPosition = Vec(282.5, 89.0);
+ auto high7ParamPosition = Vec(282.5, 135.0);
+ auto a7ParamPosition = Vec(282.5, 180.0);
+ auto preA7ParamPosition = Vec(294.0, 208.0);
+ auto b7ParamPosition = Vec(282.5, 236.0);
+ auto preB7ParamPosition = Vec(294.0, 264.0);
+ auto low8ParamPosition = Vec(326.5, 43.0);
+ auto mid8ParamPosition = Vec(326.5, 89.0);
+ auto high8ParamPosition = Vec(326.5, 135.0);
+ auto a8ParamPosition = Vec(326.5, 180.0);
+ auto preA8ParamPosition = Vec(338.0, 208.0);
+ auto b8ParamPosition = Vec(326.5, 236.0);
+ auto preB8ParamPosition = Vec(338.0, 264.0);
+ auto levelAParamPosition = Vec(370.5, 138.0);
+ auto levelBParamPosition = Vec(370.5, 328.0);
+
+ auto a1InputPosition = Vec(14.5, 290.0);
+ auto b1InputPosition = Vec(14.5, 325.0);
+ auto a2InputPosition = Vec(58.5, 290.0);
+ auto b2InputPosition = Vec(58.5, 325.0);
+ auto a3InputPosition = Vec(102.5, 290.0);
+ auto b3InputPosition = Vec(102.5, 325.0);
+ auto a4InputPosition = Vec(146.5, 290.0);
+ auto b4InputPosition = Vec(146.5, 325.0);
+ auto a5InputPosition = Vec(190.5, 290.0);
+ auto b5InputPosition = Vec(190.5, 325.0);
+ auto a6InputPosition = Vec(234.5, 290.0);
+ auto b6InputPosition = Vec(234.5, 325.0);
+ auto a7InputPosition = Vec(278.5, 290.0);
+ auto b7InputPosition = Vec(278.5, 325.0);
+ auto a8InputPosition = Vec(322.5, 290.0);
+ auto b8InputPosition = Vec(322.5, 325.0);
+ auto lAInputPosition = Vec(366.5, 62.0);
+ auto rAInputPosition = Vec(366.5, 97.0);
+ auto levelAInputPosition = Vec(366.5, 170.0);
+ auto lBInputPosition = Vec(366.5, 252.0);
+ auto rBInputPosition = Vec(366.5, 287.0);
+
+ auto sendAOutputPosition = Vec(366.5, 24.0);
+ auto sendBOutputPosition = Vec(366.5, 214.0);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<Knob16>(low1ParamPosition, module, Mix8x::LOW1_PARAM));
+ addParam(createParam<Knob16>(mid1ParamPosition, module, Mix8x::MID1_PARAM));
+ addParam(createParam<Knob16>(high1ParamPosition, module, Mix8x::HIGH1_PARAM));
+ addParam(createParam<Knob16>(a1ParamPosition, module, Mix8x::A1_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA1ParamPosition, module, Mix8x::PRE_A1_PARAM));
+ addParam(createParam<Knob16>(b1ParamPosition, module, Mix8x::B1_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB1ParamPosition, module, Mix8x::PRE_B1_PARAM));
+ addParam(createParam<Knob16>(low2ParamPosition, module, Mix8x::LOW2_PARAM));
+ addParam(createParam<Knob16>(mid2ParamPosition, module, Mix8x::MID2_PARAM));
+ addParam(createParam<Knob16>(high2ParamPosition, module, Mix8x::HIGH2_PARAM));
+ addParam(createParam<Knob16>(a2ParamPosition, module, Mix8x::A2_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA2ParamPosition, module, Mix8x::PRE_A2_PARAM));
+ addParam(createParam<Knob16>(b2ParamPosition, module, Mix8x::B2_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB2ParamPosition, module, Mix8x::PRE_B2_PARAM));
+ addParam(createParam<Knob16>(low3ParamPosition, module, Mix8x::LOW3_PARAM));
+ addParam(createParam<Knob16>(mid3ParamPosition, module, Mix8x::MID3_PARAM));
+ addParam(createParam<Knob16>(high3ParamPosition, module, Mix8x::HIGH3_PARAM));
+ addParam(createParam<Knob16>(a3ParamPosition, module, Mix8x::A3_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA3ParamPosition, module, Mix8x::PRE_A3_PARAM));
+ addParam(createParam<Knob16>(b3ParamPosition, module, Mix8x::B3_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB3ParamPosition, module, Mix8x::PRE_B3_PARAM));
+ addParam(createParam<Knob16>(low4ParamPosition, module, Mix8x::LOW4_PARAM));
+ addParam(createParam<Knob16>(mid4ParamPosition, module, Mix8x::MID4_PARAM));
+ addParam(createParam<Knob16>(high4ParamPosition, module, Mix8x::HIGH4_PARAM));
+ addParam(createParam<Knob16>(a4ParamPosition, module, Mix8x::A4_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA4ParamPosition, module, Mix8x::PRE_A4_PARAM));
+ addParam(createParam<Knob16>(b4ParamPosition, module, Mix8x::B4_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB4ParamPosition, module, Mix8x::PRE_B4_PARAM));
+ addParam(createParam<Knob16>(low5ParamPosition, module, Mix8x::LOW5_PARAM));
+ addParam(createParam<Knob16>(mid5ParamPosition, module, Mix8x::MID5_PARAM));
+ addParam(createParam<Knob16>(high5ParamPosition, module, Mix8x::HIGH5_PARAM));
+ addParam(createParam<Knob16>(a5ParamPosition, module, Mix8x::A5_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA5ParamPosition, module, Mix8x::PRE_A5_PARAM));
+ addParam(createParam<Knob16>(b5ParamPosition, module, Mix8x::B5_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB5ParamPosition, module, Mix8x::PRE_B5_PARAM));
+ addParam(createParam<Knob16>(low6ParamPosition, module, Mix8x::LOW6_PARAM));
+ addParam(createParam<Knob16>(mid6ParamPosition, module, Mix8x::MID6_PARAM));
+ addParam(createParam<Knob16>(high6ParamPosition, module, Mix8x::HIGH6_PARAM));
+ addParam(createParam<Knob16>(a6ParamPosition, module, Mix8x::A6_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA6ParamPosition, module, Mix8x::PRE_A6_PARAM));
+ addParam(createParam<Knob16>(b6ParamPosition, module, Mix8x::B6_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB6ParamPosition, module, Mix8x::PRE_B6_PARAM));
+ addParam(createParam<Knob16>(low7ParamPosition, module, Mix8x::LOW7_PARAM));
+ addParam(createParam<Knob16>(mid7ParamPosition, module, Mix8x::MID7_PARAM));
+ addParam(createParam<Knob16>(high7ParamPosition, module, Mix8x::HIGH7_PARAM));
+ addParam(createParam<Knob16>(a7ParamPosition, module, Mix8x::A7_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA7ParamPosition, module, Mix8x::PRE_A7_PARAM));
+ addParam(createParam<Knob16>(b7ParamPosition, module, Mix8x::B7_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB7ParamPosition, module, Mix8x::PRE_B7_PARAM));
+ addParam(createParam<Knob16>(low8ParamPosition, module, Mix8x::LOW8_PARAM));
+ addParam(createParam<Knob16>(mid8ParamPosition, module, Mix8x::MID8_PARAM));
+ addParam(createParam<Knob16>(high8ParamPosition, module, Mix8x::HIGH8_PARAM));
+ addParam(createParam<Knob16>(a8ParamPosition, module, Mix8x::A8_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preA8ParamPosition, module, Mix8x::PRE_A8_PARAM));
+ addParam(createParam<Knob16>(b8ParamPosition, module, Mix8x::B8_PARAM));
+ addParam(createParam<IndicatorButtonGreen9>(preB8ParamPosition, module, Mix8x::PRE_B8_PARAM));
+ addParam(createParam<Knob16>(levelAParamPosition, module, Mix8x::LEVEL_A_PARAM));
+ addParam(createParam<Knob16>(levelBParamPosition, module, Mix8x::LEVEL_B_PARAM));
+
+ addInput(createInput<Port24>(a1InputPosition, module, Mix8x::A1_INPUT));
+ addInput(createInput<Port24>(b1InputPosition, module, Mix8x::B1_INPUT));
+ addInput(createInput<Port24>(a2InputPosition, module, Mix8x::A2_INPUT));
+ addInput(createInput<Port24>(b2InputPosition, module, Mix8x::B2_INPUT));
+ addInput(createInput<Port24>(a3InputPosition, module, Mix8x::A3_INPUT));
+ addInput(createInput<Port24>(b3InputPosition, module, Mix8x::B3_INPUT));
+ addInput(createInput<Port24>(a4InputPosition, module, Mix8x::A4_INPUT));
+ addInput(createInput<Port24>(b4InputPosition, module, Mix8x::B4_INPUT));
+ addInput(createInput<Port24>(a5InputPosition, module, Mix8x::A5_INPUT));
+ addInput(createInput<Port24>(b5InputPosition, module, Mix8x::B5_INPUT));
+ addInput(createInput<Port24>(a6InputPosition, module, Mix8x::A6_INPUT));
+ addInput(createInput<Port24>(b6InputPosition, module, Mix8x::B6_INPUT));
+ addInput(createInput<Port24>(a7InputPosition, module, Mix8x::A7_INPUT));
+ addInput(createInput<Port24>(b7InputPosition, module, Mix8x::B7_INPUT));
+ addInput(createInput<Port24>(a8InputPosition, module, Mix8x::A8_INPUT));
+ addInput(createInput<Port24>(b8InputPosition, module, Mix8x::B8_INPUT));
+ addInput(createInput<Port24>(lAInputPosition, module, Mix8x::L_A_INPUT));
+ addInput(createInput<Port24>(rAInputPosition, module, Mix8x::R_A_INPUT));
+ addInput(createInput<Port24>(levelAInputPosition, module, Mix8x::LEVEL_A_INPUT));
+ addInput(createInput<Port24>(lBInputPosition, module, Mix8x::L_B_INPUT));
+ addInput(createInput<Port24>(rBInputPosition, module, Mix8x::R_B_INPUT));
+
+ addOutput(createOutput<Port24>(sendAOutputPosition, module, Mix8x::SEND_A_OUTPUT));
+ addOutput(createOutput<Port24>(sendBOutputPosition, module, Mix8x::SEND_B_OUTPUT));
+ }
+};
+
+Model* modelMix8x = createModel<Mix8x, Mix8xWidget>("Bogaudio-Mix8x", "MIX8X", "Expander for MIX8, adds EQs and sends", "Mixer", "Expander");
diff --git a/src/Mix8x.hpp b/src/Mix8x.hpp
@@ -0,0 +1,191 @@
+#pragma once
+
+#include "bogaudio.hpp"
+#include "Mix8_shared.hpp"
+
+using namespace bogaudio::dsp;
+namespace bogaudio {
+
+struct Mix8x : ExpanderModule<Mix8ExpanderMessage, BGModule> {
+ enum ParamsIds {
+ LOW1_PARAM,
+ MID1_PARAM,
+ HIGH1_PARAM,
+ A1_PARAM,
+ PRE_A1_PARAM,
+ B1_PARAM,
+ PRE_B1_PARAM,
+ LOW2_PARAM,
+ MID2_PARAM,
+ HIGH2_PARAM,
+ A2_PARAM,
+ PRE_A2_PARAM,
+ B2_PARAM,
+ PRE_B2_PARAM,
+ LOW3_PARAM,
+ MID3_PARAM,
+ HIGH3_PARAM,
+ A3_PARAM,
+ PRE_A3_PARAM,
+ B3_PARAM,
+ PRE_B3_PARAM,
+ LOW4_PARAM,
+ MID4_PARAM,
+ HIGH4_PARAM,
+ A4_PARAM,
+ PRE_A4_PARAM,
+ B4_PARAM,
+ PRE_B4_PARAM,
+ LOW5_PARAM,
+ MID5_PARAM,
+ HIGH5_PARAM,
+ A5_PARAM,
+ PRE_A5_PARAM,
+ B5_PARAM,
+ PRE_B5_PARAM,
+ LOW6_PARAM,
+ MID6_PARAM,
+ HIGH6_PARAM,
+ A6_PARAM,
+ PRE_A6_PARAM,
+ B6_PARAM,
+ PRE_B6_PARAM,
+ LOW7_PARAM,
+ MID7_PARAM,
+ HIGH7_PARAM,
+ A7_PARAM,
+ PRE_A7_PARAM,
+ B7_PARAM,
+ PRE_B7_PARAM,
+ LOW8_PARAM,
+ MID8_PARAM,
+ HIGH8_PARAM,
+ A8_PARAM,
+ PRE_A8_PARAM,
+ B8_PARAM,
+ PRE_B8_PARAM,
+ LEVEL_A_PARAM,
+ LEVEL_B_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ A1_INPUT,
+ B1_INPUT,
+ A2_INPUT,
+ B2_INPUT,
+ A3_INPUT,
+ B3_INPUT,
+ A4_INPUT,
+ B4_INPUT,
+ A5_INPUT,
+ B5_INPUT,
+ A6_INPUT,
+ B6_INPUT,
+ A7_INPUT,
+ B7_INPUT,
+ A8_INPUT,
+ B8_INPUT,
+ L_A_INPUT,
+ R_A_INPUT,
+ LEVEL_A_INPUT,
+ L_B_INPUT,
+ R_B_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ SEND_A_OUTPUT,
+ SEND_B_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ MixerExpanderChannel* _channels[8] {};
+ Saturator _saturatorA, _saturatorB;
+ Amplifier _returnAAmp, _returnBAmp;
+ bogaudio::dsp::SlewLimiter _returnASL, _returnBSL;
+
+ Mix8x() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
+ configParam<EQParamQuantity>(LOW1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 low", " dB");
+ configParam<EQParamQuantity>(MID1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 mid", " dB");
+ configParam<EQParamQuantity>(HIGH1_PARAM, -1.0f, 1.0f, 0.0f, "Channel 1 high", " dB");
+ configParam<AmplifierParamQuantity>(A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send");
+ configParam(PRE_A1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 A send pre/post");
+ configParam<AmplifierParamQuantity>(B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send");
+ configParam(PRE_B1_PARAM, 0.0f, 1.0f, 0.0f, "Channel 1 B send pre/post");
+ configParam<EQParamQuantity>(LOW2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 low", " dB");
+ configParam<EQParamQuantity>(MID2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 mid", " dB");
+ configParam<EQParamQuantity>(HIGH2_PARAM, -1.0f, 1.0f, 0.0f, "Channel 2 high", " dB");
+ configParam<AmplifierParamQuantity>(A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send");
+ configParam(PRE_A2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 A send pre/post");
+ configParam<AmplifierParamQuantity>(B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send");
+ configParam(PRE_B2_PARAM, 0.0f, 1.0f, 0.0f, "Channel 2 B send pre/post");
+ configParam<EQParamQuantity>(LOW3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 low", " dB");
+ configParam<EQParamQuantity>(MID3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 mid", " dB");
+ configParam<EQParamQuantity>(HIGH3_PARAM, -1.0f, 1.0f, 0.0f, "Channel 3 high", " dB");
+ configParam<AmplifierParamQuantity>(A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send");
+ configParam(PRE_A3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 A send pre/post");
+ configParam<AmplifierParamQuantity>(B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send");
+ configParam(PRE_B3_PARAM, 0.0f, 1.0f, 0.0f, "Channel 3 B send pre/post");
+ configParam<EQParamQuantity>(LOW4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 low", " dB");
+ configParam<EQParamQuantity>(MID4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 mid", " dB");
+ configParam<EQParamQuantity>(HIGH4_PARAM, -1.0f, 1.0f, 0.0f, "Channel 4 high", " dB");
+ configParam<AmplifierParamQuantity>(A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send");
+ configParam(PRE_A4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 A send pre/post");
+ configParam<AmplifierParamQuantity>(B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send");
+ configParam(PRE_B4_PARAM, 0.0f, 1.0f, 0.0f, "Channel 4 B send pre/post");
+ configParam<EQParamQuantity>(LOW5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 low", " dB");
+ configParam<EQParamQuantity>(MID5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 mid", " dB");
+ configParam<EQParamQuantity>(HIGH5_PARAM, -1.0f, 1.0f, 0.0f, "Channel 5 high", " dB");
+ configParam<AmplifierParamQuantity>(A5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 A send");
+ configParam(PRE_A5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 A send pre/post");
+ configParam<AmplifierParamQuantity>(B5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 B send");
+ configParam(PRE_B5_PARAM, 0.0f, 1.0f, 0.0f, "Channel 5 B send pre/post");
+ configParam<EQParamQuantity>(LOW6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 low", " dB");
+ configParam<EQParamQuantity>(MID6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 mid", " dB");
+ configParam<EQParamQuantity>(HIGH6_PARAM, -1.0f, 1.0f, 0.0f, "Channel 6 high", " dB");
+ configParam<AmplifierParamQuantity>(A6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 A send");
+ configParam(PRE_A6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 A send pre/post");
+ configParam<AmplifierParamQuantity>(B6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 B send");
+ configParam(PRE_B6_PARAM, 0.0f, 1.0f, 0.0f, "Channel 6 B send pre/post");
+ configParam<EQParamQuantity>(LOW7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 low", " dB");
+ configParam<EQParamQuantity>(MID7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 mid", " dB");
+ configParam<EQParamQuantity>(HIGH7_PARAM, -1.0f, 1.0f, 0.0f, "Channel 7 high", " dB");
+ configParam<AmplifierParamQuantity>(A7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 A send");
+ configParam(PRE_A7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 A send pre/post");
+ configParam<AmplifierParamQuantity>(B7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 B send");
+ configParam(PRE_B7_PARAM, 0.0f, 1.0f, 0.0f, "Channel 7 B send pre/post");
+ configParam<EQParamQuantity>(LOW8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 low", " dB");
+ configParam<EQParamQuantity>(MID8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 mid", " dB");
+ configParam<EQParamQuantity>(HIGH8_PARAM, -1.0f, 1.0f, 0.0f, "Channel 8 high", " dB");
+ configParam<AmplifierParamQuantity>(A8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 A send");
+ configParam(PRE_A8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 A send pre/post");
+ configParam<AmplifierParamQuantity>(B8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 B send");
+ configParam(PRE_B8_PARAM, 0.0f, 1.0f, 0.0f, "Channel 8 B send pre/post");
+ configParam<AmplifierParamQuantity>(LEVEL_A_PARAM, 0.0f, 1.0f, 0.8f, "A return level");
+ configParam<AmplifierParamQuantity>(LEVEL_B_PARAM, 0.0f, 1.0f, 0.8f, "B return level");
+
+ _channels[0] = new MixerExpanderChannel(params[LOW1_PARAM], params[MID1_PARAM], params[HIGH1_PARAM], params[A1_PARAM], params[B1_PARAM], params[PRE_A1_PARAM], params[PRE_B1_PARAM], inputs[A1_INPUT], inputs[B1_INPUT]);
+ _channels[1] = new MixerExpanderChannel(params[LOW2_PARAM], params[MID2_PARAM], params[HIGH2_PARAM], params[A2_PARAM], params[B2_PARAM], params[PRE_A2_PARAM], params[PRE_B2_PARAM], inputs[A2_INPUT], inputs[B2_INPUT]);
+ _channels[2] = new MixerExpanderChannel(params[LOW3_PARAM], params[MID3_PARAM], params[HIGH3_PARAM], params[A3_PARAM], params[B3_PARAM], params[PRE_A3_PARAM], params[PRE_B3_PARAM], inputs[A3_INPUT], inputs[B3_INPUT]);
+ _channels[3] = new MixerExpanderChannel(params[LOW4_PARAM], params[MID4_PARAM], params[HIGH4_PARAM], params[A4_PARAM], params[B4_PARAM], params[PRE_A4_PARAM], params[PRE_B4_PARAM], inputs[A4_INPUT], inputs[B4_INPUT]);
+ _channels[4] = new MixerExpanderChannel(params[LOW5_PARAM], params[MID5_PARAM], params[HIGH5_PARAM], params[A5_PARAM], params[B5_PARAM], params[PRE_A5_PARAM], params[PRE_B5_PARAM], inputs[A5_INPUT], inputs[B5_INPUT]);
+ _channels[5] = new MixerExpanderChannel(params[LOW6_PARAM], params[MID6_PARAM], params[HIGH6_PARAM], params[A6_PARAM], params[B6_PARAM], params[PRE_A6_PARAM], params[PRE_B6_PARAM], inputs[A6_INPUT], inputs[B6_INPUT]);
+ _channels[6] = new MixerExpanderChannel(params[LOW7_PARAM], params[MID7_PARAM], params[HIGH7_PARAM], params[A7_PARAM], params[B7_PARAM], params[PRE_A7_PARAM], params[PRE_B7_PARAM], inputs[A7_INPUT], inputs[B7_INPUT]);
+ _channels[7] = new MixerExpanderChannel(params[LOW8_PARAM], params[MID8_PARAM], params[HIGH8_PARAM], params[A8_PARAM], params[B8_PARAM], params[PRE_A8_PARAM], params[PRE_B8_PARAM], inputs[A8_INPUT], inputs[B8_INPUT]);
+
+ setBaseModel(modelMix8);
+ }
+ virtual ~Mix8x() {
+ for (int i = 0; i < 8; ++i) {
+ delete _channels[i];
+ }
+ }
+
+ void sampleRateChange() override;
+ void modulate() override;
+ void processAll(const ProcessArgs& args) override;
+};
+
+} // namespace bogaudio
diff --git a/src/Pgmr.cpp b/src/Pgmr.cpp
@@ -3,82 +3,6 @@
#define SELECT_TRIGGERS "SELECT_TRIGGERS"
-void PgmrStep::reset() {
- for (int c = 0; c < BGModule::maxChannels; ++c) {
- triggers[c].reset();
- pulseGens[c].process(1000.0f);
- }
-}
-
-
-PgmrRegistry::Base::Base(Pgmr& b) : module(b) {
- std::copy(b._localSteps, b._localSteps + 4, std::back_inserter(steps));
-}
-
-int PgmrRegistry::registerBase(Pgmr& b) {
- std::lock_guard<std::mutex> lock(_lock);
-
- int id = _nextID;
- ++_nextID;
- auto p = _bases.emplace(id, Base(b));
- b.setSteps(p.first->second.steps);
- return id;
-}
-
-void PgmrRegistry::deregisterBase(int id) {
- std::lock_guard<std::mutex> lock(_lock);
- _bases.erase(id);
-}
-
-void PgmrRegistry::registerExpander(int baseID, int position, PgmrX& x) {
- std::lock_guard<std::mutex> lock(_lock);
-
- assert(position > 0);
- auto base = _bases.find(baseID);
- if (base != _bases.end()) {
- int i = 4 * position;
- if (i < (int)base->second.steps.size()) {
- assert(!base->second.steps[i]);
- std::copy(x._localSteps, x._localSteps + 4, base->second.steps.begin() + i);
- }
- else {
- base->second.steps.resize(i + 4, NULL);
- std::copy(x._localSteps, x._localSteps + 4, base->second.steps.begin() + i);
- }
- for (auto i = base->second.steps.begin(), n = base->second.steps.end(); i != n; ++i) {
- if (!*i) {
- return;
- }
- }
- base->second.module.setSteps(base->second.steps);
- }
-}
-
-void PgmrRegistry::deregisterExpander(int baseID, int position) {
- std::lock_guard<std::mutex> lock(_lock);
-
- auto base = _bases.find(baseID);
- if (base != _bases.end()) {
- int n = 4 * position;
- if (n < (int)base->second.steps.size()) {
- int i = 0;
- for (; i < n; ++i) {
- if (!base->second.steps[i]) {
- break;
- }
- }
- base->second.steps.resize(i);
- base->second.module.setSteps(base->second.steps);
- }
- }
-}
-
-PgmrRegistry& PgmrRegistry::registry() {
- static PgmrRegistry instance;
- return instance;
-}
-
-
void Pgmr::reset() {
std::lock_guard<SpinLock> lock(_stepsLock);
@@ -332,139 +256,3 @@ struct PgmrWidget : AddressableSequenceBaseModuleWidget {
};
Model* modelPgmr = createModel<Pgmr, PgmrWidget>("Bogaudio-Pgmr", "PGMR", "4-step programmer and sequencer", "Sequencer", "Polyphonic");
-
-
-void PgmrX::processAlways(const ProcessArgs& args) {
- int position = 0;
- int baseID = 0;
- if (baseConnected()) {
- PgmrExpanderMessage* bm = fromBase();
- baseID = bm->baseID;
- position = bm->position;
- _rangeOffset = bm->rangeOffset;
- _rangeScale = bm->rangeScale;
- }
-
- if (_registered && (position <= 0 || position != _position)) {
- PgmrRegistry::registry().deregisterExpander(_baseID, _position);
- _registered = false;
- _baseID = 0;
- _position = 0;
- }
- else if (!_registered && position > 0) {
- _registered = true;
- _baseID = baseID;
- _position = position;
- PgmrRegistry::registry().registerExpander(_baseID, _position, *this);
- }
-
- if (_position < 1) {
- for (int i = 0; i < 4; ++i) {
- _localSteps[i]->selectedLight.value = 0.0f;
- }
- }
- if (expanderConnected()) {
- PgmrExpanderMessage* te = toExpander();
- te->baseID = _baseID;
- te->position = _position > 0 ? _position + 1 : 0;
- te->rangeOffset = _rangeOffset;
- te->rangeScale = _rangeScale;
- }
-}
-
-struct PgmrXWidget : ModuleWidget {
- static constexpr int hp = 12;
-
- PgmrXWidget(PgmrX* module) {
- setModule(module);
- box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
-
- {
- SvgPanel *panel = new SvgPanel();
- panel->box.size = box.size;
- panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PgmrX.svg")));
- addChild(panel);
- }
-
- addChild(createWidget<ScrewSilver>(Vec(0, 0)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 0)));
- addChild(createWidget<ScrewSilver>(Vec(0, 365)));
- addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365)));
-
- // generated by svg_widgets.rb
- auto cva1ParamPosition = Vec(9.5, 40.5);
- auto cvb1ParamPosition = Vec(9.5, 94.5);
- auto cvc1ParamPosition = Vec(9.5, 148.5);
- auto cvd1ParamPosition = Vec(9.5, 202.5);
- auto select1ParamPosition = Vec(13.5, 267.0);
- auto cva2ParamPosition = Vec(54.5, 40.5);
- auto cvb2ParamPosition = Vec(54.5, 94.5);
- auto cvc2ParamPosition = Vec(54.5, 148.5);
- auto cvd2ParamPosition = Vec(54.5, 202.5);
- auto select2ParamPosition = Vec(58.5, 267.0);
- auto cva3ParamPosition = Vec(99.5, 40.5);
- auto cvb3ParamPosition = Vec(99.5, 94.5);
- auto cvc3ParamPosition = Vec(99.5, 148.5);
- auto cvd3ParamPosition = Vec(99.5, 202.5);
- auto select3ParamPosition = Vec(103.5, 267.0);
- auto cva4ParamPosition = Vec(144.5, 40.5);
- auto cvb4ParamPosition = Vec(144.5, 94.5);
- auto cvc4ParamPosition = Vec(144.5, 148.5);
- auto cvd4ParamPosition = Vec(144.5, 202.5);
- auto select4ParamPosition = Vec(148.5, 267.0);
-
- auto select1InputPosition = Vec(10.5, 290.0);
- auto select2InputPosition = Vec(55.5, 290.0);
- auto select3InputPosition = Vec(100.5, 290.0);
- auto select4InputPosition = Vec(145.5, 290.0);
-
- auto select1OutputPosition = Vec(10.5, 330.0);
- auto select2OutputPosition = Vec(55.5, 330.0);
- auto select3OutputPosition = Vec(100.5, 330.0);
- auto select4OutputPosition = Vec(145.5, 330.0);
-
- auto select1LightPosition = Vec(19.3, 255.0);
- auto select2LightPosition = Vec(64.3, 255.0);
- auto select3LightPosition = Vec(109.3, 255.0);
- auto select4LightPosition = Vec(154.3, 255.0);
- // end generated by svg_widgets.rb
-
- addParam(createParam<Knob26>(cva1ParamPosition, module, PgmrX::CVA1_PARAM));
- addParam(createParam<Knob26>(cvb1ParamPosition, module, PgmrX::CVB1_PARAM));
- addParam(createParam<Knob26>(cvc1ParamPosition, module, PgmrX::CVC1_PARAM));
- addParam(createParam<Knob26>(cvd1ParamPosition, module, PgmrX::CVD1_PARAM));
- addParam(createParam<Button18>(select1ParamPosition, module, PgmrX::SELECT1_PARAM));
- addParam(createParam<Knob26>(cva2ParamPosition, module, PgmrX::CVA2_PARAM));
- addParam(createParam<Knob26>(cvb2ParamPosition, module, PgmrX::CVB2_PARAM));
- addParam(createParam<Knob26>(cvc2ParamPosition, module, PgmrX::CVC2_PARAM));
- addParam(createParam<Knob26>(cvd2ParamPosition, module, PgmrX::CVD2_PARAM));
- addParam(createParam<Button18>(select2ParamPosition, module, PgmrX::SELECT2_PARAM));
- addParam(createParam<Knob26>(cva3ParamPosition, module, PgmrX::CVA3_PARAM));
- addParam(createParam<Knob26>(cvb3ParamPosition, module, PgmrX::CVB3_PARAM));
- addParam(createParam<Knob26>(cvc3ParamPosition, module, PgmrX::CVC3_PARAM));
- addParam(createParam<Knob26>(cvd3ParamPosition, module, PgmrX::CVD3_PARAM));
- addParam(createParam<Button18>(select3ParamPosition, module, PgmrX::SELECT3_PARAM));
- addParam(createParam<Knob26>(cva4ParamPosition, module, PgmrX::CVA4_PARAM));
- addParam(createParam<Knob26>(cvb4ParamPosition, module, PgmrX::CVB4_PARAM));
- addParam(createParam<Knob26>(cvc4ParamPosition, module, PgmrX::CVC4_PARAM));
- addParam(createParam<Knob26>(cvd4ParamPosition, module, PgmrX::CVD4_PARAM));
- addParam(createParam<Button18>(select4ParamPosition, module, PgmrX::SELECT4_PARAM));
-
- addInput(createInput<Port24>(select1InputPosition, module, PgmrX::SELECT1_INPUT));
- addInput(createInput<Port24>(select2InputPosition, module, PgmrX::SELECT2_INPUT));
- addInput(createInput<Port24>(select3InputPosition, module, PgmrX::SELECT3_INPUT));
- addInput(createInput<Port24>(select4InputPosition, module, PgmrX::SELECT4_INPUT));
-
- addOutput(createOutput<Port24>(select1OutputPosition, module, PgmrX::SELECT1_OUTPUT));
- addOutput(createOutput<Port24>(select2OutputPosition, module, PgmrX::SELECT2_OUTPUT));
- addOutput(createOutput<Port24>(select3OutputPosition, module, PgmrX::SELECT3_OUTPUT));
- addOutput(createOutput<Port24>(select4OutputPosition, module, PgmrX::SELECT4_OUTPUT));
-
- addChild(createLight<SmallLight<GreenLight>>(select1LightPosition, module, PgmrX::SELECT1_LIGHT));
- addChild(createLight<SmallLight<GreenLight>>(select2LightPosition, module, PgmrX::SELECT2_LIGHT));
- addChild(createLight<SmallLight<GreenLight>>(select3LightPosition, module, PgmrX::SELECT3_LIGHT));
- addChild(createLight<SmallLight<GreenLight>>(select4LightPosition, module, PgmrX::SELECT4_LIGHT));
- }
-};
-
-Model* modelPgmrX = createModel<PgmrX, PgmrXWidget>("Bogaudio-PgmrX", "PGMRX", "4-step chainable expander for PGMR", "Sequencer", "Expander", "Polyphonic");
diff --git a/src/Pgmr.hpp b/src/Pgmr.hpp
@@ -1,99 +1,9 @@
#pragma once
-#include <mutex>
-#include <unordered_map>
-
-#include "bogaudio.hpp"
-#include "addressable_sequence.hpp"
-#include "expanders.hpp"
-
-extern Model* modelPgmr;
-extern Model* modelPgmrX;
+#include "Pgmr_shared.hpp"
namespace bogaudio {
-struct PgmrExpanderMessage : ExpanderMessage {
- int baseID = -1;
- int position = -1;
- float rangeOffset = 0.0f;
- float rangeScale = 10.0f;
-};
-
-struct PgmrStep {
- Param& aParam;
- Param& bParam;
- Param& cParam;
- Param& dParam;
- Light& selectedLight;
- Param& selectParam;
- Input& selectInput;
- Output& selectedOutput;
-
- Trigger triggers[BGModule::maxChannels];
- rack::dsp::PulseGenerator pulseGens[BGModule::maxChannels];
- float lightSum = 0.0f;
-
- PgmrStep(
- Param& aParam,
- Param& bParam,
- Param& cParam,
- Param& dParam,
- Light& selectedLight,
- Param& selectParam,
- Input& selectInput,
- Output& selectedOutput
- )
- : aParam(aParam)
- , bParam(bParam)
- , cParam(cParam)
- , dParam(dParam)
- , selectedLight(selectedLight)
- , selectParam(selectParam)
- , selectInput(selectInput)
- , selectedOutput(selectedOutput)
- {
- }
-
- void reset();
-};
-
-struct PgmrBase {
- PgmrStep* _localSteps[4] {};
-
- virtual ~PgmrBase() {
- for (int i = 0; i < 4; ++i) {
- if (_localSteps[i]) {
- delete _localSteps[i];
- }
- }
- }
-};
-
-struct Pgmr;
-struct PgmrX;
-
-struct PgmrRegistry {
-private:
- struct Base {
- Pgmr& module;
- std::vector<PgmrStep*> steps;
-
- Base(Pgmr& b);
- };
-
- std::mutex _lock;
- int _nextID = 1;
- std::unordered_map<int, Base> _bases;
-
-public:
- int registerBase(Pgmr& b);
- void deregisterBase(int id);
- void registerExpander(int baseID, int position, PgmrX& x);
- void deregisterExpander(int baseID, int position);
-
- static PgmrRegistry& registry();
-};
-
struct Pgmr : ExpandableModule<PgmrExpanderMessage, OutputRangeAddressableSequenceModule>, PgmrBase {
enum ParamsIds {
DIRECTION_PARAM,
@@ -208,96 +118,4 @@ struct Pgmr : ExpandableModule<PgmrExpanderMessage, OutputRangeAddressableSequen
void setSteps(std::vector<PgmrStep*>& steps);
};
-struct PgmrX : ExpanderModule<PgmrExpanderMessage, ExpandableModule<PgmrExpanderMessage, BGModule>>, PgmrBase, OutputRange {
- enum ParamsIds {
- CVA1_PARAM,
- CVB1_PARAM,
- CVC1_PARAM,
- CVD1_PARAM,
- SELECT1_PARAM,
- CVA2_PARAM,
- CVB2_PARAM,
- CVC2_PARAM,
- CVD2_PARAM,
- SELECT2_PARAM,
- CVA3_PARAM,
- CVB3_PARAM,
- CVC3_PARAM,
- CVD3_PARAM,
- SELECT3_PARAM,
- CVA4_PARAM,
- CVB4_PARAM,
- CVC4_PARAM,
- CVD4_PARAM,
- SELECT4_PARAM,
- NUM_PARAMS
- };
-
- enum InputsIds {
- SELECT1_INPUT,
- SELECT2_INPUT,
- SELECT3_INPUT,
- SELECT4_INPUT,
- NUM_INPUTS
- };
-
- enum OutputsIds {
- SELECT1_OUTPUT,
- SELECT2_OUTPUT,
- SELECT3_OUTPUT,
- SELECT4_OUTPUT,
- NUM_OUTPUTS
- };
-
- enum LightsIds {
- SELECT1_LIGHT,
- SELECT2_LIGHT,
- SELECT3_LIGHT,
- SELECT4_LIGHT,
- NUM_LIGHTS
- };
-
- bool _registered = false;
- int _baseID = -1;
- int _position = -1;
-
- PgmrX() {
- config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
- configParam<OutputRangeParamQuantity>(CVA1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1A", " V");
- configParam<OutputRangeParamQuantity>(CVB1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1B", " V");
- configParam<OutputRangeParamQuantity>(CVC1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1C", " V");
- configParam<OutputRangeParamQuantity>(CVD1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1D", " V");
- configParam(SELECT1_PARAM, 0.0f, 1.0f, 0.0f, "Select 1");
- configParam<OutputRangeParamQuantity>(CVA2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2A", " V");
- configParam<OutputRangeParamQuantity>(CVB2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2B", " V");
- configParam<OutputRangeParamQuantity>(CVC2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2C", " V");
- configParam<OutputRangeParamQuantity>(CVD2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2D", " V");
- configParam(SELECT2_PARAM, 0.0f, 1.0f, 0.0f, "Select 2");
- configParam<OutputRangeParamQuantity>(CVA3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3A", " V");
- configParam<OutputRangeParamQuantity>(CVB3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3B", " V");
- configParam<OutputRangeParamQuantity>(CVC3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3C", " V");
- configParam<OutputRangeParamQuantity>(CVD3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3D", " V");
- configParam(SELECT3_PARAM, 0.0f, 1.0f, 0.0f, "Select 3");
- configParam<OutputRangeParamQuantity>(CVA4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4A", " V");
- configParam<OutputRangeParamQuantity>(CVB4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4B", " V");
- configParam<OutputRangeParamQuantity>(CVC4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4C", " V");
- configParam<OutputRangeParamQuantity>(CVD4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4D", " V");
- configParam<OutputRangeParamQuantity>(SELECT4_PARAM, 0.0f, 1.0f, 0.0f, "Select 4");
-
- _localSteps[0] = new PgmrStep(params[CVA1_PARAM], params[CVB1_PARAM], params[CVC1_PARAM], params[CVD1_PARAM], lights[SELECT1_LIGHT], params[SELECT1_PARAM], inputs[SELECT1_INPUT], outputs[SELECT1_OUTPUT]);
- _localSteps[1] = new PgmrStep(params[CVA2_PARAM], params[CVB2_PARAM], params[CVC2_PARAM], params[CVD2_PARAM], lights[SELECT2_LIGHT], params[SELECT2_PARAM], inputs[SELECT2_INPUT], outputs[SELECT2_OUTPUT]);
- _localSteps[2] = new PgmrStep(params[CVA3_PARAM], params[CVB3_PARAM], params[CVC3_PARAM], params[CVD3_PARAM], lights[SELECT3_LIGHT], params[SELECT3_PARAM], inputs[SELECT3_INPUT], outputs[SELECT3_OUTPUT]);
- _localSteps[3] = new PgmrStep(params[CVA4_PARAM], params[CVB4_PARAM], params[CVC4_PARAM], params[CVD4_PARAM], lights[SELECT4_LIGHT], params[SELECT4_PARAM], inputs[SELECT4_INPUT], outputs[SELECT4_OUTPUT]);
-
- setBaseModel(modelPgmr);
- setChainableModel(modelPgmrX);
- setExpanderModel(modelPgmrX);
- }
- virtual ~PgmrX() {
- PgmrRegistry::registry().deregisterExpander(_baseID, _position);
- }
-
- void processAlways(const ProcessArgs& args) override;
-};
-
} // namespace bogaudio
diff --git a/src/PgmrX.cpp b/src/PgmrX.cpp
@@ -0,0 +1,137 @@
+
+#include "PgmrX.hpp"
+
+void PgmrX::processAlways(const ProcessArgs& args) {
+ int position = 0;
+ int baseID = 0;
+ if (baseConnected()) {
+ PgmrExpanderMessage* bm = fromBase();
+ baseID = bm->baseID;
+ position = bm->position;
+ _rangeOffset = bm->rangeOffset;
+ _rangeScale = bm->rangeScale;
+ }
+
+ if (_registered && (position <= 0 || position != _position)) {
+ PgmrRegistry::registry().deregisterExpander(_baseID, _position);
+ _registered = false;
+ _baseID = 0;
+ _position = 0;
+ }
+ else if (!_registered && position > 0) {
+ _registered = true;
+ _baseID = baseID;
+ _position = position;
+ PgmrRegistry::registry().registerExpander(_baseID, _position, *this);
+ }
+
+ if (_position < 1) {
+ for (int i = 0; i < 4; ++i) {
+ _localSteps[i]->selectedLight.value = 0.0f;
+ }
+ }
+ if (expanderConnected()) {
+ PgmrExpanderMessage* te = toExpander();
+ te->baseID = _baseID;
+ te->position = _position > 0 ? _position + 1 : 0;
+ te->rangeOffset = _rangeOffset;
+ te->rangeScale = _rangeScale;
+ }
+}
+
+struct PgmrXWidget : ModuleWidget {
+ static constexpr int hp = 12;
+
+ PgmrXWidget(PgmrX* module) {
+ setModule(module);
+ box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
+
+ {
+ SvgPanel *panel = new SvgPanel();
+ panel->box.size = box.size;
+ panel->setBackground(APP->window->loadSvg(asset::plugin(pluginInstance, "res/PgmrX.svg")));
+ addChild(panel);
+ }
+
+ addChild(createWidget<ScrewSilver>(Vec(0, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 0)));
+ addChild(createWidget<ScrewSilver>(Vec(0, 365)));
+ addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365)));
+
+ // generated by svg_widgets.rb
+ auto cva1ParamPosition = Vec(9.5, 40.5);
+ auto cvb1ParamPosition = Vec(9.5, 94.5);
+ auto cvc1ParamPosition = Vec(9.5, 148.5);
+ auto cvd1ParamPosition = Vec(9.5, 202.5);
+ auto select1ParamPosition = Vec(13.5, 267.0);
+ auto cva2ParamPosition = Vec(54.5, 40.5);
+ auto cvb2ParamPosition = Vec(54.5, 94.5);
+ auto cvc2ParamPosition = Vec(54.5, 148.5);
+ auto cvd2ParamPosition = Vec(54.5, 202.5);
+ auto select2ParamPosition = Vec(58.5, 267.0);
+ auto cva3ParamPosition = Vec(99.5, 40.5);
+ auto cvb3ParamPosition = Vec(99.5, 94.5);
+ auto cvc3ParamPosition = Vec(99.5, 148.5);
+ auto cvd3ParamPosition = Vec(99.5, 202.5);
+ auto select3ParamPosition = Vec(103.5, 267.0);
+ auto cva4ParamPosition = Vec(144.5, 40.5);
+ auto cvb4ParamPosition = Vec(144.5, 94.5);
+ auto cvc4ParamPosition = Vec(144.5, 148.5);
+ auto cvd4ParamPosition = Vec(144.5, 202.5);
+ auto select4ParamPosition = Vec(148.5, 267.0);
+
+ auto select1InputPosition = Vec(10.5, 290.0);
+ auto select2InputPosition = Vec(55.5, 290.0);
+ auto select3InputPosition = Vec(100.5, 290.0);
+ auto select4InputPosition = Vec(145.5, 290.0);
+
+ auto select1OutputPosition = Vec(10.5, 330.0);
+ auto select2OutputPosition = Vec(55.5, 330.0);
+ auto select3OutputPosition = Vec(100.5, 330.0);
+ auto select4OutputPosition = Vec(145.5, 330.0);
+
+ auto select1LightPosition = Vec(19.3, 255.0);
+ auto select2LightPosition = Vec(64.3, 255.0);
+ auto select3LightPosition = Vec(109.3, 255.0);
+ auto select4LightPosition = Vec(154.3, 255.0);
+ // end generated by svg_widgets.rb
+
+ addParam(createParam<Knob26>(cva1ParamPosition, module, PgmrX::CVA1_PARAM));
+ addParam(createParam<Knob26>(cvb1ParamPosition, module, PgmrX::CVB1_PARAM));
+ addParam(createParam<Knob26>(cvc1ParamPosition, module, PgmrX::CVC1_PARAM));
+ addParam(createParam<Knob26>(cvd1ParamPosition, module, PgmrX::CVD1_PARAM));
+ addParam(createParam<Button18>(select1ParamPosition, module, PgmrX::SELECT1_PARAM));
+ addParam(createParam<Knob26>(cva2ParamPosition, module, PgmrX::CVA2_PARAM));
+ addParam(createParam<Knob26>(cvb2ParamPosition, module, PgmrX::CVB2_PARAM));
+ addParam(createParam<Knob26>(cvc2ParamPosition, module, PgmrX::CVC2_PARAM));
+ addParam(createParam<Knob26>(cvd2ParamPosition, module, PgmrX::CVD2_PARAM));
+ addParam(createParam<Button18>(select2ParamPosition, module, PgmrX::SELECT2_PARAM));
+ addParam(createParam<Knob26>(cva3ParamPosition, module, PgmrX::CVA3_PARAM));
+ addParam(createParam<Knob26>(cvb3ParamPosition, module, PgmrX::CVB3_PARAM));
+ addParam(createParam<Knob26>(cvc3ParamPosition, module, PgmrX::CVC3_PARAM));
+ addParam(createParam<Knob26>(cvd3ParamPosition, module, PgmrX::CVD3_PARAM));
+ addParam(createParam<Button18>(select3ParamPosition, module, PgmrX::SELECT3_PARAM));
+ addParam(createParam<Knob26>(cva4ParamPosition, module, PgmrX::CVA4_PARAM));
+ addParam(createParam<Knob26>(cvb4ParamPosition, module, PgmrX::CVB4_PARAM));
+ addParam(createParam<Knob26>(cvc4ParamPosition, module, PgmrX::CVC4_PARAM));
+ addParam(createParam<Knob26>(cvd4ParamPosition, module, PgmrX::CVD4_PARAM));
+ addParam(createParam<Button18>(select4ParamPosition, module, PgmrX::SELECT4_PARAM));
+
+ addInput(createInput<Port24>(select1InputPosition, module, PgmrX::SELECT1_INPUT));
+ addInput(createInput<Port24>(select2InputPosition, module, PgmrX::SELECT2_INPUT));
+ addInput(createInput<Port24>(select3InputPosition, module, PgmrX::SELECT3_INPUT));
+ addInput(createInput<Port24>(select4InputPosition, module, PgmrX::SELECT4_INPUT));
+
+ addOutput(createOutput<Port24>(select1OutputPosition, module, PgmrX::SELECT1_OUTPUT));
+ addOutput(createOutput<Port24>(select2OutputPosition, module, PgmrX::SELECT2_OUTPUT));
+ addOutput(createOutput<Port24>(select3OutputPosition, module, PgmrX::SELECT3_OUTPUT));
+ addOutput(createOutput<Port24>(select4OutputPosition, module, PgmrX::SELECT4_OUTPUT));
+
+ addChild(createLight<SmallLight<GreenLight>>(select1LightPosition, module, PgmrX::SELECT1_LIGHT));
+ addChild(createLight<SmallLight<GreenLight>>(select2LightPosition, module, PgmrX::SELECT2_LIGHT));
+ addChild(createLight<SmallLight<GreenLight>>(select3LightPosition, module, PgmrX::SELECT3_LIGHT));
+ addChild(createLight<SmallLight<GreenLight>>(select4LightPosition, module, PgmrX::SELECT4_LIGHT));
+ }
+};
+
+Model* modelPgmrX = createModel<PgmrX, PgmrXWidget>("Bogaudio-PgmrX", "PGMRX", "4-step chainable expander for PGMR", "Sequencer", "Expander", "Polyphonic");
diff --git a/src/PgmrX.hpp b/src/PgmrX.hpp
@@ -0,0 +1,99 @@
+#pragma once
+
+#include "Pgmr_shared.hpp"
+
+namespace bogaudio {
+
+struct PgmrX : ExpanderModule<PgmrExpanderMessage, ExpandableModule<PgmrExpanderMessage, BGModule>>, PgmrBase, OutputRange {
+ enum ParamsIds {
+ CVA1_PARAM,
+ CVB1_PARAM,
+ CVC1_PARAM,
+ CVD1_PARAM,
+ SELECT1_PARAM,
+ CVA2_PARAM,
+ CVB2_PARAM,
+ CVC2_PARAM,
+ CVD2_PARAM,
+ SELECT2_PARAM,
+ CVA3_PARAM,
+ CVB3_PARAM,
+ CVC3_PARAM,
+ CVD3_PARAM,
+ SELECT3_PARAM,
+ CVA4_PARAM,
+ CVB4_PARAM,
+ CVC4_PARAM,
+ CVD4_PARAM,
+ SELECT4_PARAM,
+ NUM_PARAMS
+ };
+
+ enum InputsIds {
+ SELECT1_INPUT,
+ SELECT2_INPUT,
+ SELECT3_INPUT,
+ SELECT4_INPUT,
+ NUM_INPUTS
+ };
+
+ enum OutputsIds {
+ SELECT1_OUTPUT,
+ SELECT2_OUTPUT,
+ SELECT3_OUTPUT,
+ SELECT4_OUTPUT,
+ NUM_OUTPUTS
+ };
+
+ enum LightsIds {
+ SELECT1_LIGHT,
+ SELECT2_LIGHT,
+ SELECT3_LIGHT,
+ SELECT4_LIGHT,
+ NUM_LIGHTS
+ };
+
+ bool _registered = false;
+ int _baseID = -1;
+ int _position = -1;
+
+ PgmrX() {
+ config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
+ configParam<OutputRangeParamQuantity>(CVA1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1A", " V");
+ configParam<OutputRangeParamQuantity>(CVB1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1B", " V");
+ configParam<OutputRangeParamQuantity>(CVC1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1C", " V");
+ configParam<OutputRangeParamQuantity>(CVD1_PARAM, -1.0f, 1.0f, 0.0f, "Step 1D", " V");
+ configParam(SELECT1_PARAM, 0.0f, 1.0f, 0.0f, "Select 1");
+ configParam<OutputRangeParamQuantity>(CVA2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2A", " V");
+ configParam<OutputRangeParamQuantity>(CVB2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2B", " V");
+ configParam<OutputRangeParamQuantity>(CVC2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2C", " V");
+ configParam<OutputRangeParamQuantity>(CVD2_PARAM, -1.0f, 1.0f, 0.0f, "Step 2D", " V");
+ configParam(SELECT2_PARAM, 0.0f, 1.0f, 0.0f, "Select 2");
+ configParam<OutputRangeParamQuantity>(CVA3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3A", " V");
+ configParam<OutputRangeParamQuantity>(CVB3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3B", " V");
+ configParam<OutputRangeParamQuantity>(CVC3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3C", " V");
+ configParam<OutputRangeParamQuantity>(CVD3_PARAM, -1.0f, 1.0f, 0.0f, "Step 3D", " V");
+ configParam(SELECT3_PARAM, 0.0f, 1.0f, 0.0f, "Select 3");
+ configParam<OutputRangeParamQuantity>(CVA4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4A", " V");
+ configParam<OutputRangeParamQuantity>(CVB4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4B", " V");
+ configParam<OutputRangeParamQuantity>(CVC4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4C", " V");
+ configParam<OutputRangeParamQuantity>(CVD4_PARAM, -1.0f, 1.0f, 0.0f, "Step 4D", " V");
+ configParam<OutputRangeParamQuantity>(SELECT4_PARAM, 0.0f, 1.0f, 0.0f, "Select 4");
+
+ _localSteps[0] = new PgmrStep(params[CVA1_PARAM], params[CVB1_PARAM], params[CVC1_PARAM], params[CVD1_PARAM], lights[SELECT1_LIGHT], params[SELECT1_PARAM], inputs[SELECT1_INPUT], outputs[SELECT1_OUTPUT]);
+ _localSteps[1] = new PgmrStep(params[CVA2_PARAM], params[CVB2_PARAM], params[CVC2_PARAM], params[CVD2_PARAM], lights[SELECT2_LIGHT], params[SELECT2_PARAM], inputs[SELECT2_INPUT], outputs[SELECT2_OUTPUT]);
+ _localSteps[2] = new PgmrStep(params[CVA3_PARAM], params[CVB3_PARAM], params[CVC3_PARAM], params[CVD3_PARAM], lights[SELECT3_LIGHT], params[SELECT3_PARAM], inputs[SELECT3_INPUT], outputs[SELECT3_OUTPUT]);
+ _localSteps[3] = new PgmrStep(params[CVA4_PARAM], params[CVB4_PARAM], params[CVC4_PARAM], params[CVD4_PARAM], lights[SELECT4_LIGHT], params[SELECT4_PARAM], inputs[SELECT4_INPUT], outputs[SELECT4_OUTPUT]);
+
+ setBaseModel(modelPgmr);
+ setChainableModel(modelPgmrX);
+ setExpanderModel(modelPgmrX);
+ }
+ virtual ~PgmrX() {
+ PgmrRegistry::registry().deregisterExpander(_baseID, _position);
+ }
+
+ void processAlways(const ProcessArgs& args) override;
+};
+
+} // namespace bogaudio
diff --git a/src/Pgmr_shared.cpp b/src/Pgmr_shared.cpp
@@ -0,0 +1,79 @@
+
+#include "Pgmr_shared.hpp"
+#include "Pgmr.hpp"
+#include "PgmrX.hpp"
+
+void PgmrStep::reset() {
+ for (int c = 0; c < BGModule::maxChannels; ++c) {
+ triggers[c].reset();
+ pulseGens[c].process(1000.0f);
+ }
+}
+
+
+PgmrRegistry::Base::Base(Pgmr& b) : module(b) {
+ std::copy(b._localSteps, b._localSteps + 4, std::back_inserter(steps));
+}
+
+int PgmrRegistry::registerBase(Pgmr& b) {
+ std::lock_guard<std::mutex> lock(_lock);
+
+ int id = _nextID;
+ ++_nextID;
+ auto p = _bases.emplace(id, Base(b));
+ b.setSteps(p.first->second.steps);
+ return id;
+}
+
+void PgmrRegistry::deregisterBase(int id) {
+ std::lock_guard<std::mutex> lock(_lock);
+ _bases.erase(id);
+}
+
+void PgmrRegistry::registerExpander(int baseID, int position, PgmrX& x) {
+ std::lock_guard<std::mutex> lock(_lock);
+
+ assert(position > 0);
+ auto base = _bases.find(baseID);
+ if (base != _bases.end()) {
+ int i = 4 * position;
+ if (i < (int)base->second.steps.size()) {
+ assert(!base->second.steps[i]);
+ std::copy(x._localSteps, x._localSteps + 4, base->second.steps.begin() + i);
+ }
+ else {
+ base->second.steps.resize(i + 4, NULL);
+ std::copy(x._localSteps, x._localSteps + 4, base->second.steps.begin() + i);
+ }
+ for (auto i = base->second.steps.begin(), n = base->second.steps.end(); i != n; ++i) {
+ if (!*i) {
+ return;
+ }
+ }
+ base->second.module.setSteps(base->second.steps);
+ }
+}
+
+void PgmrRegistry::deregisterExpander(int baseID, int position) {
+ std::lock_guard<std::mutex> lock(_lock);
+
+ auto base = _bases.find(baseID);
+ if (base != _bases.end()) {
+ int n = 4 * position;
+ if (n < (int)base->second.steps.size()) {
+ int i = 0;
+ for (; i < n; ++i) {
+ if (!base->second.steps[i]) {
+ break;
+ }
+ }
+ base->second.steps.resize(i);
+ base->second.module.setSteps(base->second.steps);
+ }
+ }
+}
+
+PgmrRegistry& PgmrRegistry::registry() {
+ static PgmrRegistry instance;
+ return instance;
+}
diff --git a/src/Pgmr_shared.hpp b/src/Pgmr_shared.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <mutex>
+#include <unordered_map>
+
+#include "bogaudio.hpp"
+#include "addressable_sequence.hpp"
+#include "expanders.hpp"
+
+extern Model* modelPgmr;
+extern Model* modelPgmrX;
+
+namespace bogaudio {
+
+struct PgmrExpanderMessage : ExpanderMessage {
+ int baseID = -1;
+ int position = -1;
+ float rangeOffset = 0.0f;
+ float rangeScale = 10.0f;
+};
+
+struct PgmrStep {
+ Param& aParam;
+ Param& bParam;
+ Param& cParam;
+ Param& dParam;
+ Light& selectedLight;
+ Param& selectParam;
+ Input& selectInput;
+ Output& selectedOutput;
+
+ Trigger triggers[BGModule::maxChannels];
+ rack::dsp::PulseGenerator pulseGens[BGModule::maxChannels];
+ float lightSum = 0.0f;
+
+ PgmrStep(
+ Param& aParam,
+ Param& bParam,
+ Param& cParam,
+ Param& dParam,
+ Light& selectedLight,
+ Param& selectParam,
+ Input& selectInput,
+ Output& selectedOutput
+ )
+ : aParam(aParam)
+ , bParam(bParam)
+ , cParam(cParam)
+ , dParam(dParam)
+ , selectedLight(selectedLight)
+ , selectParam(selectParam)
+ , selectInput(selectInput)
+ , selectedOutput(selectedOutput)
+ {
+ }
+
+ void reset();
+};
+
+struct PgmrBase {
+ PgmrStep* _localSteps[4] {};
+
+ virtual ~PgmrBase() {
+ for (int i = 0; i < 4; ++i) {
+ if (_localSteps[i]) {
+ delete _localSteps[i];
+ }
+ }
+ }
+};
+
+struct Pgmr;
+struct PgmrX;
+
+struct PgmrRegistry {
+private:
+ struct Base {
+ Pgmr& module;
+ std::vector<PgmrStep*> steps;
+
+ Base(Pgmr& b);
+ };
+
+ std::mutex _lock;
+ int _nextID = 1;
+ std::unordered_map<int, Base> _bases;
+
+public:
+ int registerBase(Pgmr& b);
+ void deregisterBase(int id);
+ void registerExpander(int baseID, int position, PgmrX& x);
+ void deregisterExpander(int baseID, int position);
+
+ static PgmrRegistry& registry();
+};
+
+} // namespace bogaudio
diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp
@@ -44,7 +44,9 @@
#include "Mix1.hpp"
#include "Mix2.hpp"
#include "Mix4.hpp"
+#include "Mix4x.hpp"
#include "Mix8.hpp"
+#include "Mix8x.hpp"
#include "Mono.hpp"
#include "Mult.hpp"
#include "Mumix.hpp"
@@ -58,6 +60,7 @@
#include "PEQ6.hpp"
#include "PEQ14.hpp"
#include "Pgmr.hpp"
+#include "PgmrX.hpp"
#include "PolyCon8.hpp"
#include "PolyCon16.hpp"
#include "PolyOff8.hpp"