@@ -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": { | |||
@@ -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); | |||
} | |||
@@ -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; | |||
@@ -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); | |||
} | |||
}; | |||
@@ -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); | |||
@@ -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); | |||
} | |||
} | |||
@@ -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); | |||
@@ -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); | |||
} | |||
@@ -1,7 +1,8 @@ | |||
#include "plugin.hpp" | |||
template <int TYPE> | |||
// Only valid for <1, 4> and <4, 1> | |||
template <int INPUTS, int OUTPUTS> | |||
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<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.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, 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 { | |||
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<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, 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, 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++) { | |||
// 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); | |||
} | |||
@@ -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); | |||
} | |||
}; | |||
@@ -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); | |||
} | |||
}; | |||
@@ -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); | |||
} | |||
}; | |||
@@ -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); | |||