BogaudioModules

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

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:
MREADME-prerelease.md | 4++--
Msrc/Mix2.cpp | 47+++++++++++++++++++++++++++++++++++++++++++++--
Msrc/Mix2.hpp | 3+++
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;