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:
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