@@ -12,7 +12,7 @@ struct _8VERT : Module { | |||||
NUM_OUTPUTS = 8 | NUM_OUTPUTS = 8 | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
NUM_LIGHTS = 8 | |||||
NUM_LIGHTS = 16 | |||||
}; | }; | ||||
_8VERT() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | _8VERT() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | ||||
@@ -25,7 +25,8 @@ void _8VERT::step() { | |||||
lastIn = inputs[i].normalize(lastIn); | lastIn = inputs[i].normalize(lastIn); | ||||
float out = lastIn * params[i].value; | float out = lastIn * params[i].value; | ||||
outputs[i].value = out; | outputs[i].value = out; | ||||
lights[i].value = out / 10.0; | |||||
lights[2*i + 0].setBrightnessSmooth(fmaxf(0.0, out / 5.0)); | |||||
lights[2*i + 1].setBrightnessSmooth(fmaxf(0.0, -out / 5.0)); | |||||
} | } | ||||
} | } | ||||
@@ -73,11 +74,11 @@ _8VERTWidget::_8VERTWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(86.393, 319.504), module, 7)); | addOutput(createOutput<PJ301MPort>(Vec(86.393, 319.504), module, 7)); | ||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 50.414), module, 0)); | addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 50.414), module, 0)); | ||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 88.859), module, 1)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 127.304), module, 2)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 165.745), module, 3)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 204.19), module, 4)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 242.635), module, 5)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 281.076), module, 6)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 319.521), module, 7)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 88.859), module, 2)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 127.304), module, 4)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 165.745), module, 6)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 204.19), module, 8)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 242.635), module, 10)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 281.076), module, 12)); | |||||
addChild(createLight<TinyLight<GreenRedLight>>(Vec(107.702, 319.521), module, 14)); | |||||
} | } |
@@ -49,10 +49,10 @@ void ADSR::step() { | |||||
float release = clampf(params[RELEASE_PARAM].value + inputs[RELEASE_PARAM].value / 10.0, 0.0, 1.0); | float release = clampf(params[RELEASE_PARAM].value + inputs[RELEASE_PARAM].value / 10.0, 0.0, 1.0); | ||||
// Lights | // Lights | ||||
lights[ATTACK_LIGHT].value = 2.0*attack - 1.0; | |||||
lights[DECAY_LIGHT].value = 2.0*decay - 1.0; | |||||
lights[SUSTAIN_LIGHT].value = 2.0*sustain - 1.0; | |||||
lights[RELEASE_LIGHT].value = 2.0*release - 1.0; | |||||
lights[ATTACK_LIGHT].value = attack; | |||||
lights[DECAY_LIGHT].value = decay; | |||||
lights[SUSTAIN_LIGHT].value = sustain; | |||||
lights[RELEASE_LIGHT].value = release; | |||||
// Gate and trigger | // Gate and trigger | ||||
bool gated = inputs[GATE_INPUT].value >= 1.0; | bool gated = inputs[GATE_INPUT].value >= 1.0; | ||||
@@ -132,8 +132,8 @@ ADSRWidget::ADSRWidget() { | |||||
addInput(createInput<PJ301MPort>(Vec(48, 320), module, ADSR::TRIG_INPUT)); | addInput(createInput<PJ301MPort>(Vec(48, 320), module, ADSR::TRIG_INPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(87, 320), module, ADSR::ENVELOPE_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(87, 320), module, ADSR::ENVELOPE_OUTPUT)); | ||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 41), module, ADSR::ATTACK_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 108), module, ADSR::DECAY_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 175), module, ADSR::SUSTAIN_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(94, 241), module, ADSR::RELEASE_LIGHT)); | |||||
addChild(createLight<SmallLight<RedLight>>(Vec(94, 41), module, ADSR::ATTACK_LIGHT)); | |||||
addChild(createLight<SmallLight<RedLight>>(Vec(94, 108), module, ADSR::DECAY_LIGHT)); | |||||
addChild(createLight<SmallLight<RedLight>>(Vec(94, 175), module, ADSR::SUSTAIN_LIGHT)); | |||||
addChild(createLight<SmallLight<RedLight>>(Vec(94, 241), module, ADSR::RELEASE_LIGHT)); | |||||
} | } |
@@ -2,14 +2,14 @@ | |||||
#include "dsp/digital.hpp" | #include "dsp/digital.hpp" | ||||
struct LFOGenerator { | |||||
struct LowFrequencyOscillator { | |||||
float phase = 0.0; | float phase = 0.0; | ||||
float pw = 0.5; | float pw = 0.5; | ||||
float freq = 1.0; | float freq = 1.0; | ||||
bool offset = false; | bool offset = false; | ||||
bool invert = false; | bool invert = false; | ||||
SchmittTrigger resetTrigger; | SchmittTrigger resetTrigger; | ||||
LFOGenerator() { | |||||
LowFrequencyOscillator() { | |||||
resetTrigger.setThresholds(0.0, 0.01); | resetTrigger.setThresholds(0.0, 0.01); | ||||
} | } | ||||
void setPitch(float pitch) { | void setPitch(float pitch) { | ||||
@@ -91,11 +91,12 @@ struct LFO : Module { | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
PHASE_LIGHT, | |||||
PHASE_POS_LIGHT, | |||||
PHASE_NEG_LIGHT, | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
LFOGenerator generator; | |||||
LowFrequencyOscillator oscillator; | |||||
LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | ||||
void step() override; | void step() override; | ||||
@@ -103,19 +104,20 @@ struct LFO : Module { | |||||
void LFO::step() { | void LFO::step() { | ||||
generator.setPitch(params[FREQ_PARAM].value + params[FM1_PARAM].value * inputs[FM1_INPUT].value + params[FM2_PARAM].value * inputs[FM2_INPUT].value); | |||||
generator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.0); | |||||
generator.offset = (params[OFFSET_PARAM].value > 0.0); | |||||
generator.invert = (params[INVERT_PARAM].value <= 0.0); | |||||
generator.step(1.0 / engineGetSampleRate()); | |||||
generator.setReset(inputs[RESET_INPUT].value); | |||||
outputs[SIN_OUTPUT].value = 5.0 * generator.sin(); | |||||
outputs[TRI_OUTPUT].value = 5.0 * generator.tri(); | |||||
outputs[SAW_OUTPUT].value = 5.0 * generator.saw(); | |||||
outputs[SQR_OUTPUT].value = 5.0 * generator.sqr(); | |||||
lights[PHASE_LIGHT].value = generator.light(); | |||||
oscillator.setPitch(params[FREQ_PARAM].value + params[FM1_PARAM].value * inputs[FM1_INPUT].value + params[FM2_PARAM].value * inputs[FM2_INPUT].value); | |||||
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.0); | |||||
oscillator.offset = (params[OFFSET_PARAM].value > 0.0); | |||||
oscillator.invert = (params[INVERT_PARAM].value <= 0.0); | |||||
oscillator.step(1.0 / engineGetSampleRate()); | |||||
oscillator.setReset(inputs[RESET_INPUT].value); | |||||
outputs[SIN_OUTPUT].value = 5.0 * oscillator.sin(); | |||||
outputs[TRI_OUTPUT].value = 5.0 * oscillator.tri(); | |||||
outputs[SAW_OUTPUT].value = 5.0 * oscillator.saw(); | |||||
outputs[SQR_OUTPUT].value = 5.0 * oscillator.sqr(); | |||||
lights[PHASE_POS_LIGHT].setBrightness(fmaxf(0.0, oscillator.light())); | |||||
lights[PHASE_NEG_LIGHT].setBrightness(fmaxf(0.0, -oscillator.light())); | |||||
} | } | ||||
@@ -155,7 +157,7 @@ LFOWidget::LFOWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(80, 320), module, LFO::SAW_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(80, 320), module, LFO::SAW_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(114, 320), module, LFO::SQR_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(114, 320), module, LFO::SQR_OUTPUT)); | ||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(99, 42), module, LFO::PHASE_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(99, 42), module, LFO::PHASE_POS_LIGHT)); | |||||
} | } | ||||
@@ -180,11 +182,12 @@ struct LFO2 : Module { | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
PHASE_LIGHT, | |||||
PHASE_POS_LIGHT, | |||||
PHASE_NEG_LIGHT, | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
LFOGenerator generator; | |||||
LowFrequencyOscillator oscillator; | |||||
LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | ||||
void step() override; | void step() override; | ||||
@@ -192,24 +195,25 @@ struct LFO2 : Module { | |||||
void LFO2::step() { | void LFO2::step() { | ||||
generator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value); | |||||
generator.offset = (params[OFFSET_PARAM].value > 0.0); | |||||
generator.invert = (params[INVERT_PARAM].value <= 0.0); | |||||
generator.step(1.0 / engineGetSampleRate()); | |||||
generator.setReset(inputs[RESET_INPUT].value); | |||||
oscillator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value); | |||||
oscillator.offset = (params[OFFSET_PARAM].value > 0.0); | |||||
oscillator.invert = (params[INVERT_PARAM].value <= 0.0); | |||||
oscillator.step(1.0 / engineGetSampleRate()); | |||||
oscillator.setReset(inputs[RESET_INPUT].value); | |||||
float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value; | float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value; | ||||
wave = clampf(wave, 0.0, 3.0); | wave = clampf(wave, 0.0, 3.0); | ||||
float interp; | float interp; | ||||
if (wave < 1.0) | if (wave < 1.0) | ||||
interp = crossf(generator.sin(), generator.tri(), wave); | |||||
interp = crossf(oscillator.sin(), oscillator.tri(), wave); | |||||
else if (wave < 2.0) | else if (wave < 2.0) | ||||
interp = crossf(generator.tri(), generator.saw(), wave - 1.0); | |||||
interp = crossf(oscillator.tri(), oscillator.saw(), wave - 1.0); | |||||
else | else | ||||
interp = crossf(generator.saw(), generator.sqr(), wave - 2.0); | |||||
interp = crossf(oscillator.saw(), oscillator.sqr(), wave - 2.0); | |||||
outputs[INTERP_OUTPUT].value = 5.0 * interp; | outputs[INTERP_OUTPUT].value = 5.0 * interp; | ||||
lights[PHASE_LIGHT].value = generator.light(); | |||||
lights[PHASE_POS_LIGHT].setBrightness(fmaxf(0.0, oscillator.light())); | |||||
lights[PHASE_NEG_LIGHT].setBrightness(fmaxf(0.0, -oscillator.light())); | |||||
} | } | ||||
@@ -243,5 +247,5 @@ LFO2Widget::LFO2Widget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(54, 319), module, LFO2::INTERP_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(54, 319), module, LFO2::INTERP_OUTPUT)); | ||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, LFO2::PHASE_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, LFO2::PHASE_POS_LIGHT)); | |||||
} | } |
@@ -27,10 +27,10 @@ struct Scope : Module { | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
PLOT_LIGHT, | |||||
LISSAJOUS_LIGHT, | LISSAJOUS_LIGHT, | ||||
NOT_LISSAJOUS_LIGHT, // FIXME: what should this be called? | |||||
EXTERNAL_LIGHT, | |||||
INTERNAL_LIGHT, | INTERNAL_LIGHT, | ||||
EXTERNAL_LIGHT, | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
@@ -77,14 +77,14 @@ void Scope::step() { | |||||
if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | ||||
lissajous = !lissajous; | lissajous = !lissajous; | ||||
} | } | ||||
lights[LISSAJOUS_LIGHT].value = lissajous ? 0.0 : 1.0; | |||||
lights[NOT_LISSAJOUS_LIGHT].value = lissajous ? 1.0 : 0.0; | |||||
lights[PLOT_LIGHT].value = lissajous ? 0.0 : 1.0; | |||||
lights[LISSAJOUS_LIGHT].value = lissajous ? 1.0 : 0.0; | |||||
if (extTrigger.process(params[EXTERNAL_PARAM].value)) { | if (extTrigger.process(params[EXTERNAL_PARAM].value)) { | ||||
external = !external; | external = !external; | ||||
} | } | ||||
lights[EXTERNAL_LIGHT].value = external ? 0.0 : 1.0; | |||||
lights[INTERNAL_LIGHT].value = external ? 1.0 : 0.0; | |||||
lights[INTERNAL_LIGHT].value = external ? 0.0 : 1.0; | |||||
lights[EXTERNAL_LIGHT].value = external ? 1.0 : 0.0; | |||||
// Compute time | // Compute time | ||||
float deltaTime = powf(2.0, params[TIME_PARAM].value); | float deltaTime = powf(2.0, params[TIME_PARAM].value); | ||||
@@ -338,8 +338,8 @@ ScopeWidget::ScopeWidget() { | |||||
addInput(createInput<PJ301MPort>(Vec(63, 319), module, Scope::Y_INPUT)); | addInput(createInput<PJ301MPort>(Vec(63, 319), module, Scope::Y_INPUT)); | ||||
addInput(createInput<PJ301MPort>(Vec(154, 319), module, Scope::TRIG_INPUT)); | addInput(createInput<PJ301MPort>(Vec(154, 319), module, Scope::TRIG_INPUT)); | ||||
addChild(createLight<TinyLight<GreenLight>>(Vec(104, 251), module, Scope::LISSAJOUS_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(104, 296), module, Scope::NOT_LISSAJOUS_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(150, 251), module, Scope::EXTERNAL_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(150, 296), module, Scope::INTERNAL_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(104, 251), module, Scope::PLOT_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(104, 296), module, Scope::LISSAJOUS_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(150, 251), module, Scope::INTERNAL_LIGHT)); | |||||
addChild(createLight<TinyLight<GreenLight>>(Vec(150, 296), module, Scope::EXTERNAL_LIGHT)); | |||||
} | } |
@@ -188,7 +188,8 @@ struct VCO : Module { | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
PITCH_LIGHT, | |||||
PHASE_POS_LIGHT, | |||||
PHASE_NEG_LIGHT, | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
@@ -224,7 +225,8 @@ void VCO::step() { | |||||
if (outputs[SQR_OUTPUT].active) | if (outputs[SQR_OUTPUT].active) | ||||
outputs[SQR_OUTPUT].value = 5.0 * oscillator.sqr(); | outputs[SQR_OUTPUT].value = 5.0 * oscillator.sqr(); | ||||
lights[PITCH_LIGHT].value = oscillator.light(); | |||||
lights[PHASE_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, oscillator.light())); | |||||
lights[PHASE_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -oscillator.light())); | |||||
} | } | ||||
@@ -264,7 +266,7 @@ VCOWidget::VCOWidget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(80, 320), module, VCO::SAW_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(80, 320), module, VCO::SAW_OUTPUT)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(114, 320), module, VCO::SQR_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(114, 320), module, VCO::SQR_OUTPUT)); | ||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(99, 42), module, VCO::PITCH_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(99, 42), module, VCO::PHASE_POS_LIGHT)); | |||||
} | } | ||||
@@ -288,7 +290,8 @@ struct VCO2 : Module { | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
PITCH_LIGHT, | |||||
PHASE_POS_LIGHT, | |||||
PHASE_NEG_LIGHT, | |||||
NUM_LIGHTS | NUM_LIGHTS | ||||
}; | }; | ||||
@@ -320,7 +323,8 @@ void VCO2::step() { | |||||
out = crossf(oscillator.saw(), oscillator.sqr(), wave - 2.0); | out = crossf(oscillator.saw(), oscillator.sqr(), wave - 2.0); | ||||
outputs[OUT_OUTPUT].value = 5.0 * out; | outputs[OUT_OUTPUT].value = 5.0 * out; | ||||
lights[PITCH_LIGHT].value = oscillator.light(); | |||||
lights[PHASE_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0, oscillator.light())); | |||||
lights[PHASE_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0, -oscillator.light())); | |||||
} | } | ||||
@@ -354,7 +358,7 @@ VCO2Widget::VCO2Widget() { | |||||
addOutput(createOutput<PJ301MPort>(Vec(54, 320), module, VCO2::OUT_OUTPUT)); | addOutput(createOutput<PJ301MPort>(Vec(54, 320), module, VCO2::OUT_OUTPUT)); | ||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, VCO2::PITCH_LIGHT)); | |||||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, VCO2::PHASE_POS_LIGHT)); | |||||
} | } | ||||