| @@ -72,12 +72,12 @@ _8VERTWidget::_8VERTWidget() { | |||
| addOutput(createOutput<PJ301MPort>(Vec(86.393, 281.059), module, 6)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(86.393, 319.504), module, 7)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 50.414), &module->lights[0].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 88.859), &module->lights[1].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 127.304), &module->lights[2].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 165.745), &module->lights[3].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 204.19), &module->lights[4].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 242.635), &module->lights[5].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 281.076), &module->lights[6].value)); | |||
| addChild(createValueLight<TinyLight<GreenRedPolarityLight>>(Vec(107.702, 319.521), &module->lights[7].value)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 50.414), module, 0)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 88.859), module, 1)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 127.304), module, 2)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 165.745), module, 3)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 204.19), module, 4)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 242.635), module, 5)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 281.076), module, 6)); | |||
| addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 319.521), module, 7)); | |||
| } | |||
| @@ -23,13 +23,19 @@ struct ADSR : Module { | |||
| ENVELOPE_OUTPUT, | |||
| NUM_OUTPUTS | |||
| }; | |||
| enum LightIds { | |||
| ATTACK_LIGHT, | |||
| DECAY_LIGHT, | |||
| SUSTAIN_LIGHT, | |||
| RELEASE_LIGHT, | |||
| NUM_LIGHTS | |||
| }; | |||
| bool decaying = false; | |||
| float env = 0.0; | |||
| SchmittTrigger trigger; | |||
| float lights[4] = {}; | |||
| ADSR() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | |||
| ADSR() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { | |||
| trigger.setThresholds(0.0, 1.0); | |||
| } | |||
| void step() override; | |||
| @@ -43,10 +49,10 @@ void ADSR::step() { | |||
| float release = clampf(params[RELEASE_PARAM].value + inputs[RELEASE_PARAM].value / 10.0, 0.0, 1.0); | |||
| // Lights | |||
| lights[0] = 2.0*attack - 1.0; | |||
| lights[1] = 2.0*decay - 1.0; | |||
| lights[2] = 2.0*sustain - 1.0; | |||
| lights[3] = 2.0*release - 1.0; | |||
| lights[ATTACK_LIGHT].value = 2.0*attack - 1.0; | |||
| lights[DECAY_LIGHT].value = 2.0*decay - 1.0; | |||
| lights[SUSTAIN_LIGHT].value = 2.0*sustain - 1.0; | |||
| lights[RELEASE_LIGHT].value = 2.0*release - 1.0; | |||
| // Gate and trigger | |||
| bool gated = inputs[GATE_INPUT].value >= 1.0; | |||
| @@ -126,8 +132,8 @@ ADSRWidget::ADSRWidget() { | |||
| addInput(createInput<PJ301MPort>(Vec(48, 320), module, ADSR::TRIG_INPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(87, 320), module, ADSR::ENVELOPE_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(94, 41), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(94, 108), &module->lights[1])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(94, 175), &module->lights[2])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(94, 241), &module->lights[3])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 41), module, ADSR::ATTACK_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 108), module, ADSR::DECAY_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 175), module, ADSR::SUSTAIN_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 241), module, ADSR::RELEASE_LIGHT)); | |||
| } | |||
| @@ -90,11 +90,14 @@ struct LFO : Module { | |||
| SQR_OUTPUT, | |||
| NUM_OUTPUTS | |||
| }; | |||
| enum LightIds { | |||
| PHASE_LIGHT, | |||
| NUM_LIGHTS | |||
| }; | |||
| LFOGenerator generator; | |||
| float lights[1] = {}; | |||
| LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
| LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
| void step() override; | |||
| }; | |||
| @@ -112,7 +115,7 @@ void LFO::step() { | |||
| outputs[SAW_OUTPUT].value = 5.0 * generator.saw(); | |||
| outputs[SQR_OUTPUT].value = 5.0 * generator.sqr(); | |||
| lights[0] = generator.light(); | |||
| lights[PHASE_LIGHT].value = generator.light(); | |||
| } | |||
| @@ -152,7 +155,7 @@ LFOWidget::LFOWidget() { | |||
| addOutput(createOutput<PJ301MPort>(Vec(80, 320), module, LFO::SAW_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(114, 320), module, LFO::SQR_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(99, 42), &module->lights[0])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(99, 42), module, LFO::PHASE_LIGHT)); | |||
| } | |||
| @@ -176,11 +179,14 @@ struct LFO2 : Module { | |||
| INTERP_OUTPUT, | |||
| NUM_OUTPUTS | |||
| }; | |||
| enum LightIds { | |||
| PHASE_LIGHT, | |||
| NUM_LIGHTS | |||
| }; | |||
| LFOGenerator generator; | |||
| float lights[1] = {}; | |||
| LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
| LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
| void step() override; | |||
| }; | |||
| @@ -203,7 +209,7 @@ void LFO2::step() { | |||
| interp = crossf(generator.saw(), generator.sqr(), wave - 2.0); | |||
| outputs[INTERP_OUTPUT].value = 5.0 * interp; | |||
| lights[0] = generator.light(); | |||
| lights[PHASE_LIGHT].value = generator.light(); | |||
| } | |||
| @@ -237,5 +243,5 @@ LFO2Widget::LFO2Widget() { | |||
| addOutput(createOutput<PJ301MPort>(Vec(54, 319), module, LFO2::INTERP_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(68, 41), &module->lights[0])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, LFO2::PHASE_LIGHT)); | |||
| } | |||
| @@ -29,6 +29,14 @@ struct SEQ3 : Module { | |||
| GATE_OUTPUT, | |||
| NUM_OUTPUTS = GATE_OUTPUT + 8 | |||
| }; | |||
| enum LightIds { | |||
| RUNNING_LIGHT, | |||
| RESET_LIGHT, | |||
| GATES_LIGHT, | |||
| ROW_LIGHTS, | |||
| GATE_LIGHTS = ROW_LIGHTS + 3, | |||
| NUM_LIGHTS = GATE_LIGHTS + 8 | |||
| }; | |||
| bool running = true; | |||
| SchmittTrigger clockTrigger; // for external clock | |||
| @@ -39,6 +47,7 @@ struct SEQ3 : Module { | |||
| float phase = 0.0; | |||
| int index = 0; | |||
| bool gateState[8] = {}; | |||
| float resetLight = 0.0; | |||
| float stepLights[8] = {}; | |||
| enum GateMode { | |||
| @@ -49,14 +58,7 @@ struct SEQ3 : Module { | |||
| GateMode gateMode = TRIGGER; | |||
| PulseGenerator gatePulse; | |||
| // Lights | |||
| float runningLight = 0.0; | |||
| float resetLight = 0.0; | |||
| float gatesLight = 0.0; | |||
| float rowLights[3] = {}; | |||
| float gateLights[8] = {}; | |||
| SEQ3() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
| SEQ3() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
| void step() override; | |||
| json_t *toJson() override { | |||
| @@ -122,7 +124,7 @@ void SEQ3::step() { | |||
| if (runningTrigger.process(params[RUN_PARAM].value)) { | |||
| running = !running; | |||
| } | |||
| runningLight = running ? 1.0 : 0.0; | |||
| lights[RUNNING_LIGHT].value = running ? 1.0 : 0.0; | |||
| bool nextStep = false; | |||
| @@ -181,7 +183,7 @@ void SEQ3::step() { | |||
| outputs[GATE_OUTPUT + i].value = gateOn ? 10.0 : 0.0; | |||
| stepLights[i] -= stepLights[i] / lightLambda / engineGetSampleRate(); | |||
| gateLights[i] = gateState[i] ? 1.0 - stepLights[i] : stepLights[i]; | |||
| lights[GATE_LIGHTS + i].value = gateState[i] ? 1.0 - stepLights[i] : stepLights[i]; | |||
| } | |||
| // Rows | |||
| @@ -199,10 +201,11 @@ void SEQ3::step() { | |||
| outputs[ROW2_OUTPUT].value = row2; | |||
| outputs[ROW3_OUTPUT].value = row3; | |||
| outputs[GATES_OUTPUT].value = gatesOn ? 10.0 : 0.0; | |||
| gatesLight = gatesOn ? 1.0 : 0.0; | |||
| rowLights[0] = row1; | |||
| rowLights[1] = row2; | |||
| rowLights[2] = row3; | |||
| lights[RESET_LIGHT].value = resetLight; | |||
| lights[GATES_LIGHT].value = gatesOn ? 1.0 : 0.0; | |||
| lights[ROW_LIGHTS].value = row1; | |||
| lights[ROW_LIGHTS + 1].value = row2; | |||
| lights[ROW_LIGHTS + 2].value = row3; | |||
| } | |||
| @@ -225,14 +228,14 @@ SEQ3Widget::SEQ3Widget() { | |||
| addParam(createParam<RoundSmallBlackKnob>(Vec(18, 56), module, SEQ3::CLOCK_PARAM, -2.0, 6.0, 2.0)); | |||
| addParam(createParam<LEDButton>(Vec(60, 61-1), module, SEQ3::RUN_PARAM, 0.0, 1.0, 0.0)); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(65, 65), &module->runningLight)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(65, 65), module, SEQ3::RUNNING_LIGHT)); | |||
| addParam(createParam<LEDButton>(Vec(99, 61-1), module, SEQ3::RESET_PARAM, 0.0, 1.0, 0.0)); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(104, 65), &module->resetLight)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(104, 65), module, SEQ3::RESET_LIGHT)); | |||
| addParam(createParam<RoundSmallBlackSnapKnob>(Vec(132, 56), module, SEQ3::STEPS_PARAM, 1.0, 8.0, 8.0)); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(180, 65), &module->gatesLight)); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(219, 65), &module->rowLights[0])); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(257, 65), &module->rowLights[1])); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(296, 65), &module->rowLights[2])); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(180, 65), module, SEQ3::GATES_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(219, 65), module, SEQ3::ROW_LIGHTS)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(257, 65), module, SEQ3::ROW_LIGHTS + 1)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(296, 65), module, SEQ3::ROW_LIGHTS + 2)); | |||
| static const float portX[8] = {20, 58, 96, 135, 173, 212, 250, 289}; | |||
| addInput(createInput<PJ301MPort>(Vec(portX[0]-1, 98), module, SEQ3::CLOCK_INPUT)); | |||
| @@ -249,7 +252,7 @@ SEQ3Widget::SEQ3Widget() { | |||
| addParam(createParam<RoundSmallBlackKnob>(Vec(portX[i]-2, 198), module, SEQ3::ROW2_PARAM + i, 0.0, 6.0, 0.0)); | |||
| addParam(createParam<RoundSmallBlackKnob>(Vec(portX[i]-2, 240), module, SEQ3::ROW3_PARAM + i, 0.0, 6.0, 0.0)); | |||
| addParam(createParam<LEDButton>(Vec(portX[i]+2, 278-1), module, SEQ3::GATE_PARAM + i, 0.0, 1.0, 0.0)); | |||
| addChild(createValueLight<SmallLight<GreenValueLight>>(Vec(portX[i]+7, 282), &module->gateLights[i])); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(portX[i]+7, 282), module, SEQ3::GATE_LIGHTS + i)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(portX[i]-1, 307), module, SEQ3::GATE_OUTPUT + i)); | |||
| } | |||
| } | |||
| @@ -26,6 +26,13 @@ struct Scope : Module { | |||
| enum OutputIds { | |||
| NUM_OUTPUTS | |||
| }; | |||
| enum LightIds { | |||
| LISSAJOUS_LIGHT, | |||
| NOT_LISSAJOUS_LIGHT, // FIXME: what should this be called? | |||
| EXTERNAL_LIGHT, | |||
| INTERNAL_LIGHT, | |||
| NUM_LIGHTS | |||
| }; | |||
| float bufferX[BUFFER_SIZE] = {}; | |||
| float bufferY[BUFFER_SIZE] = {}; | |||
| @@ -36,10 +43,9 @@ struct Scope : Module { | |||
| SchmittTrigger extTrigger; | |||
| bool lissajous = false; | |||
| bool external = false; | |||
| float lights[4] = {}; | |||
| SchmittTrigger resetTrigger; | |||
| Scope() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} | |||
| Scope() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
| void step() override; | |||
| json_t *toJson() override { | |||
| @@ -71,14 +77,14 @@ void Scope::step() { | |||
| if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | |||
| lissajous = !lissajous; | |||
| } | |||
| lights[0] = lissajous ? 0.0 : 1.0; | |||
| lights[1] = lissajous ? 1.0 : 0.0; | |||
| lights[LISSAJOUS_LIGHT].value = lissajous ? 0.0 : 1.0; | |||
| lights[NOT_LISSAJOUS_LIGHT].value = lissajous ? 1.0 : 0.0; | |||
| if (extTrigger.process(params[EXTERNAL_PARAM].value)) { | |||
| external = !external; | |||
| } | |||
| lights[2] = external ? 0.0 : 1.0; | |||
| lights[3] = external ? 1.0 : 0.0; | |||
| lights[EXTERNAL_LIGHT].value = external ? 0.0 : 1.0; | |||
| lights[INTERNAL_LIGHT].value = external ? 1.0 : 0.0; | |||
| // Compute time | |||
| float deltaTime = powf(2.0, params[TIME_PARAM].value); | |||
| @@ -332,8 +338,8 @@ ScopeWidget::ScopeWidget() { | |||
| addInput(createInput<PJ301MPort>(Vec(63, 319), module, Scope::Y_INPUT)); | |||
| addInput(createInput<PJ301MPort>(Vec(154, 319), module, Scope::TRIG_INPUT)); | |||
| addChild(createValueLight<TinyLight<GreenValueLight>>(Vec(104, 251), &module->lights[0])); | |||
| addChild(createValueLight<TinyLight<GreenValueLight>>(Vec(104, 296), &module->lights[1])); | |||
| addChild(createValueLight<TinyLight<GreenValueLight>>(Vec(150, 251), &module->lights[2])); | |||
| addChild(createValueLight<TinyLight<GreenValueLight>>(Vec(150, 296), &module->lights[3])); | |||
| addChild(createLight<TinyLight<GreenLight>>(Vec(104, 251), module, Scope::LISSAJOUS_LIGHT)); | |||
| addChild(createLight<TinyLight<GreenLight>>(Vec(104, 296), module, Scope::NOT_LISSAJOUS_LIGHT)); | |||
| addChild(createLight<TinyLight<GreenLight>>(Vec(150, 251), module, Scope::EXTERNAL_LIGHT)); | |||
| addChild(createLight<TinyLight<GreenLight>>(Vec(150, 296), module, Scope::INTERNAL_LIGHT)); | |||
| } | |||