@@ -32,48 +32,38 @@ struct Blinds : Module { | |||||
OUT4_OUTPUT, | OUT4_OUTPUT, | ||||
NUM_OUTPUTS | 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; | 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() { | void Blinds::step() { | ||||
float out = 0.0; | 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, 198), module, Blinds::OUT3_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(144, 277), module, Blinds::OUT4_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 { | enum InputIds { | ||||
IN1_INPUT, | IN1_INPUT, | ||||
P1_INPUT, | |||||
IN2_INPUT, | IN2_INPUT, | ||||
P1_INPUT, | |||||
P2_INPUT, | P2_INPUT, | ||||
NUM_INPUTS | NUM_INPUTS | ||||
}; | }; | ||||
enum OutputIds { | enum OutputIds { | ||||
OUT1A_OUTPUT, | OUT1A_OUTPUT, | ||||
OUT1B_OUTPUT, | |||||
OUT2A_OUTPUT, | OUT2A_OUTPUT, | ||||
OUT1B_OUTPUT, | |||||
OUT2B_OUTPUT, | OUT2B_OUTPUT, | ||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | |||||
STATE1_LIGHT, | |||||
STATE2_LIGHT, | |||||
NUM_LIGHTS | |||||
}; | |||||
bool lastGate[2] = {}; | bool lastGate[2] = {}; | ||||
bool outcome[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; | 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(9, 316), module, Branches::OUT2A_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(55, 316), module, Branches::OUT2B_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, | MAIN_OUTPUT, | ||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | |||||
EXCITER_LIGHT, | |||||
RESONATOR_LIGHT, | |||||
NUM_LIGHTS | |||||
}; | |||||
SampleRateConverter<2> inputSrc; | SampleRateConverter<2> inputSrc; | ||||
SampleRateConverter<2> outputSrc; | SampleRateConverter<2> outputSrc; | ||||
@@ -74,7 +79,6 @@ struct Elements : Module { | |||||
uint16_t reverb_buffer[32768] = {}; | uint16_t reverb_buffer[32768] = {}; | ||||
elements::Part *part; | elements::Part *part; | ||||
float lights[2] = {}; | |||||
Elements(); | Elements(); | ||||
~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(); | part = new elements::Part(); | ||||
// In the Mutable Instruments code, Part doesn't initialize itself, so zero it here. | // In the Mutable Instruments code, Part doesn't initialize itself, so zero it here. | ||||
memset(part, 0, sizeof(*part)); | memset(part, 0, sizeof(*part)); | ||||
@@ -194,8 +198,8 @@ void Elements::step() { | |||||
} | } | ||||
// Set lights | // 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 | // Set output | ||||
@@ -280,8 +284,8 @@ ElementsWidget::ElementsWidget() { | |||||
addParam(createParam<CKD6>(Vec(36, 116), module, Elements::PLAY_PARAM, 0.0, 1.0, 0.0)); | 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 { | struct ElementsModalItem : MenuItem { | ||||
@@ -34,10 +34,13 @@ struct Frames : Module { | |||||
OUT3_OUTPUT, | OUT3_OUTPUT, | ||||
OUT4_OUTPUT, | OUT4_OUTPUT, | ||||
FRAME_STEP_OUTPUT, | FRAME_STEP_OUTPUT, | ||||
NUM_OUTPUTS | |||||
}; | |||||
enum LightIds { | |||||
GAIN1_LIGHT, | GAIN1_LIGHT, | ||||
EDIT_LIGHT = GAIN1_LIGHT + 4, | EDIT_LIGHT = GAIN1_LIGHT + 4, | ||||
FRAME_LIGHT, | FRAME_LIGHT, | ||||
NUM_OUTPUTS = FRAME_LIGHT + 3 | |||||
NUM_LIGHTS = FRAME_LIGHT + 3 | |||||
}; | }; | ||||
frames::Keyframer keyframer; | frames::Keyframer keyframer; | ||||
@@ -101,12 +104,12 @@ struct Frames : Module { | |||||
} | } | ||||
void randomize() override { | void randomize() override { | ||||
// TODO | // 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)); | memset(&keyframer, 0, sizeof(keyframer)); | ||||
keyframer.Init(); | keyframer.Init(); | ||||
memset(&poly_lfo, 0, sizeof(poly_lfo)); | memset(&poly_lfo, 0, sizeof(poly_lfo)); | ||||
@@ -219,15 +222,14 @@ void Frames::step() { | |||||
// Set lights | // Set lights | ||||
for (int i = 0; i < 4; i++) { | 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) { | 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 { | 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 | // Set frame light colors | ||||
@@ -239,32 +241,11 @@ void Frames::step() { | |||||
colors = keyframer.color(); | colors = keyframer.color(); | ||||
} | } | ||||
for (int c = 0; c < 3; c++) { | 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 { | struct CKSSRot : SVGSwitch, ToggleSwitch { | ||||
CKSSRot() { | CKSSRot() { | ||||
addFrame(SVG::load(assetPlugin(plugin, "res/CKSS_rot_0.svg"))); | 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(188, 315), module, Frames::OUT4_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(231, 315), module, Frames::FRAME_STEP_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->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); | addChild(framesLight); | ||||
} | } | ||||
} | } | ||||
@@ -24,12 +24,17 @@ struct Kinks : Module { | |||||
SH_OUTPUT, | SH_OUTPUT, | ||||
NUM_OUTPUTS | 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; | SchmittTrigger trigger; | ||||
float sample = 0.0; | 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); | trigger.setThresholds(0.0, 0.7); | ||||
} | } | ||||
void step() override; | void step() override; | ||||
@@ -46,9 +51,13 @@ void Kinks::step() { | |||||
} | } | ||||
// lights | // 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 | ||||
outputs[INVERT_OUTPUT].value = -inputs[SIGN_INPUT].value; | 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(4, 316), module, Kinks::NOISE_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(31, 316), module, Kinks::SH_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, | C1_OUTPUT, | ||||
NUM_OUTPUTS | 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 step() override; | ||||
}; | }; | ||||
void Links::step() { | 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)); | addInput(createInput<PJ301MPort>(Vec(4, 316), module, Links::C3_INPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(31, 316), module, Links::C1_OUTPUT)); | 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, | EVEN_OUTPUT, | ||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | |||||
POLYPHONY_GREEN_LIGHT, POLYPHONY_RED_LIGHT, | |||||
RESONATOR_GREEN_LIGHT, RESONATOR_RED_LIGHT, | |||||
NUM_LIGHTS | |||||
}; | |||||
SampleRateConverter<1> inputSrc; | SampleRateConverter<1> inputSrc; | ||||
SampleRateConverter<2> outputSrc; | SampleRateConverter<2> outputSrc; | ||||
@@ -55,7 +60,6 @@ struct Rings : Module { | |||||
rings::Strummer strummer; | rings::Strummer strummer; | ||||
bool strum = false; | bool strum = false; | ||||
bool lastStrum = false; | bool lastStrum = false; | ||||
float lights[2] = {}; | |||||
SchmittTrigger polyphonyTrigger; | SchmittTrigger polyphonyTrigger; | ||||
SchmittTrigger modelTrigger; | SchmittTrigger modelTrigger; | ||||
int polyphonyMode = 0; | 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(&strummer, 0, sizeof(strummer)); | ||||
memset(&part, 0, sizeof(part)); | memset(&part, 0, sizeof(part)); | ||||
memset(&string_synth, 0, sizeof(string_synth)); | memset(&string_synth, 0, sizeof(string_synth)); | ||||
@@ -128,12 +132,14 @@ void Rings::step() { | |||||
if (polyphonyTrigger.process(params[POLYPHONY_PARAM].value)) { | if (polyphonyTrigger.process(params[POLYPHONY_PARAM].value)) { | ||||
polyphonyMode = (polyphonyMode + 1) % 3; | 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)) { | if (modelTrigger.process(params[RESONATOR_PARAM].value)) { | ||||
model = (model + 1) % 3; | 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 | // Render frames | ||||
if (outputBuffer.empty()) { | 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() { | RingsWidget::RingsWidget() { | ||||
Rings *module = new Rings(); | Rings *module = new Rings(); | ||||
setModule(module); | setModule(module); | ||||
@@ -283,6 +280,6 @@ RingsWidget::RingsWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(131, 316), module, Rings::ODD_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(131, 316), module, Rings::ODD_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(169, 316), module, Rings::EVEN_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, | OUT3_OUTPUT, | ||||
NUM_OUTPUTS | 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; | 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() { | void Shades::step() { | ||||
float out = 0.0; | 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, 281), module, Shades::OUT2_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(56, 317), module, Shades::OUT3_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, | BI_OUTPUT, | ||||
NUM_OUTPUTS | 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; | bool wavetableHack = false; | ||||
tides::Generator generator; | tides::Generator generator; | ||||
float lights[3] = {}; | |||||
int frame = 0; | int frame = 0; | ||||
uint8_t lastGate; | uint8_t lastGate; | ||||
SchmittTrigger modeTrigger; | 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)); | memset(&generator, 0, sizeof(generator)); | ||||
generator.Init(); | generator.Init(); | ||||
generator.set_sync(false); | generator.set_sync(false); | ||||
@@ -97,14 +102,16 @@ void Tides::step() { | |||||
mode = (tides::GeneratorMode) (((int)mode - 1 + 3) % 3); | mode = (tides::GeneratorMode) (((int)mode - 1 + 3) % 3); | ||||
generator.set_mode(mode); | 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(); | tides::GeneratorRange range = generator.range(); | ||||
if (rangeTrigger.process(params[RANGE_PARAM].value)) { | if (rangeTrigger.process(params[RANGE_PARAM].value)) { | ||||
range = (tides::GeneratorRange) (((int)range - 1 + 3) % 3); | range = (tides::GeneratorRange) (((int)range - 1 + 3) % 3); | ||||
generator.set_range(range); | 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 | // Buffer loop | ||||
if (++frame >= 16) { | if (++frame >= 16) { | ||||
@@ -162,27 +169,21 @@ void Tides::step() { | |||||
uni = uni * level >> 16; | uni = uni * level >> 16; | ||||
bi = -bi * 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[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[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() { | TidesWidget::TidesWidget() { | ||||
Tides *module = new Tides(); | Tides *module = new Tides(); | ||||
setModule(module); | setModule(module); | ||||
@@ -226,9 +227,9 @@ TidesWidget::TidesWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(128, 316), module, Tides::UNI_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(128, 316), module, Tides::UNI_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(164, 316), module, Tides::BI_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, | OUT4_OUTPUT, | ||||
NUM_OUTPUTS | 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; | 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() { | void Veils::step() { | ||||
float out = 0.0; | 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, 198), module, Veils::OUT3_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(144, 277), module, Veils::OUT4_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, | AUX_OUTPUT, | ||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | |||||
CARRIER_GREEN_LIGHT, CARRIER_RED_LIGHT, | |||||
ALGORITHM_LIGHT, | |||||
NUM_LIGHTS = ALGORITHM_LIGHT + 3 | |||||
}; | |||||
int frame = 0; | int frame = 0; | ||||
warps::Modulator modulator; | warps::Modulator modulator; | ||||
warps::ShortFrame inputFrames[60] = {}; | warps::ShortFrame inputFrames[60] = {}; | ||||
warps::ShortFrame outputFrames[60] = {}; | warps::ShortFrame outputFrames[60] = {}; | ||||
float lights[2] = {}; | |||||
SchmittTrigger stateTrigger; | SchmittTrigger stateTrigger; | ||||
Warps(); | 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)); | memset(&modulator, 0, sizeof(modulator)); | ||||
modulator.Init(96000.0f); | modulator.Init(96000.0f); | ||||
@@ -78,7 +83,8 @@ void Warps::step() { | |||||
if (stateTrigger.process(params[STATE_PARAM].value)) { | if (stateTrigger.process(params[STATE_PARAM].value)) { | ||||
p->carrier_shape = (p->carrier_shape + 1) % 4; | 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 | // Buffer loop | ||||
if (++frame >= 60) { | 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[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->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); | 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->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; | 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() { | WarpsWidget::WarpsWidget() { | ||||
Warps *module = new Warps(); | Warps *module = new Warps(); | ||||
setModule(module); | setModule(module); | ||||
@@ -176,6 +155,13 @@ WarpsWidget::WarpsWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(80, 316), module, Warps::MODULATOR_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(80, 316), module, Warps::MODULATOR_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(116, 316), module, Warps::AUX_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); | |||||
} | |||||
} | } |