@@ -6,6 +6,7 @@ | |||||
"authorEmail": "contact@vcvrack.com", | "authorEmail": "contact@vcvrack.com", | ||||
"pluginUrl": "https://vcvrack.com/Fundamental.html", | "pluginUrl": "https://vcvrack.com/Fundamental.html", | ||||
"authorUrl": "https://vcvrack.com/", | "authorUrl": "https://vcvrack.com/", | ||||
"manualUrl": "https://vcvrack.com/Fundamental.html#manual", | |||||
"sourceUrl": "https://github.com/VCVRack/Fundamental", | "sourceUrl": "https://github.com/VCVRack/Fundamental", | ||||
"version": "1.0.0", | "version": "1.0.0", | ||||
"modules": { | "modules": { | ||||
@@ -30,8 +30,8 @@ struct _8vert : Module { | |||||
float lastIn = 10.f; | float lastIn = 10.f; | ||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
lastIn = inputs[i].getNormalVoltage(lastIn); | lastIn = inputs[i].getNormalVoltage(lastIn); | ||||
float out = lastIn * params[i].value; | |||||
outputs[i].value = out; | |||||
float out = lastIn * params[i].getValue(); | |||||
outputs[i].setVoltage(out); | |||||
lights[2*i + 0].setSmoothBrightness(out / 5.f, args.sampleTime); | lights[2*i + 0].setSmoothBrightness(out / 5.f, args.sampleTime); | ||||
lights[2*i + 1].setSmoothBrightness(-out / 5.f, args.sampleTime); | lights[2*i + 1].setSmoothBrightness(-out / 5.f, args.sampleTime); | ||||
} | } | ||||
@@ -43,14 +43,14 @@ struct ADSR : Module { | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float attack = clamp(params[ATTACK_PARAM].value + inputs[ATTACK_INPUT].value / 10.f, 0.f, 1.f); | |||||
float decay = clamp(params[DECAY_PARAM].value + inputs[DECAY_INPUT].value / 10.f, 0.f, 1.f); | |||||
float sustain = clamp(params[SUSTAIN_PARAM].value + inputs[SUSTAIN_INPUT].value / 10.f, 0.f, 1.f); | |||||
float release = clamp(params[RELEASE_PARAM].value + inputs[RELEASE_INPUT].value / 10.f, 0.f, 1.f); | |||||
float attack = clamp(params[ATTACK_PARAM].getValue() + inputs[ATTACK_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
float decay = clamp(params[DECAY_PARAM].getValue() + inputs[DECAY_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
float sustain = clamp(params[SUSTAIN_PARAM].getValue() + inputs[SUSTAIN_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
float release = clamp(params[RELEASE_PARAM].getValue() + inputs[RELEASE_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
// Gate and trigger | // Gate and trigger | ||||
bool gated = inputs[GATE_INPUT].value >= 1.f; | |||||
if (trigger.process(inputs[TRIG_INPUT].value)) | |||||
bool gated = inputs[GATE_INPUT].getVoltage() >= 1.f; | |||||
if (trigger.process(inputs[TRIG_INPUT].getVoltage())) | |||||
decaying = false; | decaying = false; | ||||
const float base = 20000.f; | const float base = 20000.f; | ||||
@@ -94,7 +94,7 @@ struct ADSR : Module { | |||||
bool sustaining = isNear(env, sustain, 1e-3); | bool sustaining = isNear(env, sustain, 1e-3); | ||||
bool resting = isNear(env, 0.f, 1e-3); | bool resting = isNear(env, 0.f, 1e-3); | ||||
outputs[ENVELOPE_OUTPUT].value = 10.f * env; | |||||
outputs[ENVELOPE_OUTPUT].setVoltage(10.f * env); | |||||
// Lights | // Lights | ||||
lights[ATTACK_LIGHT].value = (gated && !decaying) ? 1.f : 0.f; | lights[ATTACK_LIGHT].value = (gated && !decaying) ? 1.f : 0.f; | ||||
@@ -49,12 +49,12 @@ struct Delay : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
// Get input to delay block | // Get input to delay block | ||||
float in = inputs[IN_INPUT].value; | |||||
float feedback = clamp(params[FEEDBACK_PARAM].value + inputs[FEEDBACK_INPUT].value / 10.0f, 0.0f, 1.0f); | |||||
float in = inputs[IN_INPUT].getVoltage(); | |||||
float feedback = clamp(params[FEEDBACK_PARAM].getValue() + inputs[FEEDBACK_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f); | |||||
float dry = in + lastWet * feedback; | float dry = in + lastWet * feedback; | ||||
// Compute delay time in seconds | // Compute delay time in seconds | ||||
float delay = 1e-3 * std::pow(10.0f / 1e-3, clamp(params[TIME_PARAM].value + inputs[TIME_INPUT].value / 10.0f, 0.0f, 1.0f)); | |||||
float delay = 1e-3 * std::pow(10.0f / 1e-3, clamp(params[TIME_PARAM].getValue() + inputs[TIME_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f)); | |||||
// Number of delay samples | // Number of delay samples | ||||
float index = delay * args.sampleRate; | float index = delay * args.sampleRate; | ||||
@@ -91,7 +91,7 @@ struct Delay : Module { | |||||
// Apply color to delay wet output | // Apply color to delay wet output | ||||
// TODO Make it sound better | // TODO Make it sound better | ||||
float color = clamp(params[COLOR_PARAM].value + inputs[COLOR_INPUT].value / 10.0f, 0.0f, 1.0f); | |||||
float color = clamp(params[COLOR_PARAM].getValue() + inputs[COLOR_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f); | |||||
float lowpassFreq = 10000.0f * std::pow(10.0f, clamp(2.0f*color, 0.0f, 1.0f)); | float lowpassFreq = 10000.0f * std::pow(10.0f, clamp(2.0f*color, 0.0f, 1.0f)); | ||||
lowpassFilter.setCutoff(lowpassFreq / args.sampleRate); | lowpassFilter.setCutoff(lowpassFreq / args.sampleRate); | ||||
lowpassFilter.process(wet); | lowpassFilter.process(wet); | ||||
@@ -103,9 +103,9 @@ struct Delay : Module { | |||||
lastWet = wet; | lastWet = wet; | ||||
float mix = clamp(params[MIX_PARAM].value + inputs[MIX_INPUT].value / 10.0f, 0.0f, 1.0f); | |||||
float mix = clamp(params[MIX_PARAM].getValue() + inputs[MIX_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f); | |||||
float out = crossfade(in, wet, mix); | float out = crossfade(in, wet, mix); | ||||
outputs[OUT_OUTPUT].value = out; | |||||
outputs[OUT_OUTPUT].setVoltage(out); | |||||
} | } | ||||
}; | }; | ||||
@@ -108,17 +108,17 @@ struct LFO : Module { | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
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.f); | |||||
oscillator.offset = (params[OFFSET_PARAM].value > 0.f); | |||||
oscillator.invert = (params[INVERT_PARAM].value <= 0.f); | |||||
oscillator.setPitch(params[FREQ_PARAM].getValue() + params[FM1_PARAM].getValue() * inputs[FM1_INPUT].getVoltage() + params[FM2_PARAM].getValue() * inputs[FM2_INPUT].getVoltage()); | |||||
oscillator.setPulseWidth(params[PW_PARAM].getValue() + params[PWM_PARAM].getValue() * inputs[PW_INPUT].getVoltage() / 10.f); | |||||
oscillator.offset = (params[OFFSET_PARAM].getValue() > 0.f); | |||||
oscillator.invert = (params[INVERT_PARAM].getValue() <= 0.f); | |||||
oscillator.step(args.sampleTime); | oscillator.step(args.sampleTime); | ||||
oscillator.setReset(inputs[RESET_INPUT].value); | |||||
oscillator.setReset(inputs[RESET_INPUT].getVoltage()); | |||||
outputs[SIN_OUTPUT].value = 5.f * oscillator.sin(); | |||||
outputs[TRI_OUTPUT].value = 5.f * oscillator.tri(); | |||||
outputs[SAW_OUTPUT].value = 5.f * oscillator.saw(); | |||||
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr(); | |||||
outputs[SIN_OUTPUT].setVoltage(5.f * oscillator.sin()); | |||||
outputs[TRI_OUTPUT].setVoltage(5.f * oscillator.tri()); | |||||
outputs[SAW_OUTPUT].setVoltage(5.f * oscillator.saw()); | |||||
outputs[SQR_OUTPUT].setVoltage(5.f * oscillator.sqr()); | |||||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | ||||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | ||||
@@ -203,13 +203,13 @@ struct LFO2 : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float deltaTime = args.sampleTime; | float deltaTime = args.sampleTime; | ||||
oscillator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value); | |||||
oscillator.offset = (params[OFFSET_PARAM].value > 0.f); | |||||
oscillator.invert = (params[INVERT_PARAM].value <= 0.f); | |||||
oscillator.setPitch(params[FREQ_PARAM].getValue() + params[FM_PARAM].getValue() * inputs[FM_INPUT].getVoltage()); | |||||
oscillator.offset = (params[OFFSET_PARAM].getValue() > 0.f); | |||||
oscillator.invert = (params[INVERT_PARAM].getValue() <= 0.f); | |||||
oscillator.step(deltaTime); | oscillator.step(deltaTime); | ||||
oscillator.setReset(inputs[RESET_INPUT].value); | |||||
oscillator.setReset(inputs[RESET_INPUT].getVoltage()); | |||||
float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value; | |||||
float wave = params[WAVE_PARAM].getValue() + inputs[WAVE_INPUT].getVoltage(); | |||||
wave = clamp(wave, 0.f, 3.f); | wave = clamp(wave, 0.f, 3.f); | ||||
float interp; | float interp; | ||||
if (wave < 1.f) | if (wave < 1.f) | ||||
@@ -218,7 +218,7 @@ struct LFO2 : Module { | |||||
interp = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); | interp = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); | ||||
else | else | ||||
interp = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f); | interp = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f); | ||||
outputs[INTERP_OUTPUT].value = 5.f * interp; | |||||
outputs[INTERP_OUTPUT].setVoltage(5.f * interp); | |||||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | ||||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | ||||
@@ -37,11 +37,11 @@ struct Mutes : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float out = 0.f; | float out = 0.f; | ||||
for (int i = 0; i < NUM_CHANNELS; i++) { | for (int i = 0; i < NUM_CHANNELS; i++) { | ||||
if (muteTrigger[i].process(params[MUTE_PARAM + i].value)) | |||||
if (muteTrigger[i].process(params[MUTE_PARAM + i].getValue())) | |||||
state[i] ^= true; | state[i] ^= true; | ||||
if (inputs[IN_INPUT + i].active) | if (inputs[IN_INPUT + i].active) | ||||
out = inputs[IN_INPUT + i].value; | |||||
outputs[OUT_OUTPUT + i].value = state[i] ? out : 0.f; | |||||
out = inputs[IN_INPUT + i].getVoltage(); | |||||
outputs[OUT_OUTPUT + i].setVoltage(state[i] ? out : 0.f); | |||||
lights[MUTE_LIGHT + i].setBrightness(state[i] ? 0.9f : 0.f); | lights[MUTE_LIGHT + i].setBrightness(state[i] ? 0.9f : 0.f); | ||||
} | } | ||||
} | } | ||||
@@ -110,7 +110,7 @@ struct SEQ3 : Module { | |||||
} | } | ||||
void setIndex(int index) { | void setIndex(int index) { | ||||
int numSteps = (int) clamp(std::round(params[STEPS_PARAM].value + inputs[STEPS_INPUT].value), 1.0f, 8.0f); | |||||
int numSteps = (int) clamp(std::round(params[STEPS_PARAM].getValue() + inputs[STEPS_INPUT].getVoltage()), 1.0f, 8.0f); | |||||
phase = 0.f; | phase = 0.f; | ||||
this->index = index; | this->index = index; | ||||
if (this->index >= numSteps) | if (this->index >= numSteps) | ||||
@@ -119,7 +119,7 @@ struct SEQ3 : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
// Run | // Run | ||||
if (runningTrigger.process(params[RUN_PARAM].value)) { | |||||
if (runningTrigger.process(params[RUN_PARAM].getValue())) { | |||||
running = !running; | running = !running; | ||||
} | } | ||||
@@ -127,14 +127,14 @@ struct SEQ3 : Module { | |||||
if (running) { | if (running) { | ||||
if (inputs[EXT_CLOCK_INPUT].active) { | if (inputs[EXT_CLOCK_INPUT].active) { | ||||
// External clock | // External clock | ||||
if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].value)) { | |||||
if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].getVoltage())) { | |||||
setIndex(index + 1); | setIndex(index + 1); | ||||
} | } | ||||
gateIn = clockTrigger.isHigh(); | gateIn = clockTrigger.isHigh(); | ||||
} | } | ||||
else { | else { | ||||
// Internal clock | // Internal clock | ||||
float clockTime = std::pow(2.0f, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value); | |||||
float clockTime = std::pow(2.0f, params[CLOCK_PARAM].getValue() + inputs[CLOCK_INPUT].getVoltage()); | |||||
phase += clockTime * args.sampleTime; | phase += clockTime * args.sampleTime; | ||||
if (phase >= 1.0f) { | if (phase >= 1.0f) { | ||||
setIndex(index + 1); | setIndex(index + 1); | ||||
@@ -144,24 +144,24 @@ struct SEQ3 : Module { | |||||
} | } | ||||
// Reset | // Reset | ||||
if (resetTrigger.process(params[RESET_PARAM].value + inputs[RESET_INPUT].value)) { | |||||
if (resetTrigger.process(params[RESET_PARAM].getValue() + inputs[RESET_INPUT].getVoltage())) { | |||||
setIndex(0); | setIndex(0); | ||||
} | } | ||||
// Gate buttons | // Gate buttons | ||||
for (int i = 0; i < 8; i++) { | for (int i = 0; i < 8; i++) { | ||||
if (gateTriggers[i].process(params[GATE_PARAM + i].value)) { | |||||
if (gateTriggers[i].process(params[GATE_PARAM + i].getValue())) { | |||||
gates[i] = !gates[i]; | gates[i] = !gates[i]; | ||||
} | } | ||||
outputs[GATE_OUTPUT + i].value = (running && gateIn && i == index && gates[i]) ? 10.0f : 0.0f; | |||||
outputs[GATE_OUTPUT + i].setVoltage((running && gateIn && i == index && gates[i]) ? 10.0f : 0.0f); | |||||
lights[GATE_LIGHTS + i].setSmoothBrightness((gateIn && i == index) ? (gates[i] ? 1.f : 0.33) : (gates[i] ? 0.66 : 0.0), args.sampleTime); | lights[GATE_LIGHTS + i].setSmoothBrightness((gateIn && i == index) ? (gates[i] ? 1.f : 0.33) : (gates[i] ? 0.66 : 0.0), args.sampleTime); | ||||
} | } | ||||
// Outputs | // Outputs | ||||
outputs[ROW1_OUTPUT].value = params[ROW1_PARAM + index].value; | |||||
outputs[ROW2_OUTPUT].value = params[ROW2_PARAM + index].value; | |||||
outputs[ROW3_OUTPUT].value = params[ROW3_PARAM + index].value; | |||||
outputs[GATES_OUTPUT].value = (gateIn && gates[index]) ? 10.0f : 0.0f; | |||||
outputs[ROW1_OUTPUT].setVoltage(params[ROW1_PARAM + index].getValue()); | |||||
outputs[ROW2_OUTPUT].setVoltage(params[ROW2_PARAM + index].getValue()); | |||||
outputs[ROW3_OUTPUT].setVoltage(params[ROW3_PARAM + index].getValue()); | |||||
outputs[GATES_OUTPUT].setVoltage((gateIn && gates[index]) ? 10.0f : 0.0f); | |||||
lights[RUNNING_LIGHT].value = (running); | lights[RUNNING_LIGHT].value = (running); | ||||
lights[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), args.sampleTime); | lights[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), args.sampleTime); | ||||
lights[GATES_LIGHT].setSmoothBrightness(gateIn, args.sampleTime); | lights[GATES_LIGHT].setSmoothBrightness(gateIn, args.sampleTime); | ||||
@@ -59,28 +59,28 @@ struct Scope : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
// Modes | // Modes | ||||
if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { | |||||
if (sumTrigger.process(params[LISSAJOUS_PARAM].getValue())) { | |||||
lissajous = !lissajous; | lissajous = !lissajous; | ||||
} | } | ||||
lights[PLOT_LIGHT].value = lissajous ? 0.0f : 1.0f; | lights[PLOT_LIGHT].value = lissajous ? 0.0f : 1.0f; | ||||
lights[LISSAJOUS_LIGHT].value = lissajous ? 1.0f : 0.0f; | lights[LISSAJOUS_LIGHT].value = lissajous ? 1.0f : 0.0f; | ||||
if (extTrigger.process(params[EXTERNAL_PARAM].value)) { | |||||
if (extTrigger.process(params[EXTERNAL_PARAM].getValue())) { | |||||
external = !external; | external = !external; | ||||
} | } | ||||
lights[INTERNAL_LIGHT].value = external ? 0.0f : 1.0f; | lights[INTERNAL_LIGHT].value = external ? 0.0f : 1.0f; | ||||
lights[EXTERNAL_LIGHT].value = external ? 1.0f : 0.0f; | lights[EXTERNAL_LIGHT].value = external ? 1.0f : 0.0f; | ||||
// Compute time | // Compute time | ||||
float deltaTime = std::pow(2.0f, -params[TIME_PARAM].value); | |||||
float deltaTime = std::pow(2.0f, -params[TIME_PARAM].getValue()); | |||||
int frameCount = (int) std::ceil(deltaTime * args.sampleRate); | int frameCount = (int) std::ceil(deltaTime * args.sampleRate); | ||||
// Add frame to buffer | // Add frame to buffer | ||||
if (bufferIndex < BUFFER_SIZE) { | if (bufferIndex < BUFFER_SIZE) { | ||||
if (++frameIndex > frameCount) { | if (++frameIndex > frameCount) { | ||||
frameIndex = 0; | frameIndex = 0; | ||||
bufferX[bufferIndex] = inputs[X_INPUT].value; | |||||
bufferY[bufferIndex] = inputs[Y_INPUT].value; | |||||
bufferX[bufferIndex] = inputs[X_INPUT].getVoltage(); | |||||
bufferY[bufferIndex] = inputs[Y_INPUT].getVoltage(); | |||||
bufferIndex++; | bufferIndex++; | ||||
} | } | ||||
} | } | ||||
@@ -101,11 +101,11 @@ struct Scope : Module { | |||||
frameIndex++; | frameIndex++; | ||||
// Must go below 0.1fV to trigger | // Must go below 0.1fV to trigger | ||||
float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value; | |||||
float gate = external ? inputs[TRIG_INPUT].getVoltage() : inputs[X_INPUT].getVoltage(); | |||||
// Reset if triggered | // Reset if triggered | ||||
float holdTime = 0.1f; | float holdTime = 0.1f; | ||||
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].value - 0.1f, params[TRIG_PARAM].value, 0.f, 1.f)) || (frameIndex >= args.sampleRate * holdTime)) { | |||||
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].getValue() - 0.1f, params[TRIG_PARAM].getValue(), 0.f, 1.f)) || (frameIndex >= args.sampleRate * holdTime)) { | |||||
bufferIndex = 0; frameIndex = 0; return; | bufferIndex = 0; frameIndex = 0; return; | ||||
} | } | ||||
@@ -260,10 +260,10 @@ struct ScopeDisplay : TransparentWidget { | |||||
if (!module) | if (!module) | ||||
return; | return; | ||||
float gainX = std::pow(2.0f, std::round(module->params[Scope::X_SCALE_PARAM].value)); | |||||
float gainY = std::pow(2.0f, std::round(module->params[Scope::Y_SCALE_PARAM].value)); | |||||
float offsetX = module->params[Scope::X_POS_PARAM].value; | |||||
float offsetY = module->params[Scope::Y_POS_PARAM].value; | |||||
float gainX = std::pow(2.0f, std::round(module->params[Scope::X_SCALE_PARAM].getValue())); | |||||
float gainY = std::pow(2.0f, std::round(module->params[Scope::Y_SCALE_PARAM].getValue())); | |||||
float offsetX = module->params[Scope::X_POS_PARAM].getValue(); | |||||
float offsetY = module->params[Scope::Y_POS_PARAM].getValue(); | |||||
float valuesX[BUFFER_SIZE]; | float valuesX[BUFFER_SIZE]; | ||||
float valuesY[BUFFER_SIZE]; | float valuesY[BUFFER_SIZE]; | ||||
@@ -297,7 +297,7 @@ struct ScopeDisplay : TransparentWidget { | |||||
drawWaveform(args, valuesX, NULL); | drawWaveform(args, valuesX, NULL); | ||||
} | } | ||||
float valueTrig = (module->params[Scope::TRIG_PARAM].value + offsetX) * gainX / 10.0f; | |||||
float valueTrig = (module->params[Scope::TRIG_PARAM].getValue() + offsetX) * gainX / 10.0f; | |||||
drawTrig(args, valueTrig); | drawTrig(args, valueTrig); | ||||
} | } | ||||
@@ -1,7 +1,8 @@ | |||||
#include "plugin.hpp" | #include "plugin.hpp" | ||||
template <int TYPE> | |||||
// Only valid for <1, 4> and <4, 1> | |||||
template <int INPUTS, int OUTPUTS> | |||||
struct SequentialSwitch : Module { | struct SequentialSwitch : Module { | ||||
enum ParamIds { | enum ParamIds { | ||||
CHANNELS_PARAM, | CHANNELS_PARAM, | ||||
@@ -10,11 +11,11 @@ struct SequentialSwitch : Module { | |||||
enum InputIds { | enum InputIds { | ||||
CLOCK_INPUT, | CLOCK_INPUT, | ||||
RESET_INPUT, | RESET_INPUT, | ||||
ENUMS(IN_INPUT, TYPE == 1 ? 1 : 4), | |||||
ENUMS(IN_INPUTS, INPUTS), | |||||
NUM_INPUTS | NUM_INPUTS | ||||
}; | }; | ||||
enum OutputIds { | enum OutputIds { | ||||
ENUMS(OUT_OUTPUT, TYPE == 1 ? 4 : 1), | |||||
ENUMS(OUT_OUTPUTS, OUTPUTS), | |||||
NUM_OUTPUTS | NUM_OUTPUTS | ||||
}; | }; | ||||
enum LightIds { | enum LightIds { | ||||
@@ -25,61 +26,69 @@ struct SequentialSwitch : Module { | |||||
dsp::SchmittTrigger clockTrigger; | dsp::SchmittTrigger clockTrigger; | ||||
dsp::SchmittTrigger resetTrigger; | dsp::SchmittTrigger resetTrigger; | ||||
int channel = 0; | int channel = 0; | ||||
dsp::SlewLimiter channelFilter[4]; | |||||
dsp::Counter lightCounter; | |||||
dsp::SlewLimiter clickFilters[4]; | |||||
SequentialSwitch() { | SequentialSwitch() { | ||||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); | ||||
params[CHANNELS_PARAM].config(0.0, 2.0, 0.0, "Channels", "", 0.f, 1.f, 2.f); | |||||
params[CHANNELS_PARAM].config(0.0, 2.0, 0.0, "Channels", "", 0, -1, 4); | |||||
for (int i = 0; i < 4; i++) { | |||||
channelFilter[i].rise = 0.01f; | |||||
channelFilter[i].fall = 0.01f; | |||||
for (int i = 0; i < OUTPUTS; i++) { | |||||
clickFilters[i].rise = 400.f; // Hz | |||||
clickFilters[i].fall = 400.f; // Hz | |||||
} | } | ||||
lightCounter.setPeriod(512); | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
// Determine current channel | // Determine current channel | ||||
if (clockTrigger.process(inputs[CLOCK_INPUT].value / 2.f)) { | |||||
if (clockTrigger.process(rescale(inputs[CLOCK_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) { | |||||
channel++; | channel++; | ||||
} | } | ||||
if (resetTrigger.process(inputs[RESET_INPUT].value / 2.f)) { | |||||
if (resetTrigger.process(rescale(inputs[RESET_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) { | |||||
channel = 0; | channel = 0; | ||||
} | } | ||||
int channels = 4 - (int) params[CHANNELS_PARAM].value; | |||||
channel %= channels; | |||||
int channels = 4 - (int) std::round(params[CHANNELS_PARAM].getValue()); | |||||
if (channel >= channels) | |||||
channel = 0; | |||||
// Filter channels | |||||
for (int i = 0; i < 4; i++) { | |||||
channelFilter[i].process(channel == i ? 1.f : 0.f); | |||||
// Get input | |||||
float v = 0.f; | |||||
if (INPUTS == 1) { | |||||
v = inputs[IN_INPUTS + 0].getVoltage(); | |||||
} | } | ||||
// Set outputs | |||||
if (TYPE == 1) { | |||||
float out = inputs[IN_INPUT + 0].value; | |||||
for (int i = 0; i < 4; i++) { | |||||
outputs[OUT_OUTPUT + i].value = channelFilter[i].out * out; | |||||
else { | |||||
for (int i = 0; i < INPUTS; i++) { | |||||
float in = inputs[IN_INPUTS + i].getVoltage(); | |||||
v += in * clickFilters[i].process(args.sampleTime, channel == i); | |||||
} | } | ||||
} | } | ||||
// Set output | |||||
if (OUTPUTS == 1) { | |||||
outputs[OUT_OUTPUTS + 0].setVoltage(v); | |||||
} | |||||
else { | else { | ||||
float out = 0.f; | |||||
for (int i = 0; i < 4; i++) { | |||||
out += channelFilter[i].out * inputs[IN_INPUT + i].value; | |||||
for (int i = 0; i < OUTPUTS; i++) { | |||||
float out = v * clickFilters[i].process(args.sampleTime, channel == i); | |||||
outputs[OUT_OUTPUTS + i].setVoltage(out); | |||||
} | } | ||||
outputs[OUT_OUTPUT + 0].value = out; | |||||
} | } | ||||
// Set lights | // Set lights | ||||
for (int i = 0; i < 4; i++) { | |||||
lights[CHANNEL_LIGHT + i].setBrightness(channelFilter[i].out); | |||||
if (lightCounter.process()) { | |||||
for (int i = 0; i < 4; i++) { | |||||
lights[CHANNEL_LIGHT + i].setBrightness(channel == i); | |||||
} | |||||
} | } | ||||
} | } | ||||
}; | }; | ||||
struct SequentialSwitch1Widget : ModuleWidget { | struct SequentialSwitch1Widget : ModuleWidget { | ||||
typedef SequentialSwitch<1> TSequentialSwitch; | |||||
typedef SequentialSwitch<1, 4> TSequentialSwitch; | |||||
SequentialSwitch1Widget(SequentialSwitch<1> *module) { | |||||
SequentialSwitch1Widget(TSequentialSwitch *module) { | |||||
setModule(module); | setModule(module); | ||||
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch1.svg"))); | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch1.svg"))); | ||||
@@ -90,12 +99,12 @@ struct SequentialSwitch1Widget : ModuleWidget { | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); | addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); | ||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT)); | addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT)); | ||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUT + 0)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUTS + 0)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUT + 0)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUT + 1)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUT + 2)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUT + 3)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUTS + 0)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUTS + 1)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUTS + 2)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUTS + 3)); | |||||
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); | addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); | ||||
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); | addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); | ||||
@@ -105,13 +114,13 @@ struct SequentialSwitch1Widget : ModuleWidget { | |||||
}; | }; | ||||
Model *modelSequentialSwitch1 = createModel<SequentialSwitch<1>, SequentialSwitch1Widget>("SequentialSwitch1"); | |||||
Model *modelSequentialSwitch1 = createModel<SequentialSwitch<1, 4>, SequentialSwitch1Widget>("SequentialSwitch1"); | |||||
struct SequentialSwitch2Widget : ModuleWidget { | struct SequentialSwitch2Widget : ModuleWidget { | ||||
typedef SequentialSwitch<2> TSequentialSwitch; | |||||
typedef SequentialSwitch<4, 1> TSequentialSwitch; | |||||
SequentialSwitch2Widget(SequentialSwitch<2> *module) { | |||||
SequentialSwitch2Widget(TSequentialSwitch *module) { | |||||
setModule(module); | setModule(module); | ||||
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch2.svg"))); | setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch2.svg"))); | ||||
@@ -122,12 +131,12 @@ struct SequentialSwitch2Widget : ModuleWidget { | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); | addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); | ||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT)); | addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT)); | ||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUT + 0)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUT + 1)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUT + 2)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUT + 3)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUTS + 0)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUTS + 1)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUTS + 2)); | |||||
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUTS + 3)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUT + 0)); | |||||
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUTS + 0)); | |||||
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); | addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); | ||||
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); | addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); | ||||
@@ -137,4 +146,4 @@ struct SequentialSwitch2Widget : ModuleWidget { | |||||
}; | }; | ||||
Model *modelSequentialSwitch2 = createModel<SequentialSwitch<2>, SequentialSwitch2Widget>("SequentialSwitch2"); | |||||
Model *modelSequentialSwitch2 = createModel<SequentialSwitch<4, 1>, SequentialSwitch2Widget>("SequentialSwitch2"); |
@@ -42,7 +42,7 @@ struct Unity : Module { | |||||
for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
// Inputs | // Inputs | ||||
for (int j = 0; j < 6; j++) { | for (int j = 0; j < 6; j++) { | ||||
mix[i] += inputs[IN_INPUTS + 6 * i + j].value; | |||||
mix[i] += inputs[IN_INPUTS + 6 * i + j].getVoltage(); | |||||
if (inputs[IN_INPUTS + 6 * i + j].active) | if (inputs[IN_INPUTS + 6 * i + j].active) | ||||
count[i]++; | count[i]++; | ||||
} | } | ||||
@@ -58,12 +58,12 @@ struct Unity : Module { | |||||
for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
// Params | // Params | ||||
if (count[i] > 0 && (int) std::round(params[AVG1_PARAM + i].value) == 1) | |||||
if (count[i] > 0 && (int) std::round(params[AVG1_PARAM + i].getValue()) == 1) | |||||
mix[i] /= count[i]; | mix[i] /= count[i]; | ||||
// Outputs | // Outputs | ||||
outputs[MIX1_OUTPUT + 2 * i].value = mix[i]; | |||||
outputs[INV1_OUTPUT + 2 * i].value = -mix[i]; | |||||
outputs[MIX1_OUTPUT + 2 * i].setVoltage(mix[i]); | |||||
outputs[INV1_OUTPUT + 2 * i].setVoltage(-mix[i]); | |||||
vuMeters[i].process(args.sampleTime, mix[i] / 10.f); | vuMeters[i].process(args.sampleTime, mix[i] / 10.f); | ||||
} | } | ||||
@@ -29,13 +29,13 @@ struct VCA : Module { | |||||
} | } | ||||
void stepChannel(InputIds in, ParamIds level, InputIds lin, InputIds exp, OutputIds out) { | void stepChannel(InputIds in, ParamIds level, InputIds lin, InputIds exp, OutputIds out) { | ||||
float v = inputs[in].value * params[level].value; | |||||
float v = inputs[in].getVoltage() * params[level].getValue(); | |||||
if (inputs[lin].active) | if (inputs[lin].active) | ||||
v *= clamp(inputs[lin].value / 10.0f, 0.0f, 1.0f); | |||||
v *= clamp(inputs[lin].getVoltage() / 10.0f, 0.0f, 1.0f); | |||||
const float expBase = 50.0f; | const float expBase = 50.0f; | ||||
if (inputs[exp].active) | if (inputs[exp].active) | ||||
v *= rescale(std::pow(expBase, clamp(inputs[exp].value / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f); | |||||
outputs[out].value = v; | |||||
v *= rescale(std::pow(expBase, clamp(inputs[exp].getVoltage() / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f); | |||||
outputs[out].setVoltage(v); | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
@@ -104,10 +104,10 @@ struct VCA_1 : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float cv = inputs[CV_INPUT].getNormalVoltage(10.f) / 10.f; | float cv = inputs[CV_INPUT].getNormalVoltage(10.f) / 10.f; | ||||
if ((int) params[EXP_PARAM].value == 0) | |||||
if ((int) params[EXP_PARAM].getValue() == 0) | |||||
cv = std::pow(cv, 4.f); | cv = std::pow(cv, 4.f); | ||||
lastCv = cv; | lastCv = cv; | ||||
outputs[OUT_OUTPUT].value = inputs[IN_INPUT].value * params[LEVEL_PARAM].value * cv; | |||||
outputs[OUT_OUTPUT].setVoltage(inputs[IN_INPUT].getVoltage() * params[LEVEL_PARAM].getValue() * cv); | |||||
} | } | ||||
}; | }; | ||||
@@ -93,13 +93,13 @@ struct VCF : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
if (!outputs[LPF_OUTPUT].active && !outputs[HPF_OUTPUT].active) { | if (!outputs[LPF_OUTPUT].active && !outputs[HPF_OUTPUT].active) { | ||||
outputs[LPF_OUTPUT].value = 0.f; | |||||
outputs[HPF_OUTPUT].value = 0.f; | |||||
outputs[LPF_OUTPUT].setVoltage(0.f); | |||||
outputs[HPF_OUTPUT].setVoltage(0.f); | |||||
return; | return; | ||||
} | } | ||||
float input = inputs[IN_INPUT].value / 5.f; | |||||
float drive = clamp(params[DRIVE_PARAM].value + inputs[DRIVE_INPUT].value / 10.f, 0.f, 1.f); | |||||
float input = inputs[IN_INPUT].getVoltage() / 5.f; | |||||
float drive = clamp(params[DRIVE_PARAM].getValue() + inputs[DRIVE_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
float gain = std::pow(1.f + drive, 5); | float gain = std::pow(1.f + drive, 5); | ||||
input *= gain; | input *= gain; | ||||
@@ -107,15 +107,15 @@ struct VCF : Module { | |||||
input += 1e-6f * (2.f * random::uniform() - 1.f); | input += 1e-6f * (2.f * random::uniform() - 1.f); | ||||
// Set resonance | // Set resonance | ||||
float res = clamp(params[RES_PARAM].value + inputs[RES_INPUT].value / 10.f, 0.f, 1.f); | |||||
float res = clamp(params[RES_PARAM].getValue() + inputs[RES_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
filter.resonance = std::pow(res, 2) * 10.f; | filter.resonance = std::pow(res, 2) * 10.f; | ||||
// Set cutoff frequency | // Set cutoff frequency | ||||
float pitch = 0.f; | float pitch = 0.f; | ||||
if (inputs[FREQ_INPUT].active) | if (inputs[FREQ_INPUT].active) | ||||
pitch += inputs[FREQ_INPUT].value * dsp::quadraticBipolar(params[FREQ_CV_PARAM].value); | |||||
pitch += params[FREQ_PARAM].value * 10.f - 5.f; | |||||
pitch += dsp::quadraticBipolar(params[FINE_PARAM].value * 2.f - 1.f) * 7.f / 12.f; | |||||
pitch += inputs[FREQ_INPUT].getVoltage() * dsp::quadraticBipolar(params[FREQ_CV_PARAM].getValue()); | |||||
pitch += params[FREQ_PARAM].getValue() * 10.f - 5.f; | |||||
pitch += dsp::quadraticBipolar(params[FINE_PARAM].getValue() * 2.f - 1.f) * 7.f / 12.f; | |||||
float cutoff = 261.626f * std::pow(2.f, pitch); | float cutoff = 261.626f * std::pow(2.f, pitch); | ||||
cutoff = clamp(cutoff, 1.f, 8000.f); | cutoff = clamp(cutoff, 1.f, 8000.f); | ||||
filter.setCutoff(cutoff); | filter.setCutoff(cutoff); | ||||
@@ -136,15 +136,15 @@ struct VCF : Module { | |||||
// Set outputs | // Set outputs | ||||
if (outputs[LPF_OUTPUT].active) { | if (outputs[LPF_OUTPUT].active) { | ||||
outputs[LPF_OUTPUT].value = 5.f * lowpassDecimator.process(lowpassBuf); | |||||
outputs[LPF_OUTPUT].setVoltage(5.f * lowpassDecimator.process(lowpassBuf)); | |||||
} | } | ||||
if (outputs[HPF_OUTPUT].active) { | if (outputs[HPF_OUTPUT].active) { | ||||
outputs[HPF_OUTPUT].value = 5.f * highpassDecimator.process(highpassBuf); | |||||
outputs[HPF_OUTPUT].setVoltage(5.f * highpassDecimator.process(highpassBuf)); | |||||
} | } | ||||
*/ | */ | ||||
filter.process(input, args.sampleTime); | filter.process(input, args.sampleTime); | ||||
outputs[LPF_OUTPUT].value = 5.f * filter.lowpass; | |||||
outputs[HPF_OUTPUT].value = 5.f * filter.highpass; | |||||
outputs[LPF_OUTPUT].setVoltage(5.f * filter.lowpass); | |||||
outputs[HPF_OUTPUT].setVoltage(5.f * filter.highpass); | |||||
} | } | ||||
}; | }; | ||||
@@ -21,27 +21,27 @@ struct VCMixer : Module { | |||||
VCMixer() { | VCMixer() { | ||||
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); | config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); | ||||
params[MIX_LVL_PARAM].config(0.0, 2.0, 1.0, "Master level"); | |||||
params[LVL_PARAM + 0].config(0.0, 1.0, 1.0, "Ch 1 level"); | |||||
params[LVL_PARAM + 1].config(0.0, 1.0, 1.0, "Ch 2 level"); | |||||
params[LVL_PARAM + 2].config(0.0, 1.0, 1.0, "Ch 3 level"); | |||||
params[LVL_PARAM + 3].config(0.0, 1.0, 1.0, "Ch 4 level"); | |||||
params[MIX_LVL_PARAM].config(0.0, 2.0, 1.0, "Master level", "%", 0, 100); | |||||
params[LVL_PARAM + 0].config(0.0, 1.0, 1.0, "Ch 1 level", "%", 0, 100); | |||||
params[LVL_PARAM + 1].config(0.0, 1.0, 1.0, "Ch 2 level", "%", 0, 100); | |||||
params[LVL_PARAM + 2].config(0.0, 1.0, 1.0, "Ch 3 level", "%", 0, 100); | |||||
params[LVL_PARAM + 3].config(0.0, 1.0, 1.0, "Ch 4 level", "%", 0, 100); | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float mix = 0.f; | float mix = 0.f; | ||||
for (int i = 0; i < 4; i++) { | for (int i = 0; i < 4; i++) { | ||||
float ch = inputs[CH_INPUT + i].value; | |||||
ch *= std::pow(params[LVL_PARAM + i].value, 2.f); | |||||
float ch = inputs[CH_INPUT + i].getVoltage(); | |||||
ch *= std::pow(params[LVL_PARAM + i].getValue(), 2.f); | |||||
if (inputs[CV_INPUT + i].active) | if (inputs[CV_INPUT + i].active) | ||||
ch *= clamp(inputs[CV_INPUT + i].value / 10.f, 0.f, 1.f); | |||||
outputs[CH_OUTPUT + i].value = ch; | |||||
ch *= clamp(inputs[CV_INPUT + i].getVoltage() / 10.f, 0.f, 1.f); | |||||
outputs[CH_OUTPUT + i].setVoltage(ch); | |||||
mix += ch; | mix += ch; | ||||
} | } | ||||
mix *= params[MIX_LVL_PARAM].value; | |||||
mix *= params[MIX_LVL_PARAM].getValue(); | |||||
if (inputs[MIX_CV_INPUT].active) | if (inputs[MIX_CV_INPUT].active) | ||||
mix *= clamp(inputs[MIX_CV_INPUT].value / 10.f, 0.f, 1.f); | |||||
outputs[MIX_OUTPUT].value = mix; | |||||
mix *= clamp(inputs[MIX_CV_INPUT].getVoltage() / 10.f, 0.f, 1.f); | |||||
outputs[MIX_OUTPUT].setVoltage(mix); | |||||
} | } | ||||
}; | }; | ||||
@@ -205,29 +205,29 @@ struct VCO : Module { | |||||
} | } | ||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
oscillator.analog = params[MODE_PARAM].value > 0.f; | |||||
oscillator.soft = params[SYNC_PARAM].value <= 0.f; | |||||
oscillator.analog = params[MODE_PARAM].getValue() > 0.f; | |||||
oscillator.soft = params[SYNC_PARAM].getValue() <= 0.f; | |||||
float pitchFine = 3.f * dsp::quadraticBipolar(params[FINE_PARAM].value); | |||||
float pitchCv = 12.f * inputs[PITCH_INPUT].value; | |||||
float pitchFine = 3.f * dsp::quadraticBipolar(params[FINE_PARAM].getValue()); | |||||
float pitchCv = 12.f * inputs[PITCH_INPUT].getVoltage(); | |||||
if (inputs[FM_INPUT].active) { | if (inputs[FM_INPUT].active) { | ||||
pitchCv += dsp::quadraticBipolar(params[FM_PARAM].value) * 12.f * inputs[FM_INPUT].value; | |||||
pitchCv += dsp::quadraticBipolar(params[FM_PARAM].getValue()) * 12.f * inputs[FM_INPUT].getVoltage(); | |||||
} | } | ||||
oscillator.setPitch(params[FREQ_PARAM].value, pitchFine + pitchCv); | |||||
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.f); | |||||
oscillator.setPitch(params[FREQ_PARAM].getValue(), pitchFine + pitchCv); | |||||
oscillator.setPulseWidth(params[PW_PARAM].getValue() + params[PWM_PARAM].getValue() * inputs[PW_INPUT].getVoltage() / 10.f); | |||||
oscillator.syncEnabled = inputs[SYNC_INPUT].active; | oscillator.syncEnabled = inputs[SYNC_INPUT].active; | ||||
oscillator.process(args.sampleTime, inputs[SYNC_INPUT].value); | |||||
oscillator.process(args.sampleTime, inputs[SYNC_INPUT].getVoltage()); | |||||
// Set output | // Set output | ||||
if (outputs[SIN_OUTPUT].active) | if (outputs[SIN_OUTPUT].active) | ||||
outputs[SIN_OUTPUT].value = 5.f * oscillator.sin(); | |||||
outputs[SIN_OUTPUT].setVoltage(5.f * oscillator.sin()); | |||||
if (outputs[TRI_OUTPUT].active) | if (outputs[TRI_OUTPUT].active) | ||||
outputs[TRI_OUTPUT].value = 5.f * oscillator.tri(); | |||||
outputs[TRI_OUTPUT].setVoltage(5.f * oscillator.tri()); | |||||
if (outputs[SAW_OUTPUT].active) | if (outputs[SAW_OUTPUT].active) | ||||
outputs[SAW_OUTPUT].value = 5.f * oscillator.saw(); | |||||
outputs[SAW_OUTPUT].setVoltage(5.f * oscillator.saw()); | |||||
if (outputs[SQR_OUTPUT].active) | if (outputs[SQR_OUTPUT].active) | ||||
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr(); | |||||
outputs[SQR_OUTPUT].setVoltage(5.f * oscillator.sqr()); | |||||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime); | ||||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); | ||||
@@ -310,17 +310,17 @@ struct VCO2 : Module { | |||||
void process(const ProcessArgs &args) override { | void process(const ProcessArgs &args) override { | ||||
float deltaTime = args.sampleTime; | float deltaTime = args.sampleTime; | ||||
oscillator.analog = params[MODE_PARAM].value > 0.f; | |||||
oscillator.soft = params[SYNC_PARAM].value <= 0.f; | |||||
oscillator.analog = params[MODE_PARAM].getValue() > 0.f; | |||||
oscillator.soft = params[SYNC_PARAM].getValue() <= 0.f; | |||||
float pitchCv = params[FREQ_PARAM].value + dsp::quadraticBipolar(params[FM_PARAM].value) * 12.f * inputs[FM_INPUT].value; | |||||
float pitchCv = params[FREQ_PARAM].getValue() + dsp::quadraticBipolar(params[FM_PARAM].getValue()) * 12.f * inputs[FM_INPUT].getVoltage(); | |||||
oscillator.setPitch(0.f, pitchCv); | oscillator.setPitch(0.f, pitchCv); | ||||
oscillator.syncEnabled = inputs[SYNC_INPUT].active; | oscillator.syncEnabled = inputs[SYNC_INPUT].active; | ||||
oscillator.process(deltaTime, inputs[SYNC_INPUT].value); | |||||
oscillator.process(deltaTime, inputs[SYNC_INPUT].getVoltage()); | |||||
// Set output | // Set output | ||||
float wave = clamp(params[WAVE_PARAM].value + inputs[WAVE_INPUT].value, 0.f, 3.f); | |||||
float wave = clamp(params[WAVE_PARAM].getValue() + inputs[WAVE_INPUT].getVoltage(), 0.f, 3.f); | |||||
float out; | float out; | ||||
if (wave < 1.f) | if (wave < 1.f) | ||||
out = crossfade(oscillator.sin(), oscillator.tri(), wave); | out = crossfade(oscillator.sin(), oscillator.tri(), wave); | ||||
@@ -328,7 +328,7 @@ struct VCO2 : Module { | |||||
out = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); | out = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); | ||||
else | else | ||||
out = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f); | out = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f); | ||||
outputs[OUT_OUTPUT].value = 5.f * out; | |||||
outputs[OUT_OUTPUT].setVoltage(5.f * out); | |||||
lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime); | ||||
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); | ||||