@@ -12,7 +12,7 @@ struct _8VERT : Module { | |||
NUM_OUTPUTS = 8 | |||
}; | |||
enum LightIds { | |||
NUM_LIGHTS = 8 | |||
NUM_LIGHTS = 16 | |||
}; | |||
_8VERT() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
@@ -25,7 +25,8 @@ void _8VERT::step() { | |||
lastIn = inputs[i].normalize(lastIn); | |||
float out = lastIn * params[i].value; | |||
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)); | |||
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); | |||
// 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 | |||
bool gated = inputs[GATE_INPUT].value >= 1.0; | |||
@@ -132,8 +132,8 @@ ADSRWidget::ADSRWidget() { | |||
addInput(createInput<PJ301MPort>(Vec(48, 320), module, ADSR::TRIG_INPUT)); | |||
addOutput(createOutput<PJ301MPort>(Vec(87, 320), module, ADSR::ENVELOPE_OUTPUT)); | |||
addChild(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" | |||
struct LFOGenerator { | |||
struct LowFrequencyOscillator { | |||
float phase = 0.0; | |||
float pw = 0.5; | |||
float freq = 1.0; | |||
bool offset = false; | |||
bool invert = false; | |||
SchmittTrigger resetTrigger; | |||
LFOGenerator() { | |||
LowFrequencyOscillator() { | |||
resetTrigger.setThresholds(0.0, 0.01); | |||
} | |||
void setPitch(float pitch) { | |||
@@ -91,11 +91,12 @@ struct LFO : Module { | |||
NUM_OUTPUTS | |||
}; | |||
enum LightIds { | |||
PHASE_LIGHT, | |||
PHASE_POS_LIGHT, | |||
PHASE_NEG_LIGHT, | |||
NUM_LIGHTS | |||
}; | |||
LFOGenerator generator; | |||
LowFrequencyOscillator oscillator; | |||
LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
void step() override; | |||
@@ -103,19 +104,20 @@ struct LFO : Module { | |||
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(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 | |||
}; | |||
enum LightIds { | |||
PHASE_LIGHT, | |||
PHASE_POS_LIGHT, | |||
PHASE_NEG_LIGHT, | |||
NUM_LIGHTS | |||
}; | |||
LFOGenerator generator; | |||
LowFrequencyOscillator oscillator; | |||
LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} | |||
void step() override; | |||
@@ -192,24 +195,25 @@ struct LFO2 : Module { | |||
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; | |||
wave = clampf(wave, 0.0, 3.0); | |||
float interp; | |||
if (wave < 1.0) | |||
interp = crossf(generator.sin(), generator.tri(), wave); | |||
interp = crossf(oscillator.sin(), oscillator.tri(), wave); | |||
else if (wave < 2.0) | |||
interp = crossf(generator.tri(), generator.saw(), wave - 1.0); | |||
interp = crossf(oscillator.tri(), oscillator.saw(), wave - 1.0); | |||
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; | |||
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)); | |||
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 | |||
}; | |||
enum LightIds { | |||
PLOT_LIGHT, | |||
LISSAJOUS_LIGHT, | |||
NOT_LISSAJOUS_LIGHT, // FIXME: what should this be called? | |||
EXTERNAL_LIGHT, | |||
INTERNAL_LIGHT, | |||
EXTERNAL_LIGHT, | |||
NUM_LIGHTS | |||
}; | |||
@@ -77,14 +77,14 @@ void Scope::step() { | |||
if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | |||
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)) { | |||
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 | |||
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(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 | |||
}; | |||
enum LightIds { | |||
PITCH_LIGHT, | |||
PHASE_POS_LIGHT, | |||
PHASE_NEG_LIGHT, | |||
NUM_LIGHTS | |||
}; | |||
@@ -224,7 +225,8 @@ void VCO::step() { | |||
if (outputs[SQR_OUTPUT].active) | |||
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(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 | |||
}; | |||
enum LightIds { | |||
PITCH_LIGHT, | |||
PHASE_POS_LIGHT, | |||
PHASE_NEG_LIGHT, | |||
NUM_LIGHTS | |||
}; | |||
@@ -320,7 +323,8 @@ void VCO2::step() { | |||
out = crossf(oscillator.saw(), oscillator.sqr(), wave - 2.0); | |||
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)); | |||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, VCO2::PITCH_LIGHT)); | |||
addChild(createLight<SmallLight<GreenRedLight>>(Vec(68, 41), module, VCO2::PHASE_POS_LIGHT)); | |||
} | |||