|
@@ -26,6 +26,9 @@ struct VCMixer : Module { |
|
|
dsp::VuMeter2 chMeters[4]; |
|
|
dsp::VuMeter2 chMeters[4]; |
|
|
dsp::ClockDivider lightDivider; |
|
|
dsp::ClockDivider lightDivider; |
|
|
|
|
|
|
|
|
|
|
|
bool chExp = false; |
|
|
|
|
|
bool mixExp = false; |
|
|
|
|
|
|
|
|
VCMixer() { |
|
|
VCMixer() { |
|
|
config(0, 0, 0, 0); |
|
|
config(0, 0, 0, 0); |
|
|
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); |
|
|
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); |
|
@@ -48,6 +51,12 @@ struct VCMixer : Module { |
|
|
lightDivider.setDivision(512); |
|
|
lightDivider.setDivision(512); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void onReset(const ResetEvent& e) override { |
|
|
|
|
|
chExp = false; |
|
|
|
|
|
mixExp = false; |
|
|
|
|
|
Module::onReset(e); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void process(const ProcessArgs& args) override { |
|
|
void process(const ProcessArgs& args) override { |
|
|
using simd::float_4; |
|
|
using simd::float_4; |
|
|
|
|
|
|
|
@@ -79,6 +88,8 @@ struct VCMixer : Module { |
|
|
if (inputs[CV_INPUTS + i].isConnected()) { |
|
|
if (inputs[CV_INPUTS + i].isConnected()) { |
|
|
float_4 cv = inputs[CV_INPUTS + i].getPolyVoltageSimd<float_4>(c) / 10.f; |
|
|
float_4 cv = inputs[CV_INPUTS + i].getPolyVoltageSimd<float_4>(c) / 10.f; |
|
|
cv = simd::fmax(0.f, cv); |
|
|
cv = simd::fmax(0.f, cv); |
|
|
|
|
|
if (chExp) |
|
|
|
|
|
cv = (cv * cv) * (cv * cv); |
|
|
out *= cv; |
|
|
out *= cv; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -105,6 +116,8 @@ struct VCMixer : Module { |
|
|
if (inputs[MIX_CV_INPUT].isConnected()) { |
|
|
if (inputs[MIX_CV_INPUT].isConnected()) { |
|
|
float_4 cv = inputs[MIX_CV_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f; |
|
|
float_4 cv = inputs[MIX_CV_INPUT].getPolyVoltageSimd<float_4>(c) / 10.f; |
|
|
cv = simd::fmax(0.f, cv); |
|
|
cv = simd::fmax(0.f, cv); |
|
|
|
|
|
if (mixExp) |
|
|
|
|
|
cv = (cv * cv) * (cv * cv); |
|
|
mix *= 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<PJ301MPort>(mm2px(Vec(28.279, 113.115)), module, VCMixer::CH_OUTPUTS + 2)); |
|
|
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(28.279, 113.115)), module, VCMixer::CH_OUTPUTS + 2)); |
|
|
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(39.116, 113.115)), module, VCMixer::CH_OUTPUTS + 3)); |
|
|
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(39.116, 113.115)), module, VCMixer::CH_OUTPUTS + 3)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void appendContextMenu(Menu* menu) override { |
|
|
|
|
|
VCMixer* module = getModule<VCMixer>(); |
|
|
|
|
|
assert(module); |
|
|
|
|
|
|
|
|
|
|
|
menu->addChild(new MenuSeparator); |
|
|
|
|
|
|
|
|
|
|
|
menu->addChild(createBoolPtrMenuItem("Exponential channel VCAs", "", &module->chExp)); |
|
|
|
|
|
menu->addChild(createBoolPtrMenuItem("Exponential mix VCA", "", &module->mixExp)); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|