commit c2a506f328a8be5e07154f623e1c75e9925b5db3
parent 8e982f462c4117f84794cbf6a13740992ff17d92
Author: Matt Demanett <matt@demanett.net>
Date: Thu, 27 Jan 2022 21:41:08 -0500
MIX2: add poly-spread feature, as on MIX4/8. #188
Diffstat:
3 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/README-prerelease.md b/README-prerelease.md
@@ -673,9 +673,9 @@ _When <a href="#bypassing">bypassed</a>:_ passes IN unmodified to OUT.
A stereo version of MIX1. The left input is normalled to the right.
-_Polyphony:_ <a href="#polyphony">polyphonic</a>, with channels defined by the L input.
+_Polyphony:_ <a href="#polyphony">polyphonic</a>, with channels defined by the L input. However, as on MIX8 there is a poly spread feature -- if this is enabled, the module becomes monophonic, and will get the left and right inputs from a pair of polyphonic channels (channels 1 and 2, 3 and 4, etc) on the input L.
-_When <a href="#bypassing">bypassed</a>:_ passes left and right inputs unmodified to the corresponding outputs; left is passed to right if right is unpatched.
+_When <a href="#bypassing">bypassed</a>:_ passes left and right inputs unmodified to the corresponding outputs; left is passed to right if the right input is unpatched.
#### <a name="umix"></a> UMIX
diff --git a/src/Mix2.cpp b/src/Mix2.cpp
@@ -1,6 +1,20 @@
#include "Mix2.hpp"
+#define POLY_OFFSET "poly_channel_offset"
+
+json_t* Mix2::saveToJson(json_t* root) {
+ json_object_set_new(root, POLY_OFFSET, json_integer(_polyChannelOffset));
+ return root;
+}
+
+void Mix2::loadFromJson(json_t* root) {
+ json_t* o = json_object_get(root, POLY_OFFSET);
+ if (o) {
+ _polyChannelOffset = json_integer_value(o);
+ }
+}
+
void Mix2::sampleRateChange() {
float sr = APP->engine->getSampleRate();
for (int c = 0; c < _channels; ++c) {
@@ -14,6 +28,9 @@ bool Mix2::active() {
}
int Mix2::channels() {
+ if (_polyChannelOffset >= 0) {
+ return 1;
+ }
return inputs[L_INPUT].getChannels();
}
@@ -39,7 +56,13 @@ void Mix2::processAlways(const ProcessArgs& args) {
void Mix2::processChannel(const ProcessArgs& args, int c) {
Engine& e = *_engines[c];
- float left = inputs[L_INPUT].getVoltage(c);
+ float left = 0.0f;
+ if (_polyChannelOffset >= 0) {
+ left = inputs[L_INPUT].getPolyVoltage(_polyChannelOffset);
+ }
+ else {
+ left = inputs[L_INPUT].getVoltage(c);
+ }
e.left.next(left, false, c, _linearCV);
_leftRmsSum += e.left.rms;
outputs[L_OUTPUT].setChannels(_channels);
@@ -49,6 +72,9 @@ void Mix2::processChannel(const ProcessArgs& args, int c) {
if (inputs[R_INPUT].isConnected()) {
right = inputs[R_INPUT].getVoltage(c);
}
+ else if (_polyChannelOffset >= 0) {
+ right = inputs[L_INPUT].getPolyVoltage(_polyChannelOffset + 1);
+ }
e.right.next(right, false, c, _linearCV);
_rightRmsSum += e.right.rms;
outputs[R_OUTPUT].setChannels(_channels);
@@ -111,7 +137,24 @@ struct Mix2Widget : LinearCVMixerWidget {
addInput(createInput<Port24>(rInputPosition, module, Mix2::R_INPUT));
addOutput(createOutput<Port24>(lOutputPosition, module, Mix2::L_OUTPUT));
- addOutput(createOutput<Port24>(rOutputPosition, module, Mix2::R_OUTPUT)); }
+ addOutput(createOutput<Port24>(rOutputPosition, module, Mix2::R_OUTPUT));
+ }
+
+ void contextMenu(Menu* menu) override {
+ auto m = dynamic_cast<Mix2*>(module);
+ assert(m);
+ OptionsMenuItem* mi = new OptionsMenuItem("Input 1 poly spread");
+ mi->addItem(OptionMenuItem("None (normal polyphonic)", [m]() { return m->_polyChannelOffset == -1; }, [m]() { m->_polyChannelOffset = -1; }));
+ mi->addItem(OptionMenuItem("Channels 1-2", [m]() { return m->_polyChannelOffset == 0; }, [m]() { m->_polyChannelOffset = 0; }));
+ mi->addItem(OptionMenuItem("Channels 3-4", [m]() { return m->_polyChannelOffset == 2; }, [m]() { m->_polyChannelOffset = 2; }));
+ mi->addItem(OptionMenuItem("Channels 5-6", [m]() { return m->_polyChannelOffset == 4; }, [m]() { m->_polyChannelOffset = 4; }));
+ mi->addItem(OptionMenuItem("Channels 7-8", [m]() { return m->_polyChannelOffset == 6; }, [m]() { m->_polyChannelOffset = 6; }));
+ mi->addItem(OptionMenuItem("Channels 9-10", [m]() { return m->_polyChannelOffset == 8; }, [m]() { m->_polyChannelOffset = 8; }));
+ mi->addItem(OptionMenuItem("Channels 11-12", [m]() { return m->_polyChannelOffset == 10; }, [m]() { m->_polyChannelOffset = 10; }));
+ mi->addItem(OptionMenuItem("Channels 13-14", [m]() { return m->_polyChannelOffset == 12; }, [m]() { m->_polyChannelOffset = 12; }));
+ mi->addItem(OptionMenuItem("Channels 15-16", [m]() { return m->_polyChannelOffset == 14; }, [m]() { m->_polyChannelOffset = 14; }));
+ OptionsMenuItem::addToMenu(mi, menu);
+ }
};
Model* modelMix2 = createModel<Mix2, Mix2Widget>("Bogaudio-Mix2", "MIX2", "Stereo fader/amplifier with CV-controllable mute", "VCA", "Polyphonic");
diff --git a/src/Mix2.hpp b/src/Mix2.hpp
@@ -55,6 +55,7 @@ struct Mix2 : LinearCVMixerModule {
float _leftRms = 0.0f;
float _rightRmsSum = 0.0f;
float _rightRms = 0.0f;
+ int _polyChannelOffset = -1;
Mix2() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
@@ -70,6 +71,8 @@ struct Mix2 : LinearCVMixerModule {
configOutput(R_OUTPUT, "Right signal");
}
+ json_t* saveToJson(json_t* root) override;
+ void loadFromJson(json_t* root) override;
void sampleRateChange() override;
bool active() override;
int channels() override;