| @@ -48,14 +48,12 @@ struct LFO : Module { | |||
| float clockFreq = 1.f; | |||
| dsp::Timer clockTimer; | |||
| dsp::BooleanTrigger offsetTrigger; | |||
| dsp::BooleanTrigger invertTrigger; | |||
| dsp::ClockDivider lightDivider; | |||
| LFO() { | |||
| config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
| configButton(OFFSET_PARAM, "Offset 0-10V"); | |||
| configButton(INVERT_PARAM, "Invert"); | |||
| configSwitch(OFFSET_PARAM, 0.f, 1.f, 0.f, "Offset", {"Bipolar", "Unipolar"}); | |||
| configSwitch(INVERT_PARAM, 0.f, 1.f, 0.f, "Invert"); | |||
| configParam(FREQ_PARAM, -8.f, 10.f, 1.f, "Frequency", " Hz", 2, 1); | |||
| configParam(FM_PARAM, -1.f, 1.f, 0.f, "Frequency modulation", "%", 0.f, 100.f); | |||
| getParamQuantity(FM_PARAM)->randomizeEnabled = false; | |||
| @@ -80,8 +78,6 @@ struct LFO : Module { | |||
| } | |||
| void onReset() override { | |||
| offset = false; | |||
| invert = false; | |||
| for (int c = 0; c < 16; c += 4) { | |||
| phases[c / 4] = 0.f; | |||
| } | |||
| @@ -94,14 +90,8 @@ struct LFO : Module { | |||
| float fmParam = params[FM_PARAM].getValue(); | |||
| float pwParam = params[PW_PARAM].getValue(); | |||
| float pwmParam = params[PWM_PARAM].getValue(); | |||
| // Buttons | |||
| if (offsetTrigger.process(params[OFFSET_PARAM].getValue() > 0.f)) { | |||
| offset ^= true; | |||
| } | |||
| if (invertTrigger.process(params[INVERT_PARAM].getValue() > 0.f)) { | |||
| invert ^= true; | |||
| } | |||
| bool offset = params[OFFSET_PARAM].getValue() > 0.f; | |||
| bool invert = params[INVERT_PARAM].getValue() > 0.f; | |||
| // Clock | |||
| if (inputs[CLOCK_INPUT].isConnected()) { | |||
| @@ -212,39 +202,6 @@ struct LFO : Module { | |||
| lights[INVERT_LIGHT].setBrightness(invert); | |||
| } | |||
| } | |||
| json_t* dataToJson() override { | |||
| json_t* rootJ = json_object(); | |||
| // offset | |||
| json_object_set_new(rootJ, "offset", json_boolean(offset)); | |||
| // invert | |||
| json_object_set_new(rootJ, "invert", json_boolean(invert)); | |||
| return rootJ; | |||
| } | |||
| void dataFromJson(json_t* rootJ) override { | |||
| // offset | |||
| json_t* offsetJ = json_object_get(rootJ, "offset"); | |||
| if (offsetJ) | |||
| offset = json_boolean_value(offsetJ); | |||
| // invert | |||
| json_t* invertJ = json_object_get(rootJ, "invert"); | |||
| if (invertJ) | |||
| invert = json_boolean_value(invertJ); | |||
| } | |||
| void paramsFromJson(json_t* rootJ) override { | |||
| Module::paramsFromJson(rootJ); | |||
| // In <2.0, OFFSET_PARAM and INVERT_PARAM were toggle switches instead of momentary buttons, so if params are on after deserializing, set boolean states instead. | |||
| if (params[OFFSET_PARAM].getValue() > 0.f) { | |||
| offset = true; | |||
| params[OFFSET_PARAM].setValue(0.f); | |||
| } | |||
| if (params[INVERT_PARAM].getValue() > 0.f) { | |||
| invert = true; | |||
| params[INVERT_PARAM].setValue(0.f); | |||
| } | |||
| } | |||
| }; | |||
| @@ -261,8 +218,8 @@ struct LFOWidget : ModuleWidget { | |||
| addParam(createParamCentered<RoundHugeBlackKnob>(mm2px(Vec(22.902, 29.803)), module, LFO::FREQ_PARAM)); | |||
| addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(22.861, 56.388)), module, LFO::PW_PARAM)); | |||
| addParam(createParamCentered<Trimpot>(mm2px(Vec(6.604, 80.603)), module, LFO::FM_PARAM)); | |||
| addParam(createLightParamCentered<LEDLightButton<MediumSimpleLight<YellowLight>>>(mm2px(Vec(17.441, 80.603)), module, LFO::INVERT_PARAM, LFO::INVERT_LIGHT)); | |||
| addParam(createLightParamCentered<LEDLightButton<MediumSimpleLight<YellowLight>>>(mm2px(Vec(28.279, 80.603)), module, LFO::OFFSET_PARAM, LFO::OFFSET_LIGHT)); | |||
| addParam(createLightParamCentered<LEDLightLatch<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(17.441, 80.603)), module, LFO::INVERT_PARAM, LFO::INVERT_LIGHT)); | |||
| addParam(createLightParamCentered<LEDLightLatch<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(28.279, 80.603)), module, LFO::OFFSET_PARAM, LFO::OFFSET_LIGHT)); | |||
| addParam(createParamCentered<Trimpot>(mm2px(Vec(39.116, 80.603)), module, LFO::PWM_PARAM)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(6.604, 96.859)), module, LFO::FM_INPUT)); | |||
| @@ -24,6 +24,9 @@ struct Scope : Module { | |||
| NUM_INPUTS | |||
| }; | |||
| enum OutputIds { | |||
| // new in 2.0 | |||
| X_OUTPUT, | |||
| Y_OUTPUT, | |||
| NUM_OUTPUTS | |||
| }; | |||
| enum LightIds { | |||
| @@ -353,36 +356,31 @@ struct ScopeWidget : ModuleWidget { | |||
| setModule(module); | |||
| setPanel(createPanel(asset::plugin(pluginInstance, "res/Scope.svg"))); | |||
| addChild(createWidget<ScrewSilver>(Vec(15, 0))); | |||
| addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 0))); | |||
| addChild(createWidget<ScrewSilver>(Vec(15, 365))); | |||
| addChild(createWidget<ScrewSilver>(Vec(box.size.x - 30, 365))); | |||
| { | |||
| ScopeDisplay* display = new ScopeDisplay(); | |||
| display->module = module; | |||
| display->box.pos = Vec(0, 44); | |||
| display->box.size = Vec(box.size.x, 140); | |||
| addChild(display); | |||
| } | |||
| addParam(createParam<RoundBlackSnapKnob>(Vec(15, 209), module, Scope::X_SCALE_PARAM)); | |||
| addParam(createParam<RoundBlackKnob>(Vec(15, 263), module, Scope::X_POS_PARAM)); | |||
| addParam(createParam<RoundBlackSnapKnob>(Vec(61, 209), module, Scope::Y_SCALE_PARAM)); | |||
| addParam(createParam<RoundBlackKnob>(Vec(61, 263), module, Scope::Y_POS_PARAM)); | |||
| addParam(createParam<RoundBlackKnob>(Vec(107, 209), module, Scope::TIME_PARAM)); | |||
| addParam(createParam<CKD6>(Vec(106, 262), module, Scope::LISSAJOUS_PARAM)); | |||
| addParam(createParam<RoundBlackKnob>(Vec(153, 209), module, Scope::TRIG_PARAM)); | |||
| addParam(createParam<CKD6>(Vec(152, 262), module, Scope::EXTERNAL_PARAM)); | |||
| addInput(createInput<PJ301MPort>(Vec(17, 319), module, Scope::X_INPUT)); | |||
| addInput(createInput<PJ301MPort>(Vec(63, 319), module, Scope::Y_INPUT)); | |||
| addInput(createInput<PJ301MPort>(Vec(154, 319), module, Scope::TRIG_INPUT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(104, 251), module, Scope::PLOT_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(104, 296), module, Scope::LISSAJOUS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(150, 251), module, Scope::INTERNAL_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(150, 296), module, Scope::EXTERNAL_LIGHT)); | |||
| addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0))); | |||
| addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); | |||
| addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
| addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); | |||
| // addParam(createParamCentered<LEDButton>(mm2px(Vec(8.643, 80.603)), module, Scope::_1X2_PARAM)); | |||
| addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(24.897, 80.551)), module, Scope::X_SCALE_PARAM)); | |||
| addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(41.147, 80.551)), module, Scope::Y_SCALE_PARAM)); | |||
| // addParam(createParamCentered<LEDButton>(mm2px(Vec(57.397, 80.521)), module, Scope::TRIG_PARAM)); | |||
| addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(8.643, 96.819)), module, Scope::TIME_PARAM)); | |||
| addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(24.897, 96.789)), module, Scope::X_POS_PARAM)); | |||
| addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(41.147, 96.815)), module, Scope::Y_POS_PARAM)); | |||
| // addParam(createParamCentered<RoundBlackKnob>(mm2px(Vec(57.397, 96.815)), module, Scope::THERS_PARAM)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(8.643, 113.115)), module, Scope::X_INPUT)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(33.023, 113.115)), module, Scope::Y_INPUT)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(57.397, 113.115)), module, Scope::TRIG_INPUT)); | |||
| addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(20.833, 113.115)), module, Scope::X_OUTPUT)); | |||
| addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(45.212, 113.115)), module, Scope::Y_OUTPUT)); | |||
| ScopeDisplay* display = createWidget<ScopeDisplay>(Vec(0, 44)); | |||
| display->box.size = Vec(box.size.x, 140); | |||
| display->module = module; | |||
| addChild(display); | |||
| } | |||
| }; | |||
| @@ -36,8 +36,6 @@ struct WTLFO : Module { | |||
| }; | |||
| Wavetable wavetable; | |||
| bool offset = false; | |||
| bool invert = false; | |||
| float_4 phases[4] = {}; | |||
| float lastPos = 0.f; | |||
| @@ -52,9 +50,8 @@ struct WTLFO : Module { | |||
| WTLFO() { | |||
| config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | |||
| // TODO Change to momentary with backward compatibility in fromJson() | |||
| configButton(OFFSET_PARAM, "Offset 0-10V"); | |||
| configButton(INVERT_PARAM, "Invert wave"); | |||
| configSwitch(OFFSET_PARAM, 0.f, 1.f, 0.f, "Offset", {"Bipolar", "Unipolar"}); | |||
| configSwitch(INVERT_PARAM, 0.f, 1.f, 0.f, "Invert"); | |||
| struct FrequencyQuantity : ParamQuantity { | |||
| float getDisplayValue() override { | |||
| @@ -88,8 +85,6 @@ struct WTLFO : Module { | |||
| } | |||
| void onReset() override { | |||
| offset = false; | |||
| invert = false; | |||
| wavetable.reset(); | |||
| // Reset state | |||
| @@ -100,12 +95,6 @@ struct WTLFO : Module { | |||
| clockTimer.reset(); | |||
| } | |||
| void onRandomize(const RandomizeEvent& e) override { | |||
| Module::onRandomize(e); | |||
| offset = random::get<bool>(); | |||
| invert = random::get<bool>(); | |||
| } | |||
| void onAdd(const AddEvent& e) override { | |||
| std::string path = system::join(getPatchStorageDirectory(), "wavetable.wav"); | |||
| // Silently fails | |||
| @@ -120,10 +109,8 @@ struct WTLFO : Module { | |||
| } | |||
| void process(const ProcessArgs& args) override { | |||
| if (offsetTrigger.process(params[OFFSET_PARAM].getValue() > 0.f)) | |||
| offset ^= true; | |||
| if (invertTrigger.process(params[INVERT_PARAM].getValue() > 0.f)) | |||
| invert ^= true; | |||
| bool offset = (params[OFFSET_PARAM].getValue() > 0.f); | |||
| bool invert = (params[INVERT_PARAM].getValue() > 0.f); | |||
| int channels = std::max(1, inputs[FM_INPUT].getChannels()); | |||
| @@ -239,10 +226,6 @@ struct WTLFO : Module { | |||
| json_t* dataToJson() override { | |||
| json_t* rootJ = json_object(); | |||
| // offset | |||
| json_object_set_new(rootJ, "offset", json_boolean(offset)); | |||
| // invert | |||
| json_object_set_new(rootJ, "invert", json_boolean(invert)); | |||
| // Merge wavetable | |||
| json_t* wavetableJ = wavetable.toJson(); | |||
| json_object_update(rootJ, wavetableJ); | |||
| @@ -251,14 +234,6 @@ struct WTLFO : Module { | |||
| } | |||
| void dataFromJson(json_t* rootJ) override { | |||
| // offset | |||
| json_t* offsetJ = json_object_get(rootJ, "offset"); | |||
| if (offsetJ) | |||
| offset = json_boolean_value(offsetJ); | |||
| // invert | |||
| json_t* invertJ = json_object_get(rootJ, "invert"); | |||
| if (invertJ) | |||
| invert = json_boolean_value(invertJ); | |||
| // wavetable | |||
| wavetable.fromJson(rootJ); | |||
| } | |||
| @@ -278,9 +253,9 @@ struct WTLFOWidget : ModuleWidget { | |||
| addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(8.913, 56.388)), module, WTLFO::FREQ_PARAM)); | |||
| addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(26.647, 56.388)), module, WTLFO::POS_PARAM)); | |||
| addParam(createParamCentered<Trimpot>(mm2px(Vec(6.987, 80.603)), module, WTLFO::FM_PARAM)); | |||
| addParam(createLightParamCentered<LEDLightButton<MediumSimpleLight<YellowLight>>>(mm2px(Vec(17.824, 80.517)), module, WTLFO::INVERT_PARAM, WTLFO::INVERT_LIGHT)); | |||
| addParam(createLightParamCentered<LEDLightLatch<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(17.824, 80.517)), module, WTLFO::INVERT_PARAM, WTLFO::INVERT_LIGHT)); | |||
| addParam(createParamCentered<Trimpot>(mm2px(Vec(28.662, 80.536)), module, WTLFO::POS_CV_PARAM)); | |||
| addParam(createLightParamCentered<LEDLightButton<MediumSimpleLight<YellowLight>>>(mm2px(Vec(17.824, 96.859)), module, WTLFO::OFFSET_PARAM, WTLFO::OFFSET_LIGHT)); | |||
| addParam(createLightParamCentered<LEDLightLatch<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(17.824, 96.859)), module, WTLFO::OFFSET_PARAM, WTLFO::OFFSET_LIGHT)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(6.987, 96.859)), module, WTLFO::FM_INPUT)); | |||
| addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.662, 96.859)), module, WTLFO::POS_INPUT)); | |||