@@ -48,14 +48,12 @@ struct LFO : Module { | |||||
float clockFreq = 1.f; | float clockFreq = 1.f; | ||||
dsp::Timer clockTimer; | dsp::Timer clockTimer; | ||||
dsp::BooleanTrigger offsetTrigger; | |||||
dsp::BooleanTrigger invertTrigger; | |||||
dsp::ClockDivider lightDivider; | dsp::ClockDivider lightDivider; | ||||
LFO() { | LFO() { | ||||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | 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(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); | configParam(FM_PARAM, -1.f, 1.f, 0.f, "Frequency modulation", "%", 0.f, 100.f); | ||||
getParamQuantity(FM_PARAM)->randomizeEnabled = false; | getParamQuantity(FM_PARAM)->randomizeEnabled = false; | ||||
@@ -80,8 +78,6 @@ struct LFO : Module { | |||||
} | } | ||||
void onReset() override { | void onReset() override { | ||||
offset = false; | |||||
invert = false; | |||||
for (int c = 0; c < 16; c += 4) { | for (int c = 0; c < 16; c += 4) { | ||||
phases[c / 4] = 0.f; | phases[c / 4] = 0.f; | ||||
} | } | ||||
@@ -94,14 +90,8 @@ struct LFO : Module { | |||||
float fmParam = params[FM_PARAM].getValue(); | float fmParam = params[FM_PARAM].getValue(); | ||||
float pwParam = params[PW_PARAM].getValue(); | float pwParam = params[PW_PARAM].getValue(); | ||||
float pwmParam = params[PWM_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 | // Clock | ||||
if (inputs[CLOCK_INPUT].isConnected()) { | if (inputs[CLOCK_INPUT].isConnected()) { | ||||
@@ -212,39 +202,6 @@ struct LFO : Module { | |||||
lights[INVERT_LIGHT].setBrightness(invert); | 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<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<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(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)); | 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)); | addInput(createInputCentered<PJ301MPort>(mm2px(Vec(6.604, 96.859)), module, LFO::FM_INPUT)); | ||||
@@ -24,6 +24,9 @@ struct Scope : Module { | |||||
NUM_INPUTS | NUM_INPUTS | ||||
}; | }; | ||||
enum OutputIds { | enum OutputIds { | ||||
// new in 2.0 | |||||
X_OUTPUT, | |||||
Y_OUTPUT, | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
@@ -353,36 +356,31 @@ struct ScopeWidget : ModuleWidget { | |||||
setModule(module); | setModule(module); | ||||
setPanel(createPanel(asset::plugin(pluginInstance, "res/Scope.svg"))); | 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; | Wavetable wavetable; | ||||
bool offset = false; | |||||
bool invert = false; | |||||
float_4 phases[4] = {}; | float_4 phases[4] = {}; | ||||
float lastPos = 0.f; | float lastPos = 0.f; | ||||
@@ -52,9 +50,8 @@ struct WTLFO : Module { | |||||
WTLFO() { | WTLFO() { | ||||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | 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 { | struct FrequencyQuantity : ParamQuantity { | ||||
float getDisplayValue() override { | float getDisplayValue() override { | ||||
@@ -88,8 +85,6 @@ struct WTLFO : Module { | |||||
} | } | ||||
void onReset() override { | void onReset() override { | ||||
offset = false; | |||||
invert = false; | |||||
wavetable.reset(); | wavetable.reset(); | ||||
// Reset state | // Reset state | ||||
@@ -100,12 +95,6 @@ struct WTLFO : Module { | |||||
clockTimer.reset(); | 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 { | void onAdd(const AddEvent& e) override { | ||||
std::string path = system::join(getPatchStorageDirectory(), "wavetable.wav"); | std::string path = system::join(getPatchStorageDirectory(), "wavetable.wav"); | ||||
// Silently fails | // Silently fails | ||||
@@ -120,10 +109,8 @@ struct WTLFO : Module { | |||||
} | } | ||||
void process(const ProcessArgs& args) override { | 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()); | int channels = std::max(1, inputs[FM_INPUT].getChannels()); | ||||
@@ -239,10 +226,6 @@ struct WTLFO : Module { | |||||
json_t* dataToJson() override { | json_t* dataToJson() override { | ||||
json_t* rootJ = json_object(); | 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 | // Merge wavetable | ||||
json_t* wavetableJ = wavetable.toJson(); | json_t* wavetableJ = wavetable.toJson(); | ||||
json_object_update(rootJ, wavetableJ); | json_object_update(rootJ, wavetableJ); | ||||
@@ -251,14 +234,6 @@ struct WTLFO : Module { | |||||
} | } | ||||
void dataFromJson(json_t* rootJ) override { | 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 | ||||
wavetable.fromJson(rootJ); | 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(8.913, 56.388)), module, WTLFO::FREQ_PARAM)); | ||||
addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(26.647, 56.388)), module, WTLFO::POS_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(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(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(6.987, 96.859)), module, WTLFO::FM_INPUT)); | ||||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.662, 96.859)), module, WTLFO::POS_INPUT)); | addInput(createInputCentered<PJ301MPort>(mm2px(Vec(28.662, 96.859)), module, WTLFO::POS_INPUT)); | ||||