commit 2bc9424db8f4bd38b0e04b605847859a00494ef2
parent 1188f4bd42cdcff5dfa5cfc4316cc24ef92d383d
Author: Matt Demanett <matt@demanett.net>
Date: Sun, 22 Apr 2018 22:21:16 -0400
FM-OP: add envelope control over depth; update layout.
Diffstat:
4 files changed, 92 insertions(+), 69 deletions(-)
diff --git a/res-src/FMOp-src.svg b/res-src/FMOp-src.svg
@@ -221,71 +221,79 @@
<use xlink:href="#knobguide-centertick" transform="translate(90 20)" />
</g>
- <g transform="translate(87 90)">
- <g transform="translate(0 0)">
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">ATT</text>
- <use id="ATTACK_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
- <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> -->
- </g>
+ <!-- <g transform="translate(87 90)"> -->
+ <g transform="translate(87 94)">
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">ATT</text>
+ <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)" />
+ </g>
+ <g transform="translate(87 139)">
+ <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">DEC</text>
+ <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)" />
+ </g>
+ <g transform="translate(87 184)">
+ <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">SUS</text>
+ <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-time" transform="translate(10.5 -9.5)" />
+ </g>
+ <g transform="translate(87 229)">
+ <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">REL</text>
+ <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)" />
- <g transform="translate(0 42)">
- <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">DEC</text>
- <use id="DECAY_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
- <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> -->
- </g>
- <use xlink:href="#knobguide-time" transform="translate(10.5 32.5)" />
- <g transform="translate(0 84)">
- <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">SUS</text>
- <use id="SUSTAIN_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
- <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> -->
- </g>
- <use xlink:href="#knobguide-linear" transform="translate(10.5 74.5)" />
- <g transform="translate(0 126)">
- <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(-140 -10)" /> -->
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 25) rotate(270)">REL</text>
- <use id="RELEASE_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
- <!-- <rect width="30" height="18" fill="#0f0" transform="translate(20 26)" /> -->
- </g>
- <use xlink:href="#knobguide-time" transform="translate(10.5 116.5)" />
</g>
- <g transform="translate(16 113)">
- <g transform="translate(0 0)">
- <text font-size="8pt" letter-spacing="1px" transform="translate(8 33) rotate(270)">DEPTH</text>
- <use id="DEPTH_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
+ <!-- <rect width="70" height="8" fill="#ff0" transform="translate(80 126)" /> -->
+ <!-- <rect width="70" height="8" fill="#ff0" transform="translate(80 171)" /> -->
+ <!-- <rect width="70" height="8" fill="#ff0" transform="translate(80 216)" /> -->
+ <!-- <rect width="70" height="8" fill="#ff0" transform="translate(80 261)" /> -->
+
+ <g transform="translate(16 106)">
+ <text font-size="8pt" letter-spacing="1px" transform="translate(8 38) rotate(270)">DEPTH</text>
+ <use id="DEPTH_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
+ <g transform="translate(14 35)">
+ <!-- <rect width="38" height="6" fill="#f0f" transform="translate(0 0)" /> -->
+ <use id="ENV_TO_DEPTH_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(9 6.2)">ENV</text>
+ <use id="ENV_TO_DEPTH_PARAM" xlink:href="#button-small" transform="translate(29 -1.3)" />
</g>
<use xlink:href="#knobguide-linear" transform="translate(10.5 -9.5)" />
- <g transform="translate(0 48)">
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 30) rotate(270)">FDBK</text>
- <use id="FEEDBACK_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
- </g>
- <use xlink:href="#knobguide-linear" transform="translate(10.5 38.5)" />
- <g transform="translate(0 96)">
- <text font-size="8pt" letter-spacing="2px" transform="translate(8 33.5) rotate(270)">LEVEL</text>
- <use id="LEVEL_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
+ </g>
+ <g transform="translate(16 162)">
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 35) rotate(270)">FDBK</text>
+ <use id="FEEDBACK_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
+ <g transform="translate(14 35)">
+ <!-- <rect width="38" height="6" fill="#f0f" transform="translate(0 0)" /> -->
+ <use id="ENV_TO_FEEDBACK_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(9 6.2)">ENV</text>
+ <use id="ENV_TO_FEEDBACK_PARAM" xlink:href="#button-small" transform="translate(29 -1.3)" />
</g>
- <use xlink:href="#knobguide-linear" transform="translate(10.5 86.5)" />
+ <use xlink:href="#knobguide-linear" transform="translate(10.5 -9.5)" />
</g>
-
- <g transform="translate(13 237.5)">
- <g transform="translate(0 17.5)">
- <!-- <polyline points="0,0 200,0" stroke="#0f0" stroke-width="1" fill="none" transform="translate(0 3.3)" /> -->
- <text font-size="6pt" letter-spacing="1px" transform="translate(0 6.2)">ENV:</text>
- <g transform="translate(27 0)">
- <use id="ENV_TO_LEVEL_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
- <text font-size="6pt" letter-spacing="1px" transform="translate(9 6.2)">LEVEL</text>
- <use id="ENV_TO_LEVEL_PARAM" xlink:href="#button-small" transform="translate(38 -1.2)" />
- </g>
- <g transform="translate(81 0)">
- <use id="ENV_TO_FEEDBACK_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
- <text font-size="6pt" letter-spacing="1px" transform="translate(9 6.2)">FDBK</text>
- <use id="ENV_TO_FEEDBACK_PARAM" xlink:href="#button-small" transform="translate(34.5 -1.2)" />
- </g>
+ <g transform="translate(16 218)">
+ <!-- <polyline points="0,0 150,0" fill="none" stroke="#0f0" transform="translate(0 13)" /> -->
+ <text font-size="8pt" letter-spacing="2px" transform="translate(8 37.5) rotate(270)">LEVEL</text>
+ <use id="LEVEL_PARAM" xlink:href="#knob-medium" transform="translate(20 0)" />
+ <g transform="translate(14 35)">
+ <!-- <rect width="38" height="6" fill="#f0f" transform="translate(0 0)" /> -->
+ <use id="ENV_TO_LEVEL_LIGHT" xlink:href="#light-small" transform="translate(0 0)" />
+ <text font-size="6pt" letter-spacing="1px" transform="translate(9 6.2)">ENV</text>
+ <use id="ENV_TO_LEVEL_PARAM" xlink:href="#button-small" transform="translate(29 -1.3)" />
</g>
+ <use xlink:href="#knobguide-linear" transform="translate(10.5 -9.5)" />
</g>
+ <!-- <rect width="70" height="9" fill="#f0f" transform="translate(0 148)" /> -->
+ <!-- <rect width="70" height="9" fill="#f0f" transform="translate(0 204)" /> -->
+ <!-- <rect width="70" height="9" fill="#f0f" transform="translate(0 260)" /> -->
+
<g transform="translate(0 269)">
<rect width="130" height="91" rx="5" fill="#bbb" transform="translate(10 0)" />
<rect width="97" height="91" rx="5" fill="#fafafa" transform="translate(10 0)" />
diff --git a/res/FMOp.svg b/res/FMOp.svg
Binary files differ.
diff --git a/src/FMOp.cpp b/src/FMOp.cpp
@@ -26,10 +26,12 @@ void FMOp::step() {
if (!outputs[AUDIO_OUTPUT].active) {
lights[ENV_TO_LEVEL_LIGHT].value = params[ENV_TO_LEVEL_PARAM].value > 0.5f;
lights[ENV_TO_FEEDBACK_LIGHT].value = params[ENV_TO_FEEDBACK_PARAM].value > 0.5f;
+ lights[ENV_TO_DEPTH_LIGHT].value = params[ENV_TO_DEPTH_PARAM].value > 0.5f;
return;
}
lights[ENV_TO_LEVEL_LIGHT].value = _levelEnvelopeOn;
lights[ENV_TO_FEEDBACK_LIGHT].value = _feedbackEnvelopeOn;
+ lights[ENV_TO_DEPTH_LIGHT].value = _depthEnvelopeOn;
float pitchIn = 0.0f;
if (inputs[PITCH_INPUT].active) {
@@ -61,10 +63,12 @@ void FMOp::step() {
bool levelEnvelopeOn = params[ENV_TO_LEVEL_PARAM].value > 0.5f;
bool feedbackEnvelopeOn = params[ENV_TO_FEEDBACK_PARAM].value > 0.5f;
- if (_levelEnvelopeOn != levelEnvelopeOn || _feedbackEnvelopeOn != feedbackEnvelopeOn) {
+ bool depthEnvelopeOn = params[ENV_TO_DEPTH_PARAM].value > 0.5f;
+ if (_levelEnvelopeOn != levelEnvelopeOn || _feedbackEnvelopeOn != feedbackEnvelopeOn || _depthEnvelopeOn != depthEnvelopeOn) {
_levelEnvelopeOn = levelEnvelopeOn;
_feedbackEnvelopeOn = feedbackEnvelopeOn;
- bool envelopeOn = _levelEnvelopeOn || _feedbackEnvelopeOn;
+ _depthEnvelopeOn = depthEnvelopeOn;
+ bool envelopeOn = _levelEnvelopeOn || _feedbackEnvelopeOn || _depthEnvelopeOn;
if (envelopeOn && !_envelopeOn) {
_envelope.reset();
}
@@ -114,7 +118,11 @@ void FMOp::step() {
offset = feedback * _feedbackDelayedSample;
}
if (inputs[FM_INPUT].active) {
- offset += inputs[FM_INPUT].value * _depthSL.next(_depth) * 2.0f;
+ float depth = _depthSL.next(_depth);
+ if (_depthEnvelopeOn) {
+ depth *= envelope;
+ }
+ offset += inputs[FM_INPUT].value * depth * 2.0f;
}
for (int i = 0; i < oversample; ++i) {
_phasor.advancePhase();
@@ -148,15 +156,16 @@ struct FMOpWidget : ModuleWidget {
// generated by svg_widgets.rb
auto ratioParamPosition = Vec(30.0, 45.0);
auto fineParamPosition = Vec(112.0, 57.0);
- auto attackParamPosition = Vec(107.0, 90.0);
- auto decayParamPosition = Vec(107.0, 132.0);
- auto sustainParamPosition = Vec(107.0, 174.0);
- auto releaseParamPosition = Vec(107.0, 216.0);
- auto depthParamPosition = Vec(36.0, 113.0);
- auto feedbackParamPosition = Vec(36.0, 161.0);
- auto levelParamPosition = Vec(36.0, 209.0);
- auto envToLevelParamPosition = Vec(78.0, 253.8);
- auto envToFeedbackParamPosition = Vec(128.5, 253.8);
+ auto attackParamPosition = Vec(107.0, 94.0);
+ auto decayParamPosition = Vec(107.0, 139.0);
+ auto sustainParamPosition = Vec(107.0, 184.0);
+ auto releaseParamPosition = Vec(107.0, 229.0);
+ auto depthParamPosition = Vec(36.0, 106.0);
+ auto envToDepthParamPosition = Vec(59.0, 139.7);
+ auto feedbackParamPosition = Vec(36.0, 162.0);
+ auto envToFeedbackParamPosition = Vec(59.0, 195.7);
+ auto levelParamPosition = Vec(36.0, 218.0);
+ auto envToLevelParamPosition = Vec(59.0, 251.7);
auto depthInputPosition = Vec(15.0, 274.0);
auto feedbackInputPosition = Vec(47.0, 274.0);
@@ -168,8 +177,9 @@ struct FMOpWidget : ModuleWidget {
auto audioOutputPosition = Vec(111.0, 318.0);
- auto envToLevelLightPosition = Vec(40.0, 255.0);
- auto envToFeedbackLightPosition = Vec(94.0, 255.0);
+ auto envToDepthLightPosition = Vec(30.0, 141.0);
+ auto envToFeedbackLightPosition = Vec(30.0, 197.0);
+ auto envToLevelLightPosition = Vec(30.0, 253.0);
// end generated by svg_widgets.rb
addParam(ParamWidget::create<Knob38>(ratioParamPosition, module, FMOp::RATIO_PARAM, -1.0, 1.0, 0.0));
@@ -183,6 +193,7 @@ struct FMOpWidget : ModuleWidget {
addParam(ParamWidget::create<Knob26>(levelParamPosition, module, FMOp::LEVEL_PARAM, 0.0, 1.0, 1.0));
addParam(ParamWidget::create<StatefulButton9>(envToLevelParamPosition, module, FMOp::ENV_TO_LEVEL_PARAM, 0.0, 1.0, 0.0));
addParam(ParamWidget::create<StatefulButton9>(envToFeedbackParamPosition, module, FMOp::ENV_TO_FEEDBACK_PARAM, 0.0, 1.0, 0.0));
+ addParam(ParamWidget::create<StatefulButton9>(envToDepthParamPosition, module, FMOp::ENV_TO_DEPTH_PARAM, 0.0, 1.0, 0.0));
addInput(Port::create<Port24>(sustainInputPosition, Port::INPUT, module, FMOp::SUSTAIN_INPUT));
addInput(Port::create<Port24>(depthInputPosition, Port::INPUT, module, FMOp::DEPTH_INPUT));
@@ -196,6 +207,7 @@ struct FMOpWidget : ModuleWidget {
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(envToLevelLightPosition, module, FMOp::ENV_TO_LEVEL_LIGHT));
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(envToFeedbackLightPosition, module, FMOp::ENV_TO_FEEDBACK_LIGHT));
+ addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(envToDepthLightPosition, module, FMOp::ENV_TO_DEPTH_LIGHT));
}
};
diff --git a/src/FMOp.hpp b/src/FMOp.hpp
@@ -25,6 +25,7 @@ struct FMOp : Module {
LEVEL_PARAM,
ENV_TO_LEVEL_PARAM,
ENV_TO_FEEDBACK_PARAM,
+ ENV_TO_DEPTH_PARAM,
NUM_PARAMS
};
@@ -47,6 +48,7 @@ struct FMOp : Module {
enum LightsIds {
ENV_TO_LEVEL_LIGHT,
ENV_TO_FEEDBACK_LIGHT,
+ ENV_TO_DEPTH_LIGHT,
NUM_LIGHTS
};
@@ -62,6 +64,7 @@ struct FMOp : Module {
bool _envelopeOn = false;
bool _levelEnvelopeOn = false;
bool _feedbackEnvelopeOn = false;
+ bool _depthEnvelopeOn = false;
float _maxFrequency = 0.0f;
float _buffer[oversample];
ADSR _envelope;