commit 4a4fb03d33bfd9abbea207032ae8dc1c886e46f9
parent b2d2d81f80984b7603aabe4cf4aea7c79daf7654
Author: Matt Demanett <matt@demanett.net>
Date: Fri, 25 May 2018 01:01:27 -0400
FM-OP: add context menu toggle for linear level response.
Diffstat:
2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/src/FMOp.cpp b/src/FMOp.cpp
@@ -2,6 +2,8 @@
#include "FMOp.hpp"
#include "dsp/pitch.hpp"
+#define LINEAR_LEVEL "linearLevel"
+
void FMOp::onReset() {
_steps = modulationSteps;
_envelope.reset();
@@ -22,6 +24,19 @@ void FMOp::onSampleRateChange() {
_sustainSL.setParams(sampleRate, slewLimitTime / 10.0f);
}
+json_t* FMOp::toJson() {
+ json_t* root = json_object();
+ json_object_set_new(root, LINEAR_LEVEL, json_boolean(_linearLevel));
+ return root;
+}
+
+void FMOp::fromJson(json_t* root) {
+ json_t* ll = json_object_get(root, LINEAR_LEVEL);
+ if (ll) {
+ _linearLevel = json_is_true(ll);
+ }
+}
+
void FMOp::step() {
if (!outputs[AUDIO_OUTPUT].active) {
lights[ENV_TO_LEVEL_LIGHT].value = params[ENV_TO_LEVEL_PARAM].value > 0.5f;
@@ -132,12 +147,35 @@ void FMOp::step() {
if (_levelEnvelopeOn) {
out *= envelope;
}
- out = (1.0f - out) * Amplifier::minDecibels;
- _amplifier.setLevel(out);
- out = _amplifier.next(_decimator.next(_buffer));
+ if (_linearLevel) {
+ out *= _decimator.next(_buffer);
+ }
+ else {
+ out = (1.0f - out) * Amplifier::minDecibels;
+ _amplifier.setLevel(out);
+ out = _amplifier.next(_decimator.next(_buffer));
+ }
outputs[AUDIO_OUTPUT].value = _feedbackDelayedSample = amplitude * out;
}
+struct LinearLevelMenuItem : MenuItem {
+ FMOp* _module;
+
+ LinearLevelMenuItem(FMOp* module, const char* label)
+ : _module(module)
+ {
+ this->text = label;
+ }
+
+ void onAction(EventAction &e) override {
+ _module->_linearLevel = !_module->_linearLevel;
+ }
+
+ void step() override {
+ rightText = _module->_linearLevel ? "✔" : "";
+ }
+};
+
struct FMOpWidget : ModuleWidget {
FMOpWidget(FMOp* module) : ModuleWidget(module) {
box.size = Vec(RACK_GRID_WIDTH * 10, RACK_GRID_HEIGHT);
@@ -210,6 +248,13 @@ struct FMOpWidget : ModuleWidget {
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(envToFeedbackLightPosition, module, FMOp::ENV_TO_FEEDBACK_LIGHT));
addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(envToDepthLightPosition, module, FMOp::ENV_TO_DEPTH_LIGHT));
}
+
+ virtual void appendContextMenu(Menu* menu) override {
+ FMOp* fmop = dynamic_cast<FMOp*>(module);
+ assert(fmop);
+ menu->addChild(new MenuLabel());
+ menu->addChild(new LinearLevelMenuItem(fmop, "Linear Level Response"));
+ }
};
Model* modelFMOp = Model::create<FMOp, FMOpWidget>("Bogaudio", "Bogaudio-FMOp", "FM-OP", OSCILLATOR_TAG, SYNTH_VOICE_TAG);
diff --git a/src/FMOp.hpp b/src/FMOp.hpp
@@ -77,6 +77,7 @@ struct FMOp : Module {
SlewLimiter _levelSL;
SlewLimiter _sustainSL;
Amplifier _amplifier;
+ bool _linearLevel = false;
FMOp()
: Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS)
@@ -88,6 +89,8 @@ struct FMOp : Module {
virtual void onReset() override;
virtual void onSampleRateChange() override;
+ virtual json_t* toJson() override;
+ virtual void fromJson(json_t* root) override;
virtual void step() override;
};