diff --git a/src/VCMixer.cpp b/src/VCMixer.cpp index e09aeff..375b73d 100644 --- a/src/VCMixer.cpp +++ b/src/VCMixer.cpp @@ -26,6 +26,9 @@ struct VCMixer : Module { dsp::VuMeter2 chMeters[4]; dsp::ClockDivider lightDivider; + bool chExp = false; + bool mixExp = false; + VCMixer() { config(0, 0, 0, 0); config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); @@ -48,6 +51,12 @@ struct VCMixer : Module { lightDivider.setDivision(512); } + void onReset(const ResetEvent& e) override { + chExp = false; + mixExp = false; + Module::onReset(e); + } + void process(const ProcessArgs& args) override { using simd::float_4; @@ -79,6 +88,8 @@ struct VCMixer : Module { if (inputs[CV_INPUTS + i].isConnected()) { float_4 cv = inputs[CV_INPUTS + i].getPolyVoltageSimd(c) / 10.f; cv = simd::fmax(0.f, cv); + if (chExp) + cv = (cv * cv) * (cv * cv); out *= cv; } @@ -105,6 +116,8 @@ struct VCMixer : Module { if (inputs[MIX_CV_INPUT].isConnected()) { float_4 cv = inputs[MIX_CV_INPUT].getPolyVoltageSimd(c) / 10.f; cv = simd::fmax(0.f, cv); + if (mixExp) + cv = (cv * cv) * (cv * cv); mix *= cv; } @@ -129,6 +142,26 @@ struct VCMixer : Module { } } } + + json_t* dataToJson() override { + json_t* rootJ = json_object(); + // chExp + json_object_set_new(rootJ, "chExp", json_boolean(chExp)); + // mixExp + json_object_set_new(rootJ, "mixExp", json_boolean(mixExp)); + return rootJ; + } + + void dataFromJson(json_t* rootJ) override { + // chExp + json_t* chExpJ = json_object_get(rootJ, "chExp"); + if (chExpJ) + chExp = json_boolean_value(chExpJ); + // mixExp + json_t* mixExpJ = json_object_get(rootJ, "mixExp"); + if (mixExpJ) + mixExp = json_boolean_value(mixExpJ); + } }; @@ -164,6 +197,16 @@ struct VCMixerWidget : ModuleWidget { addOutput(createOutputCentered(mm2px(Vec(28.279, 113.115)), module, VCMixer::CH_OUTPUTS + 2)); addOutput(createOutputCentered(mm2px(Vec(39.116, 113.115)), module, VCMixer::CH_OUTPUTS + 3)); } + + void appendContextMenu(Menu* menu) override { + VCMixer* module = getModule(); + assert(module); + + menu->addChild(new MenuSeparator); + + menu->addChild(createBoolPtrMenuItem("Exponential channel VCAs", "", &module->chExp)); + menu->addChild(createBoolPtrMenuItem("Exponential mix VCA", "", &module->mixExp)); + } };