| @@ -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<PJ301MPort>(Vec(144, 198), module, Blinds::OUT3_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(144, 277), module, Blinds::OUT4_OUTPUT)); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 87), &module->lights[0])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 166), &module->lights[1])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 245), &module->lights[2])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 324), &module->lights[3])); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 87), module, Blinds::IN1_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 166), module, Blinds::IN2_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 245), module, Blinds::IN3_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 324), module, Blinds::IN4_POS_LIGHT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(77, 96), &module->gainLights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(77, 175), &module->gainLights[1])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(77, 254), &module->gainLights[2])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(77, 333), &module->gainLights[3])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(77, 96), module, Blinds::OUT1_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(77, 175), module, Blinds::OUT2_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(77, 254), module, Blinds::OUT3_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(77, 333), module, Blinds::OUT4_POS_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(9, 316), module, Branches::OUT2A_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(55, 316), module, Branches::OUT2B_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 169), &module->light[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 325), &module->light[1])); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(40, 169), module, Branches::STATE1_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(40, 325), module, Branches::STATE2_LIGHT)); | |||
| } | |||
| @@ -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<CKD6>(Vec(36, 116), module, Elements::PLAY_PARAM, 0.0, 1.0, 0.0)); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(184, 165), &module->lights[0])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(395, 165), &module->lights[1])); | |||
| addChild(createLight<MediumLight<GreenLight>>(Vec(184, 165), module, Elements::EXCITER_LIGHT)); | |||
| addChild(createLight<MediumLight<RedLight>>(Vec(395, 165), module, Elements::RESONATOR_LIGHT)); | |||
| } | |||
| struct ElementsModalItem : MenuItem { | |||
| @@ -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<PJ301MPort>(Vec(188, 315), module, Frames::OUT4_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(231, 315), module, Frames::FRAME_STEP_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(30, 101), &module->outputs[Frames::GAIN1_LIGHT + 0].value)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(97, 101), &module->outputs[Frames::GAIN1_LIGHT + 1].value)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(165, 101), &module->outputs[Frames::GAIN1_LIGHT + 2].value)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(232, 101), &module->outputs[Frames::GAIN1_LIGHT + 3].value)); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(61, 155), &module->outputs[Frames::EDIT_LIGHT].value)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(30, 101), module, Frames::GAIN1_LIGHT + 0)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(97, 101), module, Frames::GAIN1_LIGHT + 1)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(165, 101), module, Frames::GAIN1_LIGHT + 2)); | |||
| addChild(createLight<SmallLight<GreenLight>>(Vec(232, 101), module, Frames::GAIN1_LIGHT + 3)); | |||
| addChild(createLight<MediumLight<GreenLight>>(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); | |||
| } | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(4, 316), module, Kinks::NOISE_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(31, 316), module, Kinks::SH_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(11, 59), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(11, 161), &module->lights[1])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(11, 262), &module->lights[2])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(11, 59), module, Kinks::SIGN_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(11, 161), module, Kinks::LOGIC_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(11, 262), module, Kinks::SH_POS_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(4, 316), module, Links::C3_INPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(31, 316), module, Links::C1_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(26, 59), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(26, 161), &module->lights[1])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(26, 262), &module->lights[2])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(26, 59), module, Links::A_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(26, 161), module, Links::B_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(26, 262), module, Links::C_POS_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(131, 316), module, Rings::ODD_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(169, 316), module, Rings::EVEN_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<RingsModeLight>>(Vec(38, 43.8), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<RingsModeLight>>(Vec(163, 43.8), &module->lights[1])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(38, 43.8), module, Rings::POLYPHONY_GREEN_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(163, 43.8), module, Rings::RESONATOR_GREEN_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(56, 281), module, Shades::OUT2_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(56, 317), module, Shades::OUT3_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(41, 254), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(41, 290), &module->lights[1])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(41, 326), &module->lights[2])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(41, 254), module, Shades::OUT1_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(41, 290), module, Shades::OUT2_POS_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(41, 326), module, Shades::OUT3_POS_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(128, 316), module, Tides::UNI_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(164, 316), module, Tides::BI_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<TidesModeLight>>(Vec(57, 62), &module->lights[0])); | |||
| addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(57, 83), &module->lights[1])); | |||
| addChild(createValueLight<SmallLight<TidesModeLight>>(Vec(57, 103), &module->lights[2])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(57, 62), module, Tides::MODE_GREEN_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(57, 83), module, Tides::PHASE_GREEN_LIGHT)); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(Vec(57, 103), module, Tides::RANGE_GREEN_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(144, 198), module, Veils::OUT3_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(144, 277), module, Veils::OUT4_OUTPUT)); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 87), &module->lights[0])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 166), &module->lights[1])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 245), &module->lights[2])); | |||
| addChild(createValueLight<MediumLight<GreenRedPolarityLight>>(Vec(150, 324), &module->lights[3])); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 87), module, Veils::OUT1_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 166), module, Veils::OUT2_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 245), module, Veils::OUT3_POS_LIGHT)); | |||
| addChild(createLight<MediumLight<GreenRedLight>>(Vec(150, 324), module, Veils::OUT4_POS_LIGHT)); | |||
| } | |||
| @@ -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<PJ301MPort>(Vec(80, 316), module, Warps::MODULATOR_OUTPUT)); | |||
| addOutput(createOutput<PJ301MPort>(Vec(116, 316), module, Warps::AUX_OUTPUT)); | |||
| addChild(createValueLight<SmallLight<WarpsModeLight>>(Vec(20, 167), &module->lights[0])); | |||
| addChild(createValueLight<WarpsAlgoLight>(Vec(41, 64), &module->lights[1])); | |||
| addChild(createLight<SmallLight<GreenRedLight>>(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); | |||
| } | |||
| } | |||