diff --git a/src/Blinds.cpp b/src/Blinds.cpp index f494c51..2038cea 100644 --- a/src/Blinds.cpp +++ b/src/Blinds.cpp @@ -32,48 +32,38 @@ struct Blinds : Module { OUT4_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + IN1_POS_LIGHT, IN1_NEG_LIGHT, + IN2_POS_LIGHT, IN2_NEG_LIGHT, + IN3_POS_LIGHT, IN3_NEG_LIGHT, + IN4_POS_LIGHT, IN4_NEG_LIGHT, + OUT1_POS_LIGHT, OUT1_NEG_LIGHT, + OUT2_POS_LIGHT, OUT2_NEG_LIGHT, + OUT3_POS_LIGHT, OUT3_NEG_LIGHT, + OUT4_POS_LIGHT, OUT4_NEG_LIGHT, + NUM_LIGHTS + }; - float lights[4] = {}; - float gainLights[4] = {}; - - Blinds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + Blinds() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; }; -static float processChannel(Input &in, Param &gain, Input &cv, Param &mod, float *light) { - float g = gain.value + mod.value * cv.value / 5.0; - *light = g * 5.0; - return g * in.normalize(5.0); -} - void Blinds::step() { float out = 0.0; - out += processChannel(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[MOD1_PARAM], &gainLights[0]); - lights[0] = out; - if (outputs[OUT1_OUTPUT].active) { - outputs[OUT1_OUTPUT].value = out; - out = 0.0; - } - - out += processChannel(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[MOD2_PARAM], &gainLights[1]); - lights[1] = out; - if (outputs[OUT2_OUTPUT].active) { - outputs[OUT2_OUTPUT].value = out; - out = 0.0; - } - - out += processChannel(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[MOD3_PARAM], &gainLights[2]); - lights[2] = out; - if (outputs[OUT3_OUTPUT].active) { - outputs[OUT3_OUTPUT].value = out; - out = 0.0; - } - out += processChannel(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[MOD4_PARAM], &gainLights[3]); - lights[3] = out; - if (outputs[OUT4_OUTPUT].active) { - outputs[OUT4_OUTPUT].value = out; + for (int i = 0; i < 4; i++) { + float g = params[GAIN1_PARAM + i].value; + g += params[MOD1_PARAM + i].value * inputs[CV1_INPUT + i].value / 5.0; + lights[IN1_POS_LIGHT + 2*i].setBrightness(fmaxf(0.0, g)); + lights[IN1_NEG_LIGHT + 2*i].setBrightness(fmaxf(0.0, -g)); + out += g * inputs[IN1_INPUT + i].normalize(5.0); + lights[OUT1_POS_LIGHT + 2*i].setBrightness(fmaxf(0.0, out)); + lights[OUT1_NEG_LIGHT + 2*i].setBrightness(fmaxf(0.0, -out)); + if (outputs[OUT1_OUTPUT + i].active) { + outputs[OUT1_OUTPUT + i].value = out; + out = 0.0; + } } } @@ -120,13 +110,13 @@ BlindsWidget::BlindsWidget() { addOutput(createOutput(Vec(144, 198), module, Blinds::OUT3_OUTPUT)); addOutput(createOutput(Vec(144, 277), module, Blinds::OUT4_OUTPUT)); - addChild(createValueLight>(Vec(150, 87), &module->lights[0])); - addChild(createValueLight>(Vec(150, 166), &module->lights[1])); - addChild(createValueLight>(Vec(150, 245), &module->lights[2])); - addChild(createValueLight>(Vec(150, 324), &module->lights[3])); + addChild(createLight>(Vec(150, 87), module, Blinds::IN1_POS_LIGHT)); + addChild(createLight>(Vec(150, 166), module, Blinds::IN2_POS_LIGHT)); + addChild(createLight>(Vec(150, 245), module, Blinds::IN3_POS_LIGHT)); + addChild(createLight>(Vec(150, 324), module, Blinds::IN4_POS_LIGHT)); - addChild(createValueLight>(Vec(77, 96), &module->gainLights[0])); - addChild(createValueLight>(Vec(77, 175), &module->gainLights[1])); - addChild(createValueLight>(Vec(77, 254), &module->gainLights[2])); - addChild(createValueLight>(Vec(77, 333), &module->gainLights[3])); + addChild(createLight>(Vec(77, 96), module, Blinds::OUT1_POS_LIGHT)); + addChild(createLight>(Vec(77, 175), module, Blinds::OUT2_POS_LIGHT)); + addChild(createLight>(Vec(77, 254), module, Blinds::OUT3_POS_LIGHT)); + addChild(createLight>(Vec(77, 333), module, Blinds::OUT4_POS_LIGHT)); } diff --git a/src/Branches.cpp b/src/Branches.cpp index 74809a2..8e00a11 100644 --- a/src/Branches.cpp +++ b/src/Branches.cpp @@ -11,54 +11,55 @@ struct Branches : Module { }; enum InputIds { IN1_INPUT, - P1_INPUT, IN2_INPUT, + P1_INPUT, P2_INPUT, NUM_INPUTS }; enum OutputIds { OUT1A_OUTPUT, - OUT1B_OUTPUT, OUT2A_OUTPUT, + OUT1B_OUTPUT, OUT2B_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + STATE1_LIGHT, + STATE2_LIGHT, + NUM_LIGHTS + }; bool lastGate[2] = {}; bool outcome[2] = {}; - float light[2] = {}; - Branches() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + Branches() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; }; -static void processChannel(Input &in, Input &p, Param &threshold, Param &mode, bool *lastGate, bool *outcome, Output &out1, Output &out2, float *light) { - float out = in.value; - bool gate = (out >= 1.0); - if (gate && !*lastGate) { - // trigger - float r = randomf(); - bool toss = (r < threshold.value + p.value); - if (mode.value < 0.5) { - // direct mode - *outcome = toss; - } - else { - // toggle mode - *outcome = *outcome != toss; +void Branches::step() { + for (int i = 0; i < 2; i++) { + float out = inputs[IN1_INPUT + i].value; + bool gate = (out >= 1.0); + if (gate && !lastGate[i]) { + // trigger + float r = randomf(); + bool toss = (r < params[THRESHOLD1_PARAM + i].value + inputs[P1_INPUT + i].value); + if (params[MODE1_PARAM + i].value < 0.5) { + // direct mode + outcome[i] = toss; + } + else { + // toggle mode + outcome[i] = outcome[i] != toss; + } } - } - *lastGate = gate; - *light = *outcome ? out : -out; - - out1.value = *outcome ? 0.0 : out; - out2.value = *outcome ? out : 0.0; -} + lastGate[i] = gate; + lights[STATE1_LIGHT + i].value = outcome[i] ? out : -out; -void Branches::step() { - processChannel(inputs[IN1_INPUT], inputs[P1_INPUT], params[THRESHOLD1_PARAM], params[MODE1_PARAM], &lastGate[0], &outcome[0], outputs[OUT1A_OUTPUT], outputs[OUT1B_OUTPUT], &light[0]); - processChannel(inputs[IN2_INPUT].active ? inputs[IN2_INPUT] : inputs[IN1_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]); + outputs[OUT1A_OUTPUT + i].value = outcome[i] ? 0.0 : out; + outputs[OUT1B_OUTPUT + i].value = outcome[i] ? out : 0.0; + } } @@ -91,6 +92,6 @@ BranchesWidget::BranchesWidget() { addOutput(createOutput(Vec(9, 316), module, Branches::OUT2A_OUTPUT)); addOutput(createOutput(Vec(55, 316), module, Branches::OUT2B_OUTPUT)); - addChild(createValueLight>(Vec(40, 169), &module->light[0])); - addChild(createValueLight>(Vec(40, 325), &module->light[1])); + addChild(createLight>(Vec(40, 169), module, Branches::STATE1_LIGHT)); + addChild(createLight>(Vec(40, 325), module, Branches::STATE2_LIGHT)); } diff --git a/src/Elements.cpp b/src/Elements.cpp index 4f97667..793f615 100644 --- a/src/Elements.cpp +++ b/src/Elements.cpp @@ -66,6 +66,11 @@ struct Elements : Module { MAIN_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + EXCITER_LIGHT, + RESONATOR_LIGHT, + NUM_LIGHTS + }; SampleRateConverter<2> inputSrc; SampleRateConverter<2> outputSrc; @@ -74,7 +79,6 @@ struct Elements : Module { uint16_t reverb_buffer[32768] = {}; elements::Part *part; - float lights[2] = {}; Elements(); ~Elements(); @@ -103,7 +107,7 @@ struct Elements : Module { }; -Elements::Elements() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { +Elements::Elements() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { part = new elements::Part(); // In the Mutable Instruments code, Part doesn't initialize itself, so zero it here. memset(part, 0, sizeof(*part)); @@ -194,8 +198,8 @@ void Elements::step() { } // Set lights - lights[0] = part->exciter_level(); - lights[1] = part->resonator_level(); + lights[EXCITER_LIGHT].value = part->exciter_level(); + lights[RESONATOR_LIGHT].value = part->resonator_level(); } // Set output @@ -280,8 +284,8 @@ ElementsWidget::ElementsWidget() { addParam(createParam(Vec(36, 116), module, Elements::PLAY_PARAM, 0.0, 1.0, 0.0)); - addChild(createValueLight>(Vec(184, 165), &module->lights[0])); - addChild(createValueLight>(Vec(395, 165), &module->lights[1])); + addChild(createLight>(Vec(184, 165), module, Elements::EXCITER_LIGHT)); + addChild(createLight>(Vec(395, 165), module, Elements::RESONATOR_LIGHT)); } struct ElementsModalItem : MenuItem { diff --git a/src/Frames.cpp b/src/Frames.cpp index dedd90e..cea082b 100644 --- a/src/Frames.cpp +++ b/src/Frames.cpp @@ -34,10 +34,13 @@ struct Frames : Module { OUT3_OUTPUT, OUT4_OUTPUT, FRAME_STEP_OUTPUT, + NUM_OUTPUTS + }; + enum LightIds { GAIN1_LIGHT, EDIT_LIGHT = GAIN1_LIGHT + 4, FRAME_LIGHT, - NUM_OUTPUTS = FRAME_LIGHT + 3 + NUM_LIGHTS = FRAME_LIGHT + 3 }; frames::Keyframer keyframer; @@ -101,12 +104,12 @@ struct Frames : Module { } void randomize() override { // TODO - // Maybe something useful should go in here?? + // Maybe something useful should go in here? } }; -Frames::Frames() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { +Frames::Frames() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { memset(&keyframer, 0, sizeof(keyframer)); keyframer.Init(); memset(&poly_lfo, 0, sizeof(poly_lfo)); @@ -219,15 +222,14 @@ void Frames::step() { // Set lights for (int i = 0; i < 4; i++) { - outputs[GAIN1_LIGHT + i].value = gains[i]; + lights[GAIN1_LIGHT + i].value = gains[i]; } if (poly_lfo_mode) { - outputs[EDIT_LIGHT].value = (poly_lfo.level(0) > 128 ? 1.0 : 0.0); + lights[EDIT_LIGHT].value = (poly_lfo.level(0) > 128 ? 1.0 : 0.0); } else { - // TODO - outputs[EDIT_LIGHT].value = (nearestIndex >= 0 ? 1.0 : 0.0); + lights[EDIT_LIGHT].value = (nearestIndex >= 0 ? 1.0 : 0.0); } // Set frame light colors @@ -239,32 +241,11 @@ void Frames::step() { colors = keyframer.color(); } for (int c = 0; c < 3; c++) { - outputs[FRAME_LIGHT + c].value = colors[c] / 255.0; + lights[FRAME_LIGHT + c].value = colors[c] / 255.0; } } -struct FramesLight : LightWidget { - float *colors[3]; - FramesLight() { - box.size = Vec(67, 67); - } - void step() override { - const NVGcolor red = COLOR_RED; - const NVGcolor green = COLOR_GREEN; - const NVGcolor blue = COLOR_BLUE; - float r = *colors[0]; - float g = *colors[1]; - float b = *colors[2]; - color.r = red.r * r + green.r * g + blue.r * b; - color.g = red.g * r + green.g * g + blue.g * b; - color.b = red.b * r + green.b * g + blue.b * b; - color.a = 1.0; - // Lighten - color = nvgLerpRGBA(color, COLOR_WHITE, 0.5); - } -}; - struct CKSSRot : SVGSwitch, ToggleSwitch { CKSSRot() { addFrame(SVG::load(assetPlugin(plugin, "res/CKSS_rot_0.svg"))); @@ -316,17 +297,17 @@ FramesWidget::FramesWidget() { addOutput(createOutput(Vec(188, 315), module, Frames::OUT4_OUTPUT)); addOutput(createOutput(Vec(231, 315), module, Frames::FRAME_STEP_OUTPUT)); - addChild(createValueLight>(Vec(30, 101), &module->outputs[Frames::GAIN1_LIGHT + 0].value)); - addChild(createValueLight>(Vec(97, 101), &module->outputs[Frames::GAIN1_LIGHT + 1].value)); - addChild(createValueLight>(Vec(165, 101), &module->outputs[Frames::GAIN1_LIGHT + 2].value)); - addChild(createValueLight>(Vec(232, 101), &module->outputs[Frames::GAIN1_LIGHT + 3].value)); - addChild(createValueLight>(Vec(61, 155), &module->outputs[Frames::EDIT_LIGHT].value)); + addChild(createLight>(Vec(30, 101), module, Frames::GAIN1_LIGHT + 0)); + addChild(createLight>(Vec(97, 101), module, Frames::GAIN1_LIGHT + 1)); + addChild(createLight>(Vec(165, 101), module, Frames::GAIN1_LIGHT + 2)); + addChild(createLight>(Vec(232, 101), module, Frames::GAIN1_LIGHT + 3)); + addChild(createLight>(Vec(61, 155), module, Frames::EDIT_LIGHT)); { - FramesLight *framesLight = new FramesLight(); + RedGreenBlueLight *framesLight = new RedGreenBlueLight(); framesLight->box.pos = Vec(102, 128); - framesLight->colors[0] = &module->outputs[Frames::FRAME_LIGHT + 0].value; - framesLight->colors[1] = &module->outputs[Frames::FRAME_LIGHT + 1].value; - framesLight->colors[2] = &module->outputs[Frames::FRAME_LIGHT + 2].value; + framesLight->box.size = Vec(67, 67); + framesLight->module = module; + framesLight->lightId = Frames::FRAME_LIGHT; addChild(framesLight); } } diff --git a/src/Kinks.cpp b/src/Kinks.cpp index 1404582..eba809c 100644 --- a/src/Kinks.cpp +++ b/src/Kinks.cpp @@ -24,12 +24,17 @@ struct Kinks : Module { SH_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + SIGN_POS_LIGHT, SIGN_NEG_LIGHT, + LOGIC_POS_LIGHT, LOGIC_NEG_LIGHT, + SH_POS_LIGHT, SH_NEG_LIGHT, + NUM_LIGHTS + }; SchmittTrigger trigger; float sample = 0.0; - float lights[3] = {}; - Kinks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { + Kinks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { trigger.setThresholds(0.0, 0.7); } void step() override; @@ -46,9 +51,13 @@ void Kinks::step() { } // lights - lights[0] = inputs[SIGN_INPUT].value; - lights[1] = inputs[LOGIC_A_INPUT].value + inputs[LOGIC_B_INPUT].value; - lights[2] = sample; + lights[SIGN_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, inputs[SIGN_INPUT].value / 5.0)); + lights[SIGN_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -inputs[SIGN_INPUT].value / 5.0)); + float logicSum = inputs[LOGIC_A_INPUT].value + inputs[LOGIC_B_INPUT].value; + lights[LOGIC_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, logicSum / 5.0)); + lights[LOGIC_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -logicSum / 5.0)); + lights[SH_POS_LIGHT].setBrightness(fmaxf(0.0, sample / 5.0)); + lights[SH_NEG_LIGHT].setBrightness(fmaxf(0.0, -sample / 5.0)); // outputs outputs[INVERT_OUTPUT].value = -inputs[SIGN_INPUT].value; @@ -91,7 +100,7 @@ KinksWidget::KinksWidget() { addOutput(createOutput(Vec(4, 316), module, Kinks::NOISE_OUTPUT)); addOutput(createOutput(Vec(31, 316), module, Kinks::SH_OUTPUT)); - addChild(createValueLight>(Vec(11, 59), &module->lights[0])); - addChild(createValueLight>(Vec(11, 161), &module->lights[1])); - addChild(createValueLight>(Vec(11, 262), &module->lights[2])); + addChild(createLight>(Vec(11, 59), module, Kinks::SIGN_POS_LIGHT)); + addChild(createLight>(Vec(11, 161), module, Kinks::LOGIC_POS_LIGHT)); + addChild(createLight>(Vec(11, 262), module, Kinks::SH_POS_LIGHT)); } diff --git a/src/Links.cpp b/src/Links.cpp index 68262ab..55b040d 100644 --- a/src/Links.cpp +++ b/src/Links.cpp @@ -23,28 +23,36 @@ struct Links : Module { C1_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + A_POS_LIGHT, A_NEG_LIGHT, + B_POS_LIGHT, B_NEG_LIGHT, + C_POS_LIGHT, C_NEG_LIGHT, + NUM_LIGHTS + }; - float lights[3] = {}; - Links() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + Links() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; }; void Links::step() { - float in1 = inputs[A1_INPUT].value; - float in2 = inputs[B1_INPUT].value + inputs[B2_INPUT].value; - float in3 = inputs[C1_INPUT].value + inputs[C2_INPUT].value + inputs[C3_INPUT].value; + float inA = inputs[A1_INPUT].value; + float inB = inputs[B1_INPUT].value + inputs[B2_INPUT].value; + float inC = inputs[C1_INPUT].value + inputs[C2_INPUT].value + inputs[C3_INPUT].value; - outputs[A1_OUTPUT].value = in1; - outputs[A2_OUTPUT].value = in1; - outputs[A3_OUTPUT].value = in1; - outputs[B1_OUTPUT].value = in2; - outputs[B2_OUTPUT].value = in2; - outputs[C1_OUTPUT].value = in3; + outputs[A1_OUTPUT].value = inA; + outputs[A2_OUTPUT].value = inA; + outputs[A3_OUTPUT].value = inA; + outputs[B1_OUTPUT].value = inB; + outputs[B2_OUTPUT].value = inB; + outputs[C1_OUTPUT].value = inC; - lights[0] = in1 / 5.0; - lights[1] = in2 / 5.0; - lights[2] = in3 / 5.0; + lights[A_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, inA / 5.0)); + lights[A_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -inA / 5.0)); + lights[B_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, inB / 5.0)); + lights[B_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -inB / 5.0)); + lights[C_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, inC / 5.0)); + lights[C_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -inC / 5.0)); } @@ -78,7 +86,7 @@ LinksWidget::LinksWidget() { addInput(createInput(Vec(4, 316), module, Links::C3_INPUT)); addOutput(createOutput(Vec(31, 316), module, Links::C1_OUTPUT)); - addChild(createValueLight>(Vec(26, 59), &module->lights[0])); - addChild(createValueLight>(Vec(26, 161), &module->lights[1])); - addChild(createValueLight>(Vec(26, 262), &module->lights[2])); + addChild(createLight>(Vec(26, 59), module, Links::A_POS_LIGHT)); + addChild(createLight>(Vec(26, 161), module, Links::B_POS_LIGHT)); + addChild(createLight>(Vec(26, 262), module, Links::C_POS_LIGHT)); } diff --git a/src/Rings.cpp b/src/Rings.cpp index 7c628b3..12e4a86 100644 --- a/src/Rings.cpp +++ b/src/Rings.cpp @@ -43,6 +43,11 @@ struct Rings : Module { EVEN_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + POLYPHONY_GREEN_LIGHT, POLYPHONY_RED_LIGHT, + RESONATOR_GREEN_LIGHT, RESONATOR_RED_LIGHT, + NUM_LIGHTS + }; SampleRateConverter<1> inputSrc; SampleRateConverter<2> outputSrc; @@ -55,7 +60,6 @@ struct Rings : Module { rings::Strummer strummer; bool strum = false; bool lastStrum = false; - float lights[2] = {}; SchmittTrigger polyphonyTrigger; SchmittTrigger modelTrigger; int polyphonyMode = 0; @@ -97,7 +101,7 @@ struct Rings : Module { }; -Rings::Rings() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { +Rings::Rings() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { memset(&strummer, 0, sizeof(strummer)); memset(&part, 0, sizeof(part)); memset(&string_synth, 0, sizeof(string_synth)); @@ -128,12 +132,14 @@ void Rings::step() { if (polyphonyTrigger.process(params[POLYPHONY_PARAM].value)) { polyphonyMode = (polyphonyMode + 1) % 3; } - lights[0] = (float)polyphonyMode; + lights[POLYPHONY_GREEN_LIGHT].value = (polyphonyMode == 0 || polyphonyMode == 1) ? 1.0 : 0.0; + lights[POLYPHONY_RED_LIGHT].value = (polyphonyMode == 1 || polyphonyMode == 2) ? 1.0 : 0.0; if (modelTrigger.process(params[RESONATOR_PARAM].value)) { model = (model + 1) % 3; } - lights[1] = (float)model; + lights[RESONATOR_GREEN_LIGHT].value = (model == 0 || model == 1) ? 1.0 : 0.0; + lights[RESONATOR_RED_LIGHT].value = (model == 1 || model == 2) ? 1.0 : 0.0; // Render frames if (outputBuffer.empty()) { @@ -229,15 +235,6 @@ void Rings::step() { } -struct RingsModeLight : ModeValueLight { - RingsModeLight() { - addColor(COLOR_CYAN); - addColor(COLOR_ORANGE); - addColor(COLOR_RED); - } -}; - - RingsWidget::RingsWidget() { Rings *module = new Rings(); setModule(module); @@ -283,6 +280,6 @@ RingsWidget::RingsWidget() { addOutput(createOutput(Vec(131, 316), module, Rings::ODD_OUTPUT)); addOutput(createOutput(Vec(169, 316), module, Rings::EVEN_OUTPUT)); - addChild(createValueLight>(Vec(38, 43.8), &module->lights[0])); - addChild(createValueLight>(Vec(163, 43.8), &module->lights[1])); + addChild(createLight>(Vec(38, 43.8), module, Rings::POLYPHONY_GREEN_LIGHT)); + addChild(createLight>(Vec(163, 43.8), module, Rings::RESONATOR_GREEN_LIGHT)); } diff --git a/src/Shades.cpp b/src/Shades.cpp index 0d867ca..5e8c1fe 100644 --- a/src/Shades.cpp +++ b/src/Shades.cpp @@ -24,47 +24,38 @@ struct Shades : Module { OUT3_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + OUT1_POS_LIGHT, OUT1_NEG_LIGHT, + OUT2_POS_LIGHT, OUT2_NEG_LIGHT, + OUT3_POS_LIGHT, OUT3_NEG_LIGHT, + NUM_LIGHTS + }; - float lights[3] = {}; - - Shades() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + Shades() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; }; -static float getChannelOutput(Input &in, Param &gain, Param &mode) { - float out = in.normalize(5.0); - if ((int)roundf(mode.value) == 1) { - // attenuverter - out *= 2.0*gain.value - 1.0; - } - else { - // attenuator - out *= gain.value; - } - return out; -} - void Shades::step() { float out = 0.0; - out += getChannelOutput(inputs[IN1_INPUT], params[GAIN1_PARAM], params[MODE1_PARAM]); - lights[0] = out / 5.0; - if (outputs[OUT1_OUTPUT].active) { - outputs[OUT1_OUTPUT].value = out; - out = 0.0; - } - - out += getChannelOutput(inputs[IN2_INPUT], params[GAIN2_PARAM], params[MODE2_PARAM]); - lights[1] = out / 5.0; - if (outputs[OUT2_OUTPUT].active) { - outputs[OUT2_OUTPUT].value = out; - out = 0.0; - } - out += getChannelOutput(inputs[IN3_INPUT], params[GAIN3_PARAM], params[MODE3_PARAM]); - lights[2] = out / 5.0; - if (outputs[OUT3_OUTPUT].active) { - outputs[OUT3_OUTPUT].value = out; + for (int i = 0; i < 3; i++) { + float in = inputs[IN1_INPUT + i].normalize(5.0); + if ((int)params[MODE1_PARAM + i].value == 1) { + // attenuverter + in *= 2.0 * params[GAIN1_PARAM + i].value - 1.0; + } + else { + // attenuator + in *= params[GAIN1_PARAM + i].value; + } + out += in; + lights[OUT1_POS_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, out / 5.0)); + lights[OUT1_NEG_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, -out / 5.0)); + if (outputs[OUT1_OUTPUT + i].active) { + outputs[OUT1_OUTPUT + i].value = out; + out = 0.0; + } } } @@ -100,7 +91,7 @@ ShadesWidget::ShadesWidget() { addOutput(createOutput(Vec(56, 281), module, Shades::OUT2_OUTPUT)); addOutput(createOutput(Vec(56, 317), module, Shades::OUT3_OUTPUT)); - addChild(createValueLight>(Vec(41, 254), &module->lights[0])); - addChild(createValueLight>(Vec(41, 290), &module->lights[1])); - addChild(createValueLight>(Vec(41, 326), &module->lights[2])); + addChild(createLight>(Vec(41, 254), module, Shades::OUT1_POS_LIGHT)); + addChild(createLight>(Vec(41, 290), module, Shades::OUT2_POS_LIGHT)); + addChild(createLight>(Vec(41, 326), module, Shades::OUT3_POS_LIGHT)); } diff --git a/src/Tides.cpp b/src/Tides.cpp index 38db279..61a4383 100644 --- a/src/Tides.cpp +++ b/src/Tides.cpp @@ -39,10 +39,15 @@ struct Tides : Module { BI_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + MODE_GREEN_LIGHT, MODE_RED_LIGHT, + PHASE_GREEN_LIGHT, PHASE_RED_LIGHT, + RANGE_GREEN_LIGHT, RANGE_RED_LIGHT, + NUM_LIGHTS + }; bool wavetableHack = false; tides::Generator generator; - float lights[3] = {}; int frame = 0; uint8_t lastGate; SchmittTrigger modeTrigger; @@ -84,7 +89,7 @@ struct Tides : Module { }; -Tides::Tides() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { +Tides::Tides() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { memset(&generator, 0, sizeof(generator)); generator.Init(); generator.set_sync(false); @@ -97,14 +102,16 @@ void Tides::step() { mode = (tides::GeneratorMode) (((int)mode - 1 + 3) % 3); generator.set_mode(mode); } - lights[0] = (float)mode; + lights[MODE_GREEN_LIGHT].value = (mode == 0 || mode == 1) ? 1.0 : 0.0; + lights[MODE_RED_LIGHT].value = (mode == 1 || mode == 2) ? 1.0 : 0.0; tides::GeneratorRange range = generator.range(); if (rangeTrigger.process(params[RANGE_PARAM].value)) { range = (tides::GeneratorRange) (((int)range - 1 + 3) % 3); generator.set_range(range); } - lights[2] = (float)range; + lights[RANGE_GREEN_LIGHT].value = (range == 0 || range == 1) ? 1.0 : 0.0; + lights[RANGE_RED_LIGHT].value = (range == 1 || range == 2) ? 1.0 : 0.0; // Buffer loop if (++frame >= 16) { @@ -162,27 +169,21 @@ void Tides::step() { uni = uni * level >> 16; bi = -bi * level >> 16; - float unif = rescalef(uni, 0, 0xffff, 0.0, 8.0); - float bif = rescalef(bi, -0x8000, 0x7fff, -5.0, 5.0); + float unif = (float) uni / 0xffff; + float bif = (float) bi / 0x8000; outputs[HIGH_OUTPUT].value = sample.flags & tides::FLAG_END_OF_ATTACK ? 0.0 : 5.0; outputs[LOW_OUTPUT].value = sample.flags & tides::FLAG_END_OF_RELEASE ? 0.0 : 5.0; - outputs[UNI_OUTPUT].value = unif; - outputs[BI_OUTPUT].value = bif; + outputs[UNI_OUTPUT].value = unif * 8.0; + outputs[BI_OUTPUT].value = bif * 5.0; - lights[1] = (sample.flags & tides::FLAG_END_OF_ATTACK ? -unif : unif) / 8.0; + if (sample.flags & tides::FLAG_END_OF_ATTACK) + unif *= -1.0; + lights[PHASE_GREEN_LIGHT].setBrightnessSmooth(fmaxf(0.0, unif)); + lights[PHASE_RED_LIGHT].setBrightnessSmooth(fmaxf(0.0, -unif)); } -struct TidesModeLight : ModeValueLight { - TidesModeLight() { - addColor(COLOR_RED); - addColor(COLOR_BLACK_TRANSPARENT); - addColor(COLOR_CYAN); - } -}; - - TidesWidget::TidesWidget() { Tides *module = new Tides(); setModule(module); @@ -226,9 +227,9 @@ TidesWidget::TidesWidget() { addOutput(createOutput(Vec(128, 316), module, Tides::UNI_OUTPUT)); addOutput(createOutput(Vec(164, 316), module, Tides::BI_OUTPUT)); - addChild(createValueLight>(Vec(57, 62), &module->lights[0])); - addChild(createValueLight>(Vec(57, 83), &module->lights[1])); - addChild(createValueLight>(Vec(57, 103), &module->lights[2])); + addChild(createLight>(Vec(57, 62), module, Tides::MODE_GREEN_LIGHT)); + addChild(createLight>(Vec(57, 83), module, Tides::PHASE_GREEN_LIGHT)); + addChild(createLight>(Vec(57, 103), module, Tides::RANGE_GREEN_LIGHT)); } diff --git a/src/Veils.cpp b/src/Veils.cpp index 65b605a..bdf13ad 100644 --- a/src/Veils.cpp +++ b/src/Veils.cpp @@ -32,57 +32,37 @@ struct Veils : Module { OUT4_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + OUT1_POS_LIGHT, OUT1_NEG_LIGHT, + OUT2_POS_LIGHT, OUT2_NEG_LIGHT, + OUT3_POS_LIGHT, OUT3_NEG_LIGHT, + OUT4_POS_LIGHT, OUT4_NEG_LIGHT, + NUM_LIGHTS + }; - float lights[4] = {}; - - Veils() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + Veils() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} void step() override; }; -static float processChannel(Input &in, Param &gain, Input &cv, Param &response) { - float out = in.value * gain.value; - if (out == 0.0) - return 0.0; - - if (cv.active) { - float linear = fmaxf(cv.value / 5.0, 0.0); - if (linear == 0.0) - return 0.0; - const float ex = 200.0; - float exponential = rescalef(powf(ex, linear), 1.0, ex, 0.0, 1.0); - out *= crossf(exponential, linear, response.value); - } - return out; -} - void Veils::step() { float out = 0.0; - out += processChannel(inputs[IN1_INPUT], params[GAIN1_PARAM], inputs[CV1_INPUT], params[RESPONSE1_PARAM]); - lights[0] = out; - if (outputs[OUT1_OUTPUT].active) { - outputs[OUT1_OUTPUT].value = out; - out = 0.0; - } - - out += processChannel(inputs[IN2_INPUT], params[GAIN2_PARAM], inputs[CV2_INPUT], params[RESPONSE2_PARAM]); - lights[1] = out; - if (outputs[OUT2_OUTPUT].active) { - outputs[OUT2_OUTPUT].value = out; - out = 0.0; - } - - out += processChannel(inputs[IN3_INPUT], params[GAIN3_PARAM], inputs[CV3_INPUT], params[RESPONSE3_PARAM]); - lights[2] = out; - if (outputs[OUT3_OUTPUT].active) { - outputs[OUT3_OUTPUT].value = out; - out = 0.0; - } - out += processChannel(inputs[IN4_INPUT], params[GAIN4_PARAM], inputs[CV4_INPUT], params[RESPONSE4_PARAM]); - lights[3] = out; - if (outputs[OUT4_OUTPUT].active) { - outputs[OUT4_OUTPUT].value = out; + for (int i = 0; i < 4; i++) { + float in = inputs[IN1_INPUT + i].value * params[GAIN1_PARAM + i].value; + if (inputs[CV1_INPUT + i].active) { + float linear = fmaxf(inputs[CV1_INPUT + i].value / 5.0, 0.0); + const float ex = 200.0; + float exponential = rescalef(powf(ex, linear), 1.0, ex, 0.0, 1.0); + in *= crossf(exponential, linear, params[RESPONSE1_PARAM + i].value); + } + out += in; + lights[OUT1_POS_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, out / 5.0)); + lights[OUT1_NEG_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, -out / 5.0)); + if (outputs[OUT1_OUTPUT + i].active) { + outputs[OUT1_OUTPUT + i].value = out; + out = 0.0; + } } } @@ -129,8 +109,8 @@ VeilsWidget::VeilsWidget() { addOutput(createOutput(Vec(144, 198), module, Veils::OUT3_OUTPUT)); addOutput(createOutput(Vec(144, 277), module, Veils::OUT4_OUTPUT)); - addChild(createValueLight>(Vec(150, 87), &module->lights[0])); - addChild(createValueLight>(Vec(150, 166), &module->lights[1])); - addChild(createValueLight>(Vec(150, 245), &module->lights[2])); - addChild(createValueLight>(Vec(150, 324), &module->lights[3])); + addChild(createLight>(Vec(150, 87), module, Veils::OUT1_POS_LIGHT)); + addChild(createLight>(Vec(150, 166), module, Veils::OUT2_POS_LIGHT)); + addChild(createLight>(Vec(150, 245), module, Veils::OUT3_POS_LIGHT)); + addChild(createLight>(Vec(150, 324), module, Veils::OUT4_POS_LIGHT)); } diff --git a/src/Warps.cpp b/src/Warps.cpp index 3418365..0f869f5 100644 --- a/src/Warps.cpp +++ b/src/Warps.cpp @@ -27,12 +27,17 @@ struct Warps : Module { AUX_OUTPUT, NUM_OUTPUTS }; + enum LightIds { + CARRIER_GREEN_LIGHT, CARRIER_RED_LIGHT, + ALGORITHM_LIGHT, + NUM_LIGHTS = ALGORITHM_LIGHT + 3 + }; + int frame = 0; warps::Modulator modulator; warps::ShortFrame inputFrames[60] = {}; warps::ShortFrame outputFrames[60] = {}; - float lights[2] = {}; SchmittTrigger stateTrigger; Warps(); @@ -65,7 +70,7 @@ struct Warps : Module { }; -Warps::Warps() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { +Warps::Warps() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { memset(&modulator, 0, sizeof(modulator)); modulator.Init(96000.0f); @@ -78,7 +83,8 @@ void Warps::step() { if (stateTrigger.process(params[STATE_PARAM].value)) { p->carrier_shape = (p->carrier_shape + 1) % 4; } - lights[0] = p->carrier_shape; + lights[CARRIER_GREEN_LIGHT].value = (p->carrier_shape == 1 || p->carrier_shape == 2) ? 1.0 : 0.0; + lights[CARRIER_RED_LIGHT].value = (p->carrier_shape == 2 || p->carrier_shape == 3) ? 1.0 : 0.0; // Buffer loop if (++frame >= 60) { @@ -87,7 +93,16 @@ void Warps::step() { p->channel_drive[0] = clampf(params[LEVEL1_PARAM].value + inputs[LEVEL1_INPUT].value / 5.0, 0.0, 1.0); p->channel_drive[1] = clampf(params[LEVEL2_PARAM].value + inputs[LEVEL2_INPUT].value / 5.0, 0.0, 1.0); p->modulation_algorithm = clampf(params[ALGORITHM_PARAM].value / 8.0 + inputs[ALGORITHM_INPUT].value / 5.0, 0.0, 1.0); - lights[1] = p->modulation_algorithm * 8.0; + + { + // TODO + // Use the correct light color + NVGcolor algorithmColor = nvgHSL(p->modulation_algorithm, 0.5, 0.5); + lights[ALGORITHM_LIGHT + 0].value = algorithmColor.r; + lights[ALGORITHM_LIGHT + 1].value = algorithmColor.g; + lights[ALGORITHM_LIGHT + 2].value = algorithmColor.b; + } + p->modulation_parameter = clampf(params[TIMBRE_PARAM].value + inputs[TIMBRE_INPUT].value / 5.0, 0.0, 1.0); p->frequency_shift_pot = params[ALGORITHM_PARAM].value / 8.0; @@ -106,42 +121,6 @@ void Warps::step() { } -struct WarpsModeLight : ModeValueLight { - WarpsModeLight() { - addColor(COLOR_BLACK_TRANSPARENT); - addColor(COLOR_GREEN); - addColor(COLOR_YELLOW); - addColor(COLOR_RED); - } -}; - -struct WarpsAlgoLight : ValueLight { - WarpsAlgoLight() { - box.size = Vec(67, 67); - } - - void step() override { - // TODO Set these to Warps' actual colors - static NVGcolor colors[9] = { - nvgHSL(0.5, 0.3, 0.85), - nvgHSL(0.6, 0.3, 0.85), - nvgHSL(0.7, 0.3, 0.85), - nvgHSL(0.8, 0.3, 0.85), - nvgHSL(0.9, 0.3, 0.85), - nvgHSL(0.0, 0.3, 0.85), - nvgHSL(0.1, 0.3, 0.85), - nvgHSL(0.2, 0.3, 0.85), - nvgHSL(0.3, 0.3, 0.85), - }; - int i = clampi((int) *value, 0, 7); - NVGcolor color0 = colors[i]; - NVGcolor color1 = colors[i + 1]; - float p = fmodf(*value, 1.0); - color = nvgLerpRGBA(color0, color1, p); - } -}; - - WarpsWidget::WarpsWidget() { Warps *module = new Warps(); setModule(module); @@ -176,6 +155,13 @@ WarpsWidget::WarpsWidget() { addOutput(createOutput(Vec(80, 316), module, Warps::MODULATOR_OUTPUT)); addOutput(createOutput(Vec(116, 316), module, Warps::AUX_OUTPUT)); - addChild(createValueLight>(Vec(20, 167), &module->lights[0])); - addChild(createValueLight(Vec(41, 64), &module->lights[1])); + addChild(createLight>(Vec(20, 167), module, Warps::CARRIER_GREEN_LIGHT)); + { + RedGreenBlueLight *algorithmLight = new RedGreenBlueLight(); + algorithmLight->box.pos = Vec(41, 64); + algorithmLight->box.size = Vec(67, 67); + algorithmLight->module = module; + algorithmLight->lightId = Warps::ALGORITHM_LIGHT; + addChild(algorithmLight); + } }