diff --git a/plugin.json b/plugin.json index 5472015..7e70cb2 100644 --- a/plugin.json +++ b/plugin.json @@ -6,6 +6,7 @@ "authorEmail": "contact@vcvrack.com", "pluginUrl": "https://vcvrack.com/Fundamental.html", "authorUrl": "https://vcvrack.com/", + "manualUrl": "https://vcvrack.com/Fundamental.html#manual", "sourceUrl": "https://github.com/VCVRack/Fundamental", "version": "1.0.0", "modules": { diff --git a/src/8vert.cpp b/src/8vert.cpp index e56104a..78a1f8f 100644 --- a/src/8vert.cpp +++ b/src/8vert.cpp @@ -30,8 +30,8 @@ struct _8vert : Module { float lastIn = 10.f; for (int i = 0; i < 8; i++) { 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 + 1].setSmoothBrightness(-out / 5.f, args.sampleTime); } diff --git a/src/ADSR.cpp b/src/ADSR.cpp index 365acab..849a44b 100644 --- a/src/ADSR.cpp +++ b/src/ADSR.cpp @@ -43,14 +43,14 @@ struct ADSR : Module { } 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 - 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; const float base = 20000.f; @@ -94,7 +94,7 @@ struct ADSR : Module { bool sustaining = isNear(env, sustain, 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[ATTACK_LIGHT].value = (gated && !decaying) ? 1.f : 0.f; diff --git a/src/Delay.cpp b/src/Delay.cpp index c161a1e..83f6116 100644 --- a/src/Delay.cpp +++ b/src/Delay.cpp @@ -49,12 +49,12 @@ struct Delay : Module { void process(const ProcessArgs &args) override { // 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; // 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 float index = delay * args.sampleRate; @@ -91,7 +91,7 @@ struct Delay : Module { // Apply color to delay wet output // 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)); lowpassFilter.setCutoff(lowpassFreq / args.sampleRate); lowpassFilter.process(wet); @@ -103,9 +103,9 @@ struct Delay : Module { 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); - outputs[OUT_OUTPUT].value = out; + outputs[OUT_OUTPUT].setVoltage(out); } }; diff --git a/src/LFO.cpp b/src/LFO.cpp index e337346..6acc658 100644 --- a/src/LFO.cpp +++ b/src/LFO.cpp @@ -108,17 +108,17 @@ struct LFO : Module { } 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.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_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); @@ -203,13 +203,13 @@ struct LFO2 : Module { void process(const ProcessArgs &args) override { 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.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); float interp; if (wave < 1.f) @@ -218,7 +218,7 @@ struct LFO2 : Module { interp = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); else 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_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime); diff --git a/src/Mutes.cpp b/src/Mutes.cpp index 3e1c3d6..c958f83 100644 --- a/src/Mutes.cpp +++ b/src/Mutes.cpp @@ -37,11 +37,11 @@ struct Mutes : Module { void process(const ProcessArgs &args) override { float out = 0.f; 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; 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); } } diff --git a/src/SEQ3.cpp b/src/SEQ3.cpp index 65048cd..9cc4368 100644 --- a/src/SEQ3.cpp +++ b/src/SEQ3.cpp @@ -110,7 +110,7 @@ struct SEQ3 : Module { } 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; this->index = index; if (this->index >= numSteps) @@ -119,7 +119,7 @@ struct SEQ3 : Module { void process(const ProcessArgs &args) override { // Run - if (runningTrigger.process(params[RUN_PARAM].value)) { + if (runningTrigger.process(params[RUN_PARAM].getValue())) { running = !running; } @@ -127,14 +127,14 @@ struct SEQ3 : Module { if (running) { if (inputs[EXT_CLOCK_INPUT].active) { // External clock - if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].value)) { + if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].getVoltage())) { setIndex(index + 1); } gateIn = clockTrigger.isHigh(); } else { // 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; if (phase >= 1.0f) { setIndex(index + 1); @@ -144,24 +144,24 @@ struct SEQ3 : Module { } // 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); } // Gate buttons 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]; } - 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); } // 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[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), args.sampleTime); lights[GATES_LIGHT].setSmoothBrightness(gateIn, args.sampleTime); diff --git a/src/Scope.cpp b/src/Scope.cpp index 6891420..493a89b 100644 --- a/src/Scope.cpp +++ b/src/Scope.cpp @@ -59,28 +59,28 @@ struct Scope : Module { void process(const ProcessArgs &args) override { // Modes - if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { + if (sumTrigger.process(params[LISSAJOUS_PARAM].getValue())) { lissajous = !lissajous; } lights[PLOT_LIGHT].value = lissajous ? 0.0f : 1.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; } lights[INTERNAL_LIGHT].value = external ? 0.0f : 1.0f; lights[EXTERNAL_LIGHT].value = external ? 1.0f : 0.0f; // 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); // Add frame to buffer if (bufferIndex < BUFFER_SIZE) { if (++frameIndex > frameCount) { 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++; } } @@ -101,11 +101,11 @@ struct Scope : Module { frameIndex++; // 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 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; } @@ -260,10 +260,10 @@ struct ScopeDisplay : TransparentWidget { if (!module) 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 valuesY[BUFFER_SIZE]; @@ -297,7 +297,7 @@ struct ScopeDisplay : TransparentWidget { 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); } diff --git a/src/SequentialSwitch.cpp b/src/SequentialSwitch.cpp index b1272d9..42a1b96 100644 --- a/src/SequentialSwitch.cpp +++ b/src/SequentialSwitch.cpp @@ -1,7 +1,8 @@ #include "plugin.hpp" -template +// Only valid for <1, 4> and <4, 1> +template struct SequentialSwitch : Module { enum ParamIds { CHANNELS_PARAM, @@ -10,11 +11,11 @@ struct SequentialSwitch : Module { enum InputIds { CLOCK_INPUT, RESET_INPUT, - ENUMS(IN_INPUT, TYPE == 1 ? 1 : 4), + ENUMS(IN_INPUTS, INPUTS), NUM_INPUTS }; enum OutputIds { - ENUMS(OUT_OUTPUT, TYPE == 1 ? 4 : 1), + ENUMS(OUT_OUTPUTS, OUTPUTS), NUM_OUTPUTS }; enum LightIds { @@ -25,61 +26,69 @@ struct SequentialSwitch : Module { dsp::SchmittTrigger clockTrigger; dsp::SchmittTrigger resetTrigger; int channel = 0; - dsp::SlewLimiter channelFilter[4]; + dsp::Counter lightCounter; + dsp::SlewLimiter clickFilters[4]; SequentialSwitch() { 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 { // 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++; } - 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; } - 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 { - 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 - 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 { - typedef SequentialSwitch<1> TSequentialSwitch; + typedef SequentialSwitch<1, 4> TSequentialSwitch; - SequentialSwitch1Widget(SequentialSwitch<1> *module) { + SequentialSwitch1Widget(TSequentialSwitch *module) { setModule(module); setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch1.svg"))); @@ -90,12 +99,12 @@ struct SequentialSwitch1Widget : ModuleWidget { addInput(createInput(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); addInput(createInput(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT)); - addInput(createInput(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUT + 0)); + addInput(createInput(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUTS + 0)); - addOutput(createOutput(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUT + 0)); - addOutput(createOutput(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUT + 1)); - addOutput(createOutput(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUT + 2)); - addOutput(createOutput(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUT + 3)); + addOutput(createOutput(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUTS + 0)); + addOutput(createOutput(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUTS + 1)); + addOutput(createOutput(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUTS + 2)); + addOutput(createOutput(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUTS + 3)); addChild(createLight>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); addChild(createLight>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); @@ -105,13 +114,13 @@ struct SequentialSwitch1Widget : ModuleWidget { }; -Model *modelSequentialSwitch1 = createModel, SequentialSwitch1Widget>("SequentialSwitch1"); +Model *modelSequentialSwitch1 = createModel, SequentialSwitch1Widget>("SequentialSwitch1"); struct SequentialSwitch2Widget : ModuleWidget { - typedef SequentialSwitch<2> TSequentialSwitch; + typedef SequentialSwitch<4, 1> TSequentialSwitch; - SequentialSwitch2Widget(SequentialSwitch<2> *module) { + SequentialSwitch2Widget(TSequentialSwitch *module) { setModule(module); setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch2.svg"))); @@ -122,12 +131,12 @@ struct SequentialSwitch2Widget : ModuleWidget { addInput(createInput(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); addInput(createInput(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT)); - addInput(createInput(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUT + 0)); - addInput(createInput(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUT + 1)); - addInput(createInput(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUT + 2)); - addInput(createInput(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUT + 3)); + addInput(createInput(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUTS + 0)); + addInput(createInput(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUTS + 1)); + addInput(createInput(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUTS + 2)); + addInput(createInput(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUTS + 3)); - addOutput(createOutput(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUT + 0)); + addOutput(createOutput(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUTS + 0)); addChild(createLight>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); addChild(createLight>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); @@ -137,4 +146,4 @@ struct SequentialSwitch2Widget : ModuleWidget { }; -Model *modelSequentialSwitch2 = createModel, SequentialSwitch2Widget>("SequentialSwitch2"); +Model *modelSequentialSwitch2 = createModel, SequentialSwitch2Widget>("SequentialSwitch2"); diff --git a/src/Unity.cpp b/src/Unity.cpp index 8b9a2ee..aeadc2b 100644 --- a/src/Unity.cpp +++ b/src/Unity.cpp @@ -42,7 +42,7 @@ struct Unity : Module { for (int i = 0; i < 2; i++) { // Inputs 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) count[i]++; } @@ -58,12 +58,12 @@ struct Unity : Module { for (int i = 0; i < 2; i++) { // 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]; // 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); } diff --git a/src/VCA.cpp b/src/VCA.cpp index c28ae2d..916ee60 100644 --- a/src/VCA.cpp +++ b/src/VCA.cpp @@ -29,13 +29,13 @@ struct VCA : Module { } 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) - 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; 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 { @@ -104,10 +104,10 @@ struct VCA_1 : Module { void process(const ProcessArgs &args) override { 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); 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); } }; diff --git a/src/VCF.cpp b/src/VCF.cpp index 9b3c993..c2dd17f 100644 --- a/src/VCF.cpp +++ b/src/VCF.cpp @@ -93,13 +93,13 @@ struct VCF : Module { void process(const ProcessArgs &args) override { 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; } - 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); input *= gain; @@ -107,15 +107,15 @@ struct VCF : Module { input += 1e-6f * (2.f * random::uniform() - 1.f); // 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; // Set cutoff frequency float pitch = 0.f; 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); cutoff = clamp(cutoff, 1.f, 8000.f); filter.setCutoff(cutoff); @@ -136,15 +136,15 @@ struct VCF : Module { // Set outputs 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) { - outputs[HPF_OUTPUT].value = 5.f * highpassDecimator.process(highpassBuf); + outputs[HPF_OUTPUT].setVoltage(5.f * highpassDecimator.process(highpassBuf)); } */ 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); } }; diff --git a/src/VCMixer.cpp b/src/VCMixer.cpp index ee8c71f..3f0404d 100644 --- a/src/VCMixer.cpp +++ b/src/VCMixer.cpp @@ -21,27 +21,27 @@ struct VCMixer : Module { VCMixer() { 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 { float mix = 0.f; 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) - 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 *= params[MIX_LVL_PARAM].value; + mix *= params[MIX_LVL_PARAM].getValue(); 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); } }; diff --git a/src/VCO.cpp b/src/VCO.cpp index b2f225e..e3c906b 100644 --- a/src/VCO.cpp +++ b/src/VCO.cpp @@ -205,29 +205,29 @@ struct VCO : Module { } 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) { - 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.process(args.sampleTime, inputs[SYNC_INPUT].value); + oscillator.process(args.sampleTime, inputs[SYNC_INPUT].getVoltage()); // Set output 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) - outputs[TRI_OUTPUT].value = 5.f * oscillator.tri(); + outputs[TRI_OUTPUT].setVoltage(5.f * oscillator.tri()); 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) - 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_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime); @@ -310,17 +310,17 @@ struct VCO2 : Module { void process(const ProcessArgs &args) override { 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.syncEnabled = inputs[SYNC_INPUT].active; - oscillator.process(deltaTime, inputs[SYNC_INPUT].value); + oscillator.process(deltaTime, inputs[SYNC_INPUT].getVoltage()); // 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; if (wave < 1.f) out = crossfade(oscillator.sin(), oscillator.tri(), wave); @@ -328,7 +328,7 @@ struct VCO2 : Module { out = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f); else 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_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime);