@@ -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)); | |||