BogaudioModules

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

commit b6e8be4b86475050344a62ffbf1be8254a0fbcb4
parent 7b9781d54d2dbfa191ac4a226fb65794ffd0b170
Author: Matt Demanett <matt@demanett.net>
Date:   Wed, 25 Mar 2020 22:27:00 -0400

Base classes and test modules for expanders.

Diffstat:
Ares-src/TestExpanderBase-src.svg | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares-src/TestExpanderExtension-src.svg | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/TestExpanderBase.svg | 0
Ares/TestExpanderExtension.svg | 0
Asrc/TestExpander.cpp | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/TestExpander.hpp | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/bogaudio.cpp | 3+++
Asrc/expanders.hpp | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/module.hpp | 6+++---
9 files changed, 425 insertions(+), 3 deletions(-)

diff --git a/res-src/TestExpanderBase-src.svg b/res-src/TestExpanderBase-src.svg @@ -0,0 +1,77 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="45" + height="380" + viewBox="0 0 45 380" +> + <style> + text { + fill: #333; + font-family: 'Roboto', sans-serif; + font-weight: bold; + } + text.title { + font-family: 'Comfortaa', sans-serif; + font-weight: normal; + } + text.brand { + font-family: 'Audiowide', sans-serif; + font-weight: bold; + } + </style> + + <defs> + <symbol id="input" viewBox="0 0 24px 24px"> + <g transform="translate(12 12)"> + <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#0f0" fill="#0f0" /> + <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#0f0" fill="none" /> + </g> + </symbol> + + <symbol id="output" viewBox="0 0 24px 24px"> + <g transform="translate(12 12)"> + <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#f00" fill="#f00" /> + <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#f00" fill="none" /> + </g> + </symbol> + + <symbol id="light-small" viewBox="0 0 6.4px 6.4px"> + <rect width="6.4" height="6.4" fill="#0f0" /> + </symbol> + </defs> + + <rect width="100%" height="100%" fill="#ddd" /> + <polyline points="1,1 44,1 44,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 45,0 45,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <g transform="rotate(-90) translate(-376 13)"> + <text class="title" font-size="7pt" letter-spacing="2.5px">TEB</text> + <g transform="translate(0 12)"> + <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text> + <rect width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)" /> + </g> + </g> + + <g transform="translate(0 245)"> + <use id="COM_LIGHT" xlink:href="#light-small" transform="translate(10 0.5)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(19 6)">COM</text> + </g> + + <g transform="translate(0 260)"> + <g transform="translate(5.5 0)"> + <rect width="34" height="10" fill="#fafafa" transform="translate(0 28)" /> + <rect width="34" height="35" rx="5" fill="#fafafa" /> + <use id="IN_INPUT" xlink:href="#input" transform="translate(5 3)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(12.5 35)">IN</text> + </g> + <g transform="translate(5.5 41)"> + <rect width="34" height="10" fill="#bbb" transform="translate(0 -3)" /> + <rect width="34" height="35" rx="5" fill="#bbb" /> + <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text> + </g> + </g> +</svg> diff --git a/res-src/TestExpanderExtension-src.svg b/res-src/TestExpanderExtension-src.svg @@ -0,0 +1,63 @@ +<svg + version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="45" + height="380" + viewBox="0 0 45 380" +> + <style> + text { + fill: #333; + font-family: 'Roboto', sans-serif; + font-weight: bold; + } + text.title { + font-family: 'Comfortaa', sans-serif; + font-weight: normal; + } + text.brand { + font-family: 'Audiowide', sans-serif; + font-weight: bold; + } + </style> + + <defs> + <symbol id="output" viewBox="0 0 24px 24px"> + <g transform="translate(12 12)"> + <circle cx="0" cy="0" r="5" stroke-width="1" stroke="#f00" fill="#f00" /> + <circle cx="0" cy="0" r="10.5" stroke-width="3" stroke="#f00" fill="none" /> + </g> + </symbol> + + <symbol id="light-small" viewBox="0 0 6.4px 6.4px"> + <rect width="6.4" height="6.4" fill="#0f0" /> + </symbol> + </defs> + + <rect width="100%" height="100%" fill="#ddd" /> + <polyline points="1,1 44,1 44,379 1,379 1,1" stroke="#e4e4e4" stroke-width="0.5" fill="none" /> + <polyline points="0.5,0.5 44.5,0.5 44.5,379.5 0.5,379.5 0.5,0.5" stroke="#ebebeb" stroke-width="0.8" fill="none" /> + <polyline points="0,0 45,0 45,380 0,380 0,0" stroke="#f2f2f2" stroke-width="1" fill="none" /> + + <g transform="rotate(-90) translate(-376 13)"> + <text class="title" font-size="7pt" letter-spacing="2.5px">TEE</text> + <g transform="translate(0 12)"> + <text class="brand" font-size="7pt" letter-spacing="2px">BGA</text> + <rect width="3.0" height="3" fill="#ddd" transform="translate(11.5 -5)" /> + </g> + </g> + + <g transform="translate(0 280)"> + <use id="COM_LIGHT" xlink:href="#light-small" transform="translate(10 0.5)" /> + <text font-size="5pt" letter-spacing="1px" transform="translate(19 6)">COM</text> + </g> + + <g transform="translate(0 260)"> + <g transform="translate(5.5 41)"> + <rect width="34" height="38" rx="5" fill="#bbb" transform="translate(0 -3)"/> + <use id="OUT_OUTPUT" xlink:href="#output" transform="translate(5 0)" /> + <text font-size="5pt" letter-spacing="2px" transform="translate(8.3 32)">OUT</text> + </g> + </g> +</svg> diff --git a/res/TestExpanderBase.svg b/res/TestExpanderBase.svg Binary files differ. diff --git a/res/TestExpanderExtension.svg b/res/TestExpanderExtension.svg Binary files differ. diff --git a/src/TestExpander.cpp b/src/TestExpander.cpp @@ -0,0 +1,104 @@ + +#include "TestExpander.hpp" + +int TestExpanderBase::channels() { + return inputs[IN_INPUT].getChannels(); +} + +void TestExpanderBase::processAll(const ProcessArgs& args) { + outputs[OUT_OUTPUT].setChannels(_channels); + lights[COM_LIGHT].value = connected(); +} + +void TestExpanderBase::processChannel(const ProcessArgs& args, int c) { + if (connected()) { + toExpander()->sample[c] = inputs[IN_INPUT].getPolyVoltage(c); + outputs[OUT_OUTPUT].setVoltage(fromExpander()->sample[c], c); + } + else { + outputs[OUT_OUTPUT].setVoltage(inputs[IN_INPUT].getPolyVoltage(c), c); + } +} + +struct TestExpanderBaseWidget : ModuleWidget { + static constexpr int hp = 3; + + TestExpanderBaseWidget(TestExpanderBase* 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/TestExpanderBase.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto inInputPosition = Vec(10.5, 263.0); + + auto outOutputPosition = Vec(10.5, 301.0); + + auto comLightPosition = Vec(10.0, 245.5); + // end generated by svg_widgets.rb + + addInput(createInput<Port24>(inInputPosition, module, TestExpanderBase::IN_INPUT)); + + addOutput(createOutput<Port24>(outOutputPosition, module, TestExpanderBase::OUT_OUTPUT)); + + addChild(createLight<SmallLight<GreenLight>>(comLightPosition, module, TestExpanderBase::COM_LIGHT)); + } +}; + +Model* modelTestExpanderBase = createModel<TestExpanderBase, TestExpanderBaseWidget>("Bogaudio-TestExpanderBase", "TEB", "expanders test base module"); + + +void TestExpanderExtension::processAll(const ProcessArgs& args) { + outputs[OUT_OUTPUT].setChannels(_channels); + lights[COM_LIGHT].value = connected(); +} + +void TestExpanderExtension::processChannel(const ProcessArgs& args, int c) { + if (connected()) { + float sample = fromBase()->sample[c]; + toBase()->sample[c] = -sample; + outputs[OUT_OUTPUT].setVoltage(sample, c); + } + else { + outputs[OUT_OUTPUT].setVoltage(0.0f, c); + } +} + +struct TestExpanderExtensionWidget : ModuleWidget { + static constexpr int hp = 3; + + TestExpanderExtensionWidget(TestExpanderExtension* 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/TestExpanderExtension.svg"))); + addChild(panel); + } + + addChild(createWidget<ScrewSilver>(Vec(0, 0))); + addChild(createWidget<ScrewSilver>(Vec(box.size.x - 15, 365))); + + // generated by svg_widgets.rb + auto outOutputPosition = Vec(10.5, 301.0); + + auto comLightPosition = Vec(10.0, 280.5); + // end generated by svg_widgets.rb + + addOutput(createOutput<Port24>(outOutputPosition, module, TestExpanderExtension::OUT_OUTPUT)); + + addChild(createLight<SmallLight<GreenLight>>(comLightPosition, module, TestExpanderExtension::COM_LIGHT)); + } +}; + +Model* modelTestExpanderExtension = createModel<TestExpanderExtension, TestExpanderExtensionWidget>("Bogaudio-TestExpanderExtension", "TEE", "expanders test expander module"); diff --git a/src/TestExpander.hpp b/src/TestExpander.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include "bogaudio.hpp" +#include "expanders.hpp" + +extern Model* modelTestExpanderBase; +extern Model* modelTestExpanderExtension; + +namespace bogaudio { + +struct TestExpanderMessage : MessageBase { + int channels = 0; + float sample[BGModule::maxChannels] {}; +}; + +struct TestExpanderExtension; + +struct TestExpanderBase : ExpandableModule<TestExpanderMessage, TestExpanderExtension> { + enum ParamsIds { + NUM_PARAMS + }; + + enum InputsIds { + IN_INPUT, + NUM_INPUTS + }; + + enum OutputsIds { + OUT_OUTPUT, + NUM_OUTPUTS + }; + + enum LightsIds { + COM_LIGHT, + NUM_LIGHTS + }; + + TestExpanderBase() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + } + + int channels() override; + void processAll(const ProcessArgs& args) override; + void processChannel(const ProcessArgs& args, int c) override; +}; + +struct TestExpanderExtension : ExpanderModule<TestExpanderMessage, TestExpanderBase> { + enum ParamsIds { + NUM_PARAMS + }; + + enum InputsIds { + NUM_INPUTS + }; + + enum OutputsIds { + OUT_OUTPUT, + NUM_OUTPUTS + }; + + enum LightsIds { + COM_LIGHT, + NUM_LIGHTS + }; + + TestExpanderExtension() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + } + + void processAll(const ProcessArgs& args) override; + void processChannel(const ProcessArgs& args, int c) override; +}; + +} // namespace bogaudio diff --git a/src/bogaudio.cpp b/src/bogaudio.cpp @@ -81,6 +81,7 @@ #include "Test.hpp" #include "Test2.hpp" +#include "TestExpander.hpp" #include "TestVCF.hpp" #include "template_panels.hpp" @@ -188,6 +189,8 @@ void init(rack::Plugin *p) { #ifdef TEST p->addModel(modelTest); p->addModel(modelTest2); + p->addModel(modelTestExpanderBase); + p->addModel(modelTestExpanderExtension); p->addModel(modelTestVCF); p->addModel(modelThreeHP); diff --git a/src/expanders.hpp b/src/expanders.hpp @@ -0,0 +1,101 @@ +#pragma once + +#include <type_traits> + +#include "rack.hpp" +#include "module.hpp" + +using namespace rack; + +namespace bogaudio { + +struct MessageBase { + int channels = 0; + + virtual ~MessageBase() {} +}; + +template<class MSG, class EM> +struct ExpandableModule : BGModule { + MSG _messages[2] {}; + + ExpandableModule() { + static_assert(std::is_base_of<MessageBase, MSG>::value, "type parameter MSG must derive from MessageBase"); + + rightExpander.producerMessage = &_messages[0]; + rightExpander.consumerMessage = &_messages[1]; + } + + inline bool connected() { + return rightExpander.module && dynamic_cast<EM*>(rightExpander.module); + } + + inline MSG* toExpander() { + assert(connected()); + MSG* m = (MSG*)rightExpander.module->leftExpander.producerMessage; + assert(m); + m->channels = _channels; + return m; + } + + inline MSG* fromExpander() { + assert(connected()); + MSG* m = (MSG*)rightExpander.consumerMessage; + assert(m); + return m; + } + + void process(const ProcessArgs& args) override { + BGModule::process(args); + if (rightExpander.module) { + rightExpander.module->leftExpander.messageFlipRequested = true; + } + } +}; + +// An expander must be to the right of the expanded module to work. +template<class MSG, class BM> +struct ExpanderModule : BGModule { + MSG _messages[2] {}; + + ExpanderModule() { + static_assert(std::is_base_of<MessageBase, MSG>::value, "type parameter MSG must derive from MessageBase"); + + leftExpander.producerMessage = &_messages[0]; + leftExpander.consumerMessage = &_messages[1]; + } + + inline bool connected() { + return leftExpander.module && dynamic_cast<BM*>(leftExpander.module); + } + + inline MSG* fromBase() { + assert(connected()); + MSG* m = (MSG*)leftExpander.consumerMessage; + assert(m); + return m; + } + + inline MSG* toBase() { + assert(connected()); + MSG* m = (MSG*)leftExpander.module->rightExpander.producerMessage; + assert(m); + return m; + } + + int channels() override final { + if (connected()) { + return fromBase()->channels; + } + return 1; + } + + void process(const ProcessArgs& args) override { + BGModule::process(args); + if (leftExpander.module) { + leftExpander.module->rightExpander.messageFlipRequested = true; + } + } +}; + +} // namespace bogaudio diff --git a/src/module.hpp b/src/module.hpp @@ -22,9 +22,9 @@ struct BGModule : Module { } } - void onReset() override final; - void onSampleRateChange() override final; - void process(const ProcessArgs& args) override final; + void onReset() override; + void onSampleRateChange() override; + void process(const ProcessArgs& args) override; virtual void reset() {} virtual void sampleRateChange() {}