@@ -24,9 +24,9 @@ Aeolian 3 1-2-3-4-5-b6-b7 | |||||
Locrian 2 1-2-b3-4-b5-b6-b7 | Locrian 2 1-2-b3-4-b5-b6-b7 | ||||
Locrian b4 1-b2-b3-b4-b5-b6-b7 | Locrian b4 1-b2-b3-b4-b5-b6-b7 | ||||
Bebop Dominant 1-2-3-4-5-6-#6-7 | Bebop Dominant 1-2-3-4-5-6-#6-7 | ||||
Bebob Major 1-2-3-4-5-b6-6-7 | |||||
Bebob Minor 1-2-b3-3-4-5-6-b7 | |||||
Bebob Melodic Minor 1-2-b3-4-5-b6-6-7 | |||||
Bebop Major 1-2-3-4-5-b6-6-7 | |||||
Bebop Minor 1-2-b3-3-4-5-6-b7 | |||||
Bebop Melodic Minor 1-2-b3-4-5-b6-6-7 | |||||
Blues Major 1-2-b3-3-5-6 | Blues Major 1-2-b3-3-5-6 | ||||
Blues Minor 1-b3-4-b5-5-b7 | Blues Minor 1-b3-4-b5-5-b7 | ||||
Blues Diminished 1-b2-b3-3-b5-5-6-b7 | Blues Diminished 1-b2-b3-3-b5-5-6-b7 | ||||
@@ -122,7 +122,7 @@ for line in scales.splitlines(): | |||||
path = os.path.join(dir, f"{count:02d}_{name}.vcvm") | path = os.path.join(dir, f"{count:02d}_{name}.vcvm") | ||||
print(path) | print(path) | ||||
print(data) | print(data) | ||||
with open(path, "w") as f: | |||||
with open(path, "w", newline='\n') as f: | |||||
json.dump(data, f, indent=2) | json.dump(data, f, indent=2) | ||||
count += 1 | count += 1 |
@@ -183,6 +183,16 @@ struct ADSR : Module { | |||||
lights[PUSH_LIGHT].setBrightness(anyGate); | lights[PUSH_LIGHT].setBrightness(anyGate); | ||||
} | } | ||||
} | } | ||||
void paramsFromJson(json_t* rootJ) override { | |||||
// These attenuators didn't exist in version <2.0, so set to 1 in case they are not overwritten. | |||||
params[ATTACK_CV_PARAM].setValue(1.f); | |||||
params[DECAY_CV_PARAM].setValue(1.f); | |||||
params[SUSTAIN_CV_PARAM].setValue(1.f); | |||||
params[RELEASE_CV_PARAM].setValue(1.f); | |||||
Module::paramsFromJson(rootJ); | |||||
} | |||||
}; | }; | ||||
@@ -193,7 +193,7 @@ struct Delay : Module { | |||||
} | } | ||||
} | } | ||||
void fromJson(json_t* rootJ) override { | |||||
void paramsFromJson(json_t* rootJ) override { | |||||
// These attenuators didn't exist in version <2.0, so set to 1 in case they are not overwritten. | // These attenuators didn't exist in version <2.0, so set to 1 in case they are not overwritten. | ||||
params[FEEDBACK_CV_PARAM].setValue(1.f); | params[FEEDBACK_CV_PARAM].setValue(1.f); | ||||
params[TONE_CV_PARAM].setValue(1.f); | params[TONE_CV_PARAM].setValue(1.f); | ||||
@@ -201,7 +201,7 @@ struct Delay : Module { | |||||
// The time input scaling has changed, so don't set to 1. | // The time input scaling has changed, so don't set to 1. | ||||
// params[TIME_CV_PARAM].setValue(1.f); | // params[TIME_CV_PARAM].setValue(1.f); | ||||
Module::fromJson(rootJ); | |||||
Module::paramsFromJson(rootJ); | |||||
} | } | ||||
}; | }; | ||||
@@ -6,7 +6,7 @@ struct Random : Module { | |||||
RATE_PARAM, | RATE_PARAM, | ||||
SHAPE_PARAM, | SHAPE_PARAM, | ||||
OFFSET_PARAM, | OFFSET_PARAM, | ||||
MODE_PARAM, | |||||
MODE_PARAM, // removed in 2.0 | |||||
// new in 2.0 | // new in 2.0 | ||||
PROB_PARAM, | PROB_PARAM, | ||||
RAND_PARAM, | RAND_PARAM, | ||||
@@ -148,7 +148,7 @@ struct Random : Module { | |||||
// Advance clock phase by rate | // Advance clock phase by rate | ||||
float rate = params[RATE_PARAM].getValue(); | float rate = params[RATE_PARAM].getValue(); | ||||
rate += inputs[RATE_PARAM].getVoltage() * params[RATE_CV_PARAM].getValue(); | rate += inputs[RATE_PARAM].getVoltage() * params[RATE_CV_PARAM].getValue(); | ||||
clockFreq = std::pow(2.f, rate); | |||||
clockFreq = 2.f * std::pow(2.f, rate); | |||||
deltaPhase = std::fmin(clockFreq * args.sampleTime, 0.5f); | deltaPhase = std::fmin(clockFreq * args.sampleTime, 0.5f); | ||||
clockPhase += deltaPhase; | clockPhase += deltaPhase; | ||||
// Trigger | // Trigger | ||||
@@ -233,7 +233,15 @@ struct Random : Module { | |||||
params[SHAPE_CV_PARAM].setValue(1.f); | params[SHAPE_CV_PARAM].setValue(1.f); | ||||
params[PROB_CV_PARAM].setValue(1.f); | params[PROB_CV_PARAM].setValue(1.f); | ||||
params[RAND_CV_PARAM].setValue(1.f); | params[RAND_CV_PARAM].setValue(1.f); | ||||
// In <2.0, mode=0 implied relative mode, corresponding to about 20% RND. | |||||
params[RAND_PARAM].setValue(0.2f); | |||||
Module::paramsFromJson(rootJ); | Module::paramsFromJson(rootJ); | ||||
// In <2.0, mode was used for absolute/relative mode. RND is a generalization so set it if mode is enabled. | |||||
if (params[MODE_PARAM].getValue() > 0.f) { | |||||
params[MODE_PARAM].setValue(0.f); | |||||
params[RAND_PARAM].setValue(1.f); | |||||
} | |||||
} | } | ||||
}; | }; | ||||
@@ -6,7 +6,7 @@ struct SEQ3 : Module { | |||||
TEMPO_PARAM, | TEMPO_PARAM, | ||||
RUN_PARAM, | RUN_PARAM, | ||||
RESET_PARAM, | RESET_PARAM, | ||||
STEPS_PARAM, | |||||
TRIG_PARAM, | |||||
ENUMS(CV_PARAMS, 3 * 8), | ENUMS(CV_PARAMS, 3 * 8), | ||||
ENUMS(GATE_PARAMS, 8), | ENUMS(GATE_PARAMS, 8), | ||||
// added in 2.0 | // added in 2.0 | ||||
@@ -24,7 +24,7 @@ struct SEQ3 : Module { | |||||
NUM_INPUTS | NUM_INPUTS | ||||
}; | }; | ||||
enum OutputIds { | enum OutputIds { | ||||
GATE_OUTPUT, | |||||
TRIG_OUTPUT, | |||||
ENUMS(CV_OUTPUTS, 3), | ENUMS(CV_OUTPUTS, 3), | ||||
ENUMS(STEP_OUTPUTS, 8), | ENUMS(STEP_OUTPUTS, 8), | ||||
// added in 2.0 | // added in 2.0 | ||||
@@ -44,6 +44,7 @@ struct SEQ3 : Module { | |||||
}; | }; | ||||
bool running = true; | bool running = true; | ||||
bool clockPassthrough = false; | |||||
dsp::BooleanTrigger runButtonTrigger; | dsp::BooleanTrigger runButtonTrigger; | ||||
dsp::BooleanTrigger resetButtonTrigger; | dsp::BooleanTrigger resetButtonTrigger; | ||||
@@ -69,18 +70,18 @@ struct SEQ3 : Module { | |||||
getParamQuantity(TEMPO_CV_PARAM)->randomizeEnabled = false; | getParamQuantity(TEMPO_CV_PARAM)->randomizeEnabled = false; | ||||
configButton(RUN_PARAM, "Run"); | configButton(RUN_PARAM, "Run"); | ||||
configButton(RESET_PARAM, "Reset"); | configButton(RESET_PARAM, "Reset"); | ||||
configParam(STEPS_PARAM, 1.f, 8.f, 8.f, "Steps"); | |||||
getParamQuantity(STEPS_PARAM)->randomizeEnabled = false; | |||||
configParam(TRIG_PARAM, 1.f, 8.f, 8.f, "Steps"); | |||||
getParamQuantity(TRIG_PARAM)->randomizeEnabled = false; | |||||
configParam(STEPS_CV_PARAM, 0.f, 1.f, 1.f, "Steps CV", "%", 0, 100); | configParam(STEPS_CV_PARAM, 0.f, 1.f, 1.f, "Steps CV", "%", 0, 100); | ||||
getParamQuantity(STEPS_CV_PARAM)->randomizeEnabled = false; | getParamQuantity(STEPS_CV_PARAM)->randomizeEnabled = false; | ||||
paramQuantities[STEPS_PARAM]->snapEnabled = true; | |||||
paramQuantities[TRIG_PARAM]->snapEnabled = true; | |||||
for (int j = 0; j < 3; j++) { | for (int j = 0; j < 3; j++) { | ||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
configParam(CV_PARAMS + 8 * j + i, -10.f, 10.f, 0.f, string::f("CV %d step %d", j + 1, i + 1), " V"); | configParam(CV_PARAMS + 8 * j + i, -10.f, 10.f, 0.f, string::f("CV %d step %d", j + 1, i + 1), " V"); | ||||
} | } | ||||
} | } | ||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
configButton(GATE_PARAMS + i, string::f("Step %d gate", i + 1)); | |||||
configButton(GATE_PARAMS + i, string::f("Step %d trigger", i + 1)); | |||||
} | } | ||||
configInput(TEMPO_INPUT, "Tempo"); | configInput(TEMPO_INPUT, "Tempo"); | ||||
@@ -95,7 +96,7 @@ struct SEQ3 : Module { | |||||
for (int j = 0; j < 3; j++) { | for (int j = 0; j < 3; j++) { | ||||
configOutput(CV_OUTPUTS + j, string::f("CV %d", j + 1)); | configOutput(CV_OUTPUTS + j, string::f("CV %d", j + 1)); | ||||
} | } | ||||
configOutput(GATE_OUTPUT, "Trigger"); | |||||
configOutput(TRIG_OUTPUT, "Trigger"); | |||||
configOutput(STEPS_OUTPUT, "Steps"); | configOutput(STEPS_OUTPUT, "Steps"); | ||||
configOutput(CLOCK_OUTPUT, "Clock"); | configOutput(CLOCK_OUTPUT, "Clock"); | ||||
configOutput(RUN_OUTPUT, "Run"); | configOutput(RUN_OUTPUT, "Run"); | ||||
@@ -107,6 +108,7 @@ struct SEQ3 : Module { | |||||
} | } | ||||
void onReset() override { | void onReset() override { | ||||
clockPassthrough = false; | |||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
gates[i] = true; | gates[i] = true; | ||||
} | } | ||||
@@ -164,6 +166,7 @@ struct SEQ3 : Module { | |||||
// Clock | // Clock | ||||
bool clock = false; | bool clock = false; | ||||
bool clockGate = false; | |||||
if (running) { | if (running) { | ||||
if (inputs[CLOCK_INPUT].isConnected()) { | if (inputs[CLOCK_INPUT].isConnected()) { | ||||
// External clock | // External clock | ||||
@@ -171,6 +174,7 @@ struct SEQ3 : Module { | |||||
if (clockTrigger.process(inputs[CLOCK_INPUT].getVoltage(), 0.1f, 2.f) && !resetGate) { | if (clockTrigger.process(inputs[CLOCK_INPUT].getVoltage(), 0.1f, 2.f) && !resetGate) { | ||||
clock = true; | clock = true; | ||||
} | } | ||||
clockGate = clockTrigger.isHigh(); | |||||
} | } | ||||
else { | else { | ||||
// Internal clock | // Internal clock | ||||
@@ -181,11 +185,12 @@ struct SEQ3 : Module { | |||||
clock = true; | clock = true; | ||||
} | } | ||||
phase -= std::trunc(phase); | phase -= std::trunc(phase); | ||||
clockGate = (phase < 0.5f); | |||||
} | } | ||||
} | } | ||||
// Get number of steps | // Get number of steps | ||||
float steps = params[STEPS_PARAM].getValue() + inputs[STEPS_INPUT].getVoltage() * params[STEPS_CV_PARAM].getValue(); | |||||
float steps = params[TRIG_PARAM].getValue() + inputs[STEPS_INPUT].getVoltage() * params[STEPS_CV_PARAM].getValue(); | |||||
int numSteps = (int) clamp(std::round(steps), 1.f, 8.f); | int numSteps = (int) clamp(std::round(steps), 1.f, 8.f); | ||||
// Advance step | // Advance step | ||||
@@ -195,7 +200,9 @@ struct SEQ3 : Module { | |||||
if (index >= numSteps) | if (index >= numSteps) | ||||
index = 0; | index = 0; | ||||
} | } | ||||
bool clockGate = clockPulse.process(args.sampleTime); | |||||
// Unless we're passing the clock gate, generate a pulse | |||||
if (!clockPassthrough) | |||||
clockGate = clockPulse.process(args.sampleTime); | |||||
// Gate buttons | // Gate buttons | ||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
@@ -215,7 +222,7 @@ struct SEQ3 : Module { | |||||
outputs[CV_OUTPUTS + 0].setVoltage(params[CV_PARAMS + 8 * 0 + index].getValue()); | outputs[CV_OUTPUTS + 0].setVoltage(params[CV_PARAMS + 8 * 0 + index].getValue()); | ||||
outputs[CV_OUTPUTS + 1].setVoltage(params[CV_PARAMS + 8 * 1 + index].getValue()); | outputs[CV_OUTPUTS + 1].setVoltage(params[CV_PARAMS + 8 * 1 + index].getValue()); | ||||
outputs[CV_OUTPUTS + 2].setVoltage(params[CV_PARAMS + 8 * 2 + index].getValue()); | outputs[CV_OUTPUTS + 2].setVoltage(params[CV_PARAMS + 8 * 2 + index].getValue()); | ||||
outputs[GATE_OUTPUT].setVoltage((clockGate && gates[index]) ? 10.f : 0.f); | |||||
outputs[TRIG_OUTPUT].setVoltage((clockGate && gates[index]) ? 10.f : 0.f); | |||||
outputs[STEPS_OUTPUT].setVoltage((numSteps - 1) * 1.f); | outputs[STEPS_OUTPUT].setVoltage((numSteps - 1) * 1.f); | ||||
outputs[CLOCK_OUTPUT].setVoltage(clockGate ? 10.f : 0.f); | outputs[CLOCK_OUTPUT].setVoltage(clockGate ? 10.f : 0.f); | ||||
@@ -240,6 +247,9 @@ struct SEQ3 : Module { | |||||
} | } | ||||
json_object_set_new(rootJ, "gates", gatesJ); | json_object_set_new(rootJ, "gates", gatesJ); | ||||
// clockPassthrough | |||||
json_object_set_new(rootJ, "clockPassthrough", json_boolean(clockPassthrough)); | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
@@ -258,6 +268,13 @@ struct SEQ3 : Module { | |||||
gates[i] = !!json_integer_value(gateJ); | gates[i] = !!json_integer_value(gateJ); | ||||
} | } | ||||
} | } | ||||
// clockPassthrough | |||||
json_t* clockPassthroughJ = json_object_get(rootJ, "clockPassthrough"); | |||||
if (clockPassthroughJ) | |||||
clockPassthrough = json_is_true(clockPassthroughJ); | |||||
else | |||||
clockPassthrough = true; | |||||
} | } | ||||
}; | }; | ||||
@@ -273,7 +290,7 @@ struct SEQ3Widget : ModuleWidget { | |||||
addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * 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<RoundLargeBlackKnob>(mm2px(Vec(11.753, 26.755)), module, SEQ3::TEMPO_PARAM)); | addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(11.753, 26.755)), module, SEQ3::TEMPO_PARAM)); | ||||
addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(32.077, 26.782)), module, SEQ3::STEPS_PARAM)); | |||||
addParam(createParamCentered<RoundLargeBlackKnob>(mm2px(Vec(32.077, 26.782)), module, SEQ3::TRIG_PARAM)); | |||||
addParam(createParamCentered<Trimpot>(mm2px(Vec(49.372, 34.066)), module, SEQ3::TEMPO_CV_PARAM)); | addParam(createParamCentered<Trimpot>(mm2px(Vec(49.372, 34.066)), module, SEQ3::TEMPO_CV_PARAM)); | ||||
addParam(createLightParamCentered<VCVLightButton<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(88.424, 33.679)), module, SEQ3::RUN_PARAM, SEQ3::RUN_LIGHT)); | addParam(createLightParamCentered<VCVLightButton<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(88.424, 33.679)), module, SEQ3::RUN_PARAM, SEQ3::RUN_LIGHT)); | ||||
addParam(createParamCentered<Trimpot>(mm2px(Vec(62.39, 34.066)), module, SEQ3::STEPS_CV_PARAM)); | addParam(createParamCentered<Trimpot>(mm2px(Vec(62.39, 34.066)), module, SEQ3::STEPS_CV_PARAM)); | ||||
@@ -333,7 +350,7 @@ struct SEQ3Widget : ModuleWidget { | |||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(10.319, 113.115)), module, SEQ3::CV_OUTPUTS + 0)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(10.319, 113.115)), module, SEQ3::CV_OUTPUTS + 0)); | ||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(23.336, 113.115)), module, SEQ3::CV_OUTPUTS + 1)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(23.336, 113.115)), module, SEQ3::CV_OUTPUTS + 1)); | ||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(36.354, 113.115)), module, SEQ3::CV_OUTPUTS + 2)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(36.354, 113.115)), module, SEQ3::CV_OUTPUTS + 2)); | ||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(49.371, 113.115)), module, SEQ3::GATE_OUTPUT)); | |||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(49.371, 113.115)), module, SEQ3::TRIG_OUTPUT)); | |||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(62.389, 113.115)), module, SEQ3::STEPS_OUTPUT)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(62.389, 113.115)), module, SEQ3::STEPS_OUTPUT)); | ||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(75.406, 113.115)), module, SEQ3::CLOCK_OUTPUT)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(75.406, 113.115)), module, SEQ3::CLOCK_OUTPUT)); | ||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(88.424, 113.115)), module, SEQ3::RUN_OUTPUT)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(88.424, 113.115)), module, SEQ3::RUN_OUTPUT)); | ||||
@@ -357,6 +374,10 @@ struct SEQ3Widget : ModuleWidget { | |||||
menu->addChild(new MenuSeparator); | menu->addChild(new MenuSeparator); | ||||
menu->addChild(createBoolPtrMenuItem("Clock passthrough", "", &module->clockPassthrough)); | |||||
menu->addChild(new MenuSeparator); | |||||
menu->addChild(createMenuItem("Rotate left", "", | menu->addChild(createMenuItem("Rotate left", "", | ||||
[=]() {module->rotateStates(-1);} | [=]() {module->rotateStates(-1);} | ||||
)); | )); | ||||
@@ -32,7 +32,7 @@ struct Sum : Module { | |||||
vuMeter.lambda = 1 / 0.1f; | vuMeter.lambda = 1 / 0.1f; | ||||
vuDivider.setDivision(16); | vuDivider.setDivision(16); | ||||
lightDivider.setDivision(256); | |||||
lightDivider.setDivision(512); | |||||
} | } | ||||
void process(const ProcessArgs& args) override { | void process(const ProcessArgs& args) override { | ||||
@@ -48,10 +48,12 @@ struct Sum : Module { | |||||
if (lightDivider.process()) { | if (lightDivider.process()) { | ||||
lastChannels = inputs[POLY_INPUT].getChannels(); | lastChannels = inputs[POLY_INPUT].getChannels(); | ||||
lights[VU_LIGHTS + 0].setBrightness(vuMeter.getBrightness(0.f, 0.f)); | |||||
for (int i = 1; i < 6; i++) { | |||||
lights[VU_LIGHTS + i].setBrightness(vuMeter.getBrightness(-3.f * i, -3.f * (i - 1))); | |||||
} | |||||
lights[VU_LIGHTS + 0].setBrightness(vuMeter.getBrightness(0, 0)); | |||||
lights[VU_LIGHTS + 1].setBrightness(vuMeter.getBrightness(-3, 0)); | |||||
lights[VU_LIGHTS + 2].setBrightness(vuMeter.getBrightness(-6, -3)); | |||||
lights[VU_LIGHTS + 3].setBrightness(vuMeter.getBrightness(-12, -6)); | |||||
lights[VU_LIGHTS + 4].setBrightness(vuMeter.getBrightness(-24, -12)); | |||||
lights[VU_LIGHTS + 5].setBrightness(vuMeter.getBrightness(-36, -24)); | |||||
} | } | ||||
} | } | ||||
}; | }; | ||||
@@ -59,11 +61,46 @@ struct Sum : Module { | |||||
struct SumDisplay : LedDisplay { | struct SumDisplay : LedDisplay { | ||||
Sum* module; | Sum* module; | ||||
void drawLayer(const DrawArgs& args, int layer) override { | |||||
if (layer == 1) { | |||||
static const std::vector<float> posY = { | |||||
mm2px(18.068 - 13.039), | |||||
mm2px(23.366 - 13.039), | |||||
mm2px(28.663 - 13.039), | |||||
mm2px(33.961 - 13.039), | |||||
mm2px(39.258 - 13.039), | |||||
mm2px(44.556 - 13.039), | |||||
}; | |||||
static const std::vector<std::string> texts = { | |||||
" 0", "-3", "-6", "-12", "-24", "-36", | |||||
}; | |||||
std::string fontPath = asset::system("res/fonts/Nunito-Bold.ttf"); | |||||
std::shared_ptr<Font> font = APP->window->loadFont(fontPath); | |||||
if (!font) | |||||
return; | |||||
nvgSave(args.vg); | |||||
nvgFontFaceId(args.vg, font->handle); | |||||
nvgFontSize(args.vg, 11); | |||||
nvgTextLetterSpacing(args.vg, 0.0); | |||||
nvgTextAlign(args.vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); | |||||
nvgFillColor(args.vg, nvgRGB(99, 99, 99)); | |||||
for (int i = 0; i < 6; i++) { | |||||
nvgText(args.vg, 15.0, posY[i], texts[i].c_str(), NULL); | |||||
} | |||||
nvgRestore(args.vg); | |||||
} | |||||
LedDisplay::drawLayer(args, layer); | |||||
} | |||||
}; | }; | ||||
struct SumChannelDisplay : ChannelDisplay { | struct SumChannelDisplay : ChannelDisplay { | ||||
Sum* module; | Sum* module; | ||||
void step() override { | void step() override { | ||||
int channels = 16; | int channels = 16; | ||||
if (module) | if (module) | ||||
@@ -89,18 +126,18 @@ struct SumWidget : ModuleWidget { | |||||
addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.62, 113.066)), module, Sum::MONO_OUTPUT)); | addOutput(createOutputCentered<PJ301MPort>(mm2px(Vec(7.62, 113.066)), module, Sum::MONO_OUTPUT)); | ||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 18.081)), module, Sum::VU_LIGHTS + 0)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 23.378)), module, Sum::VU_LIGHTS + 1)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 28.676)), module, Sum::VU_LIGHTS + 2)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 33.973)), module, Sum::VU_LIGHTS + 3)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 39.271)), module, Sum::VU_LIGHTS + 4)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.808, 44.568)), module, Sum::VU_LIGHTS + 5)); | |||||
SumDisplay* display = createWidget<SumDisplay>(mm2px(Vec(0.0, 12.834))); | SumDisplay* display = createWidget<SumDisplay>(mm2px(Vec(0.0, 12.834))); | ||||
display->box.size = mm2px(Vec(15.241, 36.981)); | display->box.size = mm2px(Vec(15.241, 36.981)); | ||||
display->module = module; | display->module = module; | ||||
addChild(display); | addChild(display); | ||||
addChild(createLightCentered<SmallSimpleLight<RedLight>>(mm2px(Vec(10.808, 18.081)), module, Sum::VU_LIGHTS + 0)); | |||||
addChild(createLightCentered<SmallSimpleLight<YellowLight>>(mm2px(Vec(10.808, 23.378)), module, Sum::VU_LIGHTS + 1)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenLight>>(mm2px(Vec(10.808, 28.676)), module, Sum::VU_LIGHTS + 2)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenLight>>(mm2px(Vec(10.808, 33.973)), module, Sum::VU_LIGHTS + 3)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenLight>>(mm2px(Vec(10.808, 39.271)), module, Sum::VU_LIGHTS + 4)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenLight>>(mm2px(Vec(10.808, 44.568)), module, Sum::VU_LIGHTS + 5)); | |||||
SumChannelDisplay* channelDisplay = createWidget<SumChannelDisplay>(mm2px(Vec(3.521, 77.191))); | SumChannelDisplay* channelDisplay = createWidget<SumChannelDisplay>(mm2px(Vec(3.521, 77.191))); | ||||
channelDisplay->box.size = mm2px(Vec(8.197, 8.197)); | channelDisplay->box.size = mm2px(Vec(8.197, 8.197)); | ||||
channelDisplay->module = module; | channelDisplay->module = module; | ||||
@@ -83,7 +83,7 @@ struct VizDisplay : LedDisplay { | |||||
else | else | ||||
nvgFillColor(args.vg, nvgRGB(99, 99, 99)); | nvgFillColor(args.vg, nvgRGB(99, 99, 99)); | ||||
std::string text = string::f("%d", c + 1); | std::string text = string::f("%d", c + 1); | ||||
nvgText(args.vg, 36.0, posY[c], text.c_str(), NULL); | |||||
nvgText(args.vg, 15.0, posY[c], text.c_str(), NULL); | |||||
} | } | ||||
nvgRestore(args.vg); | nvgRestore(args.vg); | ||||
} | } | ||||
@@ -104,27 +104,27 @@ struct VizWidget : ModuleWidget { | |||||
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.62, 113.115)), module, Viz::POLY_INPUT)); | addInput(createInputCentered<PJ301MPort>(mm2px(Vec(7.62, 113.115)), module, Viz::POLY_INPUT)); | ||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 18.068)), module, Viz::VU_LIGHTS + 0)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 23.366)), module, Viz::VU_LIGHTS + 1)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 28.663)), module, Viz::VU_LIGHTS + 2)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 33.961)), module, Viz::VU_LIGHTS + 3)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 39.258)), module, Viz::VU_LIGHTS + 4)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 44.556)), module, Viz::VU_LIGHTS + 5)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 49.919)), module, Viz::VU_LIGHTS + 6)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 55.217)), module, Viz::VU_LIGHTS + 7)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 60.514)), module, Viz::VU_LIGHTS + 8)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 65.812)), module, Viz::VU_LIGHTS + 9)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 71.109)), module, Viz::VU_LIGHTS + 10)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 76.473)), module, Viz::VU_LIGHTS + 11)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 81.771)), module, Viz::VU_LIGHTS + 12)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 87.068)), module, Viz::VU_LIGHTS + 13)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 92.366)), module, Viz::VU_LIGHTS + 14)); | |||||
addChild(createLightCentered<RedLight>(mm2px(Vec(10.846, 97.663)), module, Viz::VU_LIGHTS + 15)); | |||||
VizDisplay* display = createWidget<VizDisplay>(mm2px(Vec(0.003, 13.039))); | VizDisplay* display = createWidget<VizDisplay>(mm2px(Vec(0.003, 13.039))); | ||||
display->box.size = mm2px(Vec(15.237, 89.344)); | display->box.size = mm2px(Vec(15.237, 89.344)); | ||||
display->module = module; | display->module = module; | ||||
addChild(display); | addChild(display); | ||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 18.068)), module, Viz::VU_LIGHTS + 2 * 0)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 23.366)), module, Viz::VU_LIGHTS + 2 * 1)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 28.663)), module, Viz::VU_LIGHTS + 2 * 2)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 33.961)), module, Viz::VU_LIGHTS + 2 * 3)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 39.258)), module, Viz::VU_LIGHTS + 2 * 4)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 44.556)), module, Viz::VU_LIGHTS + 2 * 5)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 49.919)), module, Viz::VU_LIGHTS + 2 * 6)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 55.217)), module, Viz::VU_LIGHTS + 2 * 7)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 60.514)), module, Viz::VU_LIGHTS + 2 * 8)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 65.812)), module, Viz::VU_LIGHTS + 2 * 9)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 71.109)), module, Viz::VU_LIGHTS + 2 * 10)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 76.473)), module, Viz::VU_LIGHTS + 2 * 11)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 81.771)), module, Viz::VU_LIGHTS + 2 * 12)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 87.068)), module, Viz::VU_LIGHTS + 2 * 13)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 92.366)), module, Viz::VU_LIGHTS + 2 * 14)); | |||||
addChild(createLightCentered<SmallSimpleLight<GreenRedLight>>(mm2px(Vec(10.846, 97.663)), module, Viz::VU_LIGHTS + 2 * 15)); | |||||
} | } | ||||
}; | }; | ||||
@@ -226,6 +226,12 @@ struct WTLFO : Module { | |||||
} | } | ||||
} | } | ||||
void paramsFromJson(json_t* rootJ) override { | |||||
// In <2.0, there were no attenuverters, so set them to 1.0 in case they are not overwritten. | |||||
params[POS_CV_PARAM].setValue(1.f); | |||||
Module::paramsFromJson(rootJ); | |||||
} | |||||
json_t* dataToJson() override { | json_t* dataToJson() override { | ||||
json_t* rootJ = json_object(); | json_t* rootJ = json_object(); | ||||
// Merge wavetable | // Merge wavetable | ||||
@@ -258,6 +258,12 @@ struct WTVCO : Module { | |||||
} | } | ||||
} | } | ||||
void paramsFromJson(json_t* rootJ) override { | |||||
// In <2.0, there were no attenuverters, so set them to 1.0 in case they are not overwritten. | |||||
params[POS_CV_PARAM].setValue(1.f); | |||||
Module::paramsFromJson(rootJ); | |||||
} | |||||
json_t* dataToJson() override { | json_t* dataToJson() override { | ||||
json_t* rootJ = json_object(); | json_t* rootJ = json_object(); | ||||
// Merge wavetable | // Merge wavetable | ||||