BogaudioModules

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

commit 2593e2395d62ad049e25d2f81ae2de9bc6a598e2
parent 4c69b03e5b88bc4ecef69a6b5b8d8be5ec47103c
Author: Matt Demanett <matt@demanett.net>
Date:   Tue,  3 Dec 2019 01:02:27 -0500

Add stage lights to the FM-OP envelope.

Diffstat:
Mres-src/FMOp-src.svg | 10+++++++++-
Mres/FMOp.svg | 0
Msrc/FMOp.cpp | 26++++++++++++++++++++++++++
Msrc/FMOp.hpp | 16+++++++++++++++-
4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/res-src/FMOp-src.svg b/res-src/FMOp-src.svg @@ -187,6 +187,10 @@ <symbol id="light-small" viewBox="0 0 6.4px 6.4px"> <rect width="6.4" height="6.4" fill="#0f0" /> </symbol> + + <symbol id="light-tiny" viewBox="0 0 1.1px 1.1px"> + <rect width="3.2" height="3.2" fill="#0f0" /> + </symbol> </defs> <rect width="100%" height="100%" fill="#ddd" /> @@ -197,7 +201,7 @@ <!-- <rect width="35" height="20" fill="#0f0" transform="translate(0 0)" /> --> <!-- <rect width="35" height="20" fill="#0f0" transform="translate(115 0)" /> --> - <!-- <polyline points="0,50 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(140 0)" /> --> + <!-- <polyline points="0,50 0,380" stroke="#0f0" stroke-width="1" fill="none" transform="translate(120 0)" /> --> <text class="title" x="39" y="19" font-size="12pt" letter-spacing="4px">FM-OP</text> <g transform="translate(35.5 374)"> @@ -226,6 +230,7 @@ <use id="ATTACK_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" /> <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> --> <use xlink:href="#knobguide-time" transform="translate(10.5 -9.5)" /> + <use id="ATTACK_LIGHT" xlink:href="#light-tiny" transform="translate(31.5 29)" /> </g> <g transform="translate(87 139)"> <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> --> @@ -233,6 +238,7 @@ <use id="DECAY_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" /> <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> --> <use xlink:href="#knobguide-time" transform="translate(10.5 -9.5)" /> + <use id="DECAY_LIGHT" xlink:href="#light-tiny" transform="translate(31.5 29)" /> </g> <g transform="translate(87 184)"> <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> --> @@ -240,6 +246,7 @@ <use id="SUSTAIN_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" /> <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> --> <use xlink:href="#knobguide-linear" transform="translate(10.5 -9.5)" /> + <use id="SUSTAIN_LIGHT" xlink:href="#light-tiny" transform="translate(31.5 29)" /> </g> <g transform="translate(87 229)"> <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> --> @@ -247,6 +254,7 @@ <use id="RELEASE_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" /> <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> --> <use xlink:href="#knobguide-time" transform="translate(10.5 -9.5)" /> + <use id="RELEASE_LIGHT" xlink:href="#light-tiny" transform="translate(31.5 29)" /> </g> <!-- <rect width="70" height="8" fill="#ff0" transform="translate(80 126)" /> --> diff --git a/res/FMOp.svg b/res/FMOp.svg Binary files differ. diff --git a/src/FMOp.cpp b/src/FMOp.cpp @@ -163,6 +163,10 @@ void FMOp::modulateChannel(int c) { } } +void FMOp::always(const ProcessArgs& args) { + _attackLightSum = _decayLightSum = _sustainLightSum = _releaseLightSum = 0; +} + void FMOp::processChannel(const ProcessArgs& args, int c) { Engine& e = *_engines[c]; @@ -242,6 +246,18 @@ void FMOp::processChannel(const ProcessArgs& args, int c) { outputs[AUDIO_OUTPUT].setChannels(_channels); outputs[AUDIO_OUTPUT].setVoltage(e.feedbackDelayedSample = amplitude * sample, c); + + _attackLightSum += e.envelope.isStage(dsp::ADSR::ATTACK_STAGE); + _decayLightSum += e.envelope.isStage(dsp::ADSR::DECAY_STAGE); + _sustainLightSum += e.envelope.isStage(dsp::ADSR::SUSTAIN_STAGE); + _releaseLightSum += e.envelope.isStage(dsp::ADSR::RELEASE_STAGE); +} + +void FMOp::postProcess(const ProcessArgs& args) { + lights[ATTACK_LIGHT].value = _attackLightSum / (float)_channels; + lights[DECAY_LIGHT].value = _decayLightSum / (float)_channels; + lights[SUSTAIN_LIGHT].value = _sustainLightSum / (float)_channels; + lights[RELEASE_LIGHT].value = _releaseLightSum / (float)_channels; } struct FMOpWidget : ModuleWidget { @@ -286,6 +302,11 @@ struct FMOpWidget : ModuleWidget { auto gateInputPosition = Vec(79.0, 318.0); auto audioOutputPosition = Vec(111.0, 318.0); + + auto attackLightPosition = Vec(118.5, 123.0); + auto decayLightPosition = Vec(118.5, 168.0); + auto sustainLightPosition = Vec(118.5, 213.0); + auto releaseLightPosition = Vec(118.5, 258.0); // end generated by svg_widgets.rb addParam(createParam<Knob38>(ratioParamPosition, module, FMOp::RATIO_PARAM)); @@ -310,6 +331,11 @@ struct FMOpWidget : ModuleWidget { addInput(createInput<Port24>(fmInputPosition, module, FMOp::FM_INPUT)); addOutput(createOutput<Port24>(audioOutputPosition, module, FMOp::AUDIO_OUTPUT)); + + addChild(createLight<TinyLight<GreenLight>>(attackLightPosition, module, FMOp::ATTACK_LIGHT)); + addChild(createLight<TinyLight<GreenLight>>(decayLightPosition, module, FMOp::DECAY_LIGHT)); + addChild(createLight<TinyLight<GreenLight>>(sustainLightPosition, module, FMOp::SUSTAIN_LIGHT)); + addChild(createLight<TinyLight<GreenLight>>(releaseLightPosition, module, FMOp::RELEASE_LIGHT)); } void appendContextMenu(Menu* menu) override { diff --git a/src/FMOp.hpp b/src/FMOp.hpp @@ -45,6 +45,14 @@ struct FMOp : BGModule { NUM_OUTPUTS }; + enum LightsIds { + ATTACK_LIGHT, + DECAY_LIGHT, + SUSTAIN_LIGHT, + RELEASE_LIGHT, + NUM_LIGHTS + }; + static constexpr float amplitude = 5.0f; static constexpr int oversample = 8; static constexpr float oversampleMixIncrement = 0.01f; @@ -79,6 +87,10 @@ struct FMOp : BGModule { bool _levelEnvelopeOn = false; bool _feedbackEnvelopeOn = false; bool _depthEnvelopeOn = false; + int _attackLightSum; + int _decayLightSum; + int _sustainLightSum; + int _releaseLightSum; Engine* _engines[maxChannels] {}; struct RatioParamQuantity : ParamQuantity { @@ -91,7 +103,7 @@ struct FMOp : BGModule { }; FMOp() { - config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); configParam<RatioParamQuantity>(RATIO_PARAM, -1.0f, 1.0f, 0.0f, "Frequency ratio"); configParam(FINE_PARAM, -1.0f, 1.0f, 0.0f, "Fine tune", " cents", 0.0f, 100.0f); configParam<EnvelopeSegmentParamQuantity>(ATTACK_PARAM, 0.0f, 1.0f, 0.141421f, "Attack", " s"); @@ -116,7 +128,9 @@ struct FMOp : BGModule { void removeChannel(int c) override; void modulate() override; void modulateChannel(int c) override; + void always(const ProcessArgs& args) override; void processChannel(const ProcessArgs& args, int c) override; + void postProcess(const ProcessArgs& args) override; }; } // namespace bogaudio