diff --git a/src/LFO.cpp b/src/LFO.cpp index 4e23a7f..f68c540 100644 --- a/src/LFO.cpp +++ b/src/LFO.cpp @@ -131,18 +131,18 @@ struct LFO : Module { // FM1, polyphonic pitch += float_4::load(inputs[FM1_INPUT].getVoltages(c)) * fm1Param; // FM2, polyphonic or monophonic - if (inputs[FM2_INPUT].getChannels() == 1) - pitch += inputs[FM2_INPUT].getVoltage() * fm2Param; - else + if (inputs[FM2_INPUT].isPolyphonic()) pitch += float_4::load(inputs[FM2_INPUT].getVoltages(c)) * fm2Param; + else + pitch += inputs[FM2_INPUT].getVoltage() * fm2Param; oscillator->setPitch(pitch); // Pulse width float_4 pw = pwParam; - if (inputs[PW_INPUT].getChannels() == 1) - pw += inputs[PW_INPUT].getVoltage() / 10.f * pwmParam; - else + if (inputs[PW_INPUT].isPolyphonic()) pw += float_4::load(inputs[PW_INPUT].getVoltages(c)) / 10.f * pwmParam; + else + pw += inputs[PW_INPUT].getVoltage() / 10.f * pwmParam; oscillator->setPulseWidth(pw); // Settings @@ -284,10 +284,10 @@ struct LFO2 : Module { // Wave float_4 wave = waveParam; inputs[WAVE_INPUT].getVoltage(); - if (inputs[WAVE_INPUT].getChannels() == 1) - wave += inputs[WAVE_INPUT].getVoltage() / 10.f * 3.f; - else + if (inputs[WAVE_INPUT].isPolyphonic()) wave += float_4::load(inputs[WAVE_INPUT].getVoltages(c)) / 10.f * 3.f; + else + wave += inputs[WAVE_INPUT].getVoltage() / 10.f * 3.f; wave = clamp(wave, 0.f, 3.f); // Settings diff --git a/src/Merge.cpp b/src/Merge.cpp index 25ec173..a8ba7d1 100644 --- a/src/Merge.cpp +++ b/src/Merge.cpp @@ -42,7 +42,8 @@ struct Merge : Module { outputs[POLY_OUTPUT].setVoltage(v, c); } - outputs[POLY_OUTPUT].setChannels((channels >= 0) ? channels : (lastChannel + 1)); + // In order to allow 0 channels, modify channels directly instead of using `setChannels()` + outputs[POLY_OUTPUT].channels = (channels >= 0) ? channels : (lastChannel + 1); // Set channel lights infrequently if (lightDivider.process()) { diff --git a/src/Scope.cpp b/src/Scope.cpp index f34e860..f43d189 100644 --- a/src/Scope.cpp +++ b/src/Scope.cpp @@ -85,13 +85,13 @@ struct Scope : Module { int frameCount = (int) std::ceil(deltaTime * args.sampleRate); // Set channels - int channelsX = inputs[X_INPUT].isConnected() ? inputs[X_INPUT].getChannels() : 0; + int channelsX = inputs[X_INPUT].getChannels(); if (channelsX != this->channelsX) { std::memset(bufferX, 0, sizeof(bufferX)); this->channelsX = channelsX; } - int channelsY = inputs[Y_INPUT].isConnected() ? inputs[Y_INPUT].getChannels() : 0; + int channelsY = inputs[Y_INPUT].getChannels(); if (channelsY != this->channelsY) { std::memset(bufferY, 0, sizeof(bufferY)); this->channelsY = channelsY; diff --git a/src/Split.cpp b/src/Split.cpp index 88352ab..3d22c66 100644 --- a/src/Split.cpp +++ b/src/Split.cpp @@ -28,7 +28,7 @@ struct Split : Module { void process(const ProcessArgs &args) override { for (int c = 0; c < 16; c++) { float v = inputs[POLY_INPUT].getVoltage(c); - // To allow users to debug buggy modules, don't assume that undefined channels are 0V. + // To allow users to debug buggy modules, don't assume that undefined channel voltages are 0V. outputs[MONO_OUTPUTS + c].setVoltage(v); } diff --git a/src/VCA.cpp b/src/VCA.cpp index 8c37f10..5ea6dd9 100644 --- a/src/VCA.cpp +++ b/src/VCA.cpp @@ -29,9 +29,6 @@ struct VCA : Module { } void processChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) { - if (!in.isConnected() || !out.isConnected()) - return; - // Get input int channels = in.getChannels(); simd::float_4 v[4]; @@ -47,17 +44,17 @@ struct VCA : Module { // Apply linear CV gain if (lin.isConnected()) { - if (lin.getChannels() == 1) { - float cv = lin.getVoltage() / 10.f; - cv = clamp(cv, 0.f, 1.f); + if (lin.isPolyphonic()) { for (int c = 0; c < channels; c += 4) { + simd::float_4 cv = simd::float_4::load(lin.getVoltages(c)) / 10.f; + cv = clamp(cv, 0.f, 1.f); v[c / 4] *= cv; } } else { + float cv = lin.getVoltage() / 10.f; + cv = clamp(cv, 0.f, 1.f); for (int c = 0; c < channels; c += 4) { - simd::float_4 cv = simd::float_4::load(lin.getVoltages(c)) / 10.f; - cv = clamp(cv, 0.f, 1.f); v[c / 4] *= cv; } } @@ -66,19 +63,19 @@ struct VCA : Module { // Apply exponential CV gain const float expBase = 50.f; if (exp.isConnected()) { - if (exp.getChannels() == 1) { - float cv = exp.getVoltage() / 10.f; - cv = clamp(cv, 0.f, 1.f); - cv = rescale(std::pow(expBase, cv), 1.f, expBase, 0.f, 1.f); + if (exp.isPolyphonic()) { for (int c = 0; c < channels; c += 4) { + simd::float_4 cv = simd::float_4::load(exp.getVoltages(c)) / 10.f; + cv = clamp(cv, 0.f, 1.f); + cv = rescale(pow(expBase, cv), 1.f, expBase, 0.f, 1.f); v[c / 4] *= cv; } } else { + float cv = exp.getVoltage() / 10.f; + cv = clamp(cv, 0.f, 1.f); + cv = rescale(std::pow(expBase, cv), 1.f, expBase, 0.f, 1.f); for (int c = 0; c < channels; c += 4) { - simd::float_4 cv = simd::float_4::load(exp.getVoltages(c)) / 10.f; - cv = clamp(cv, 0.f, 1.f); - cv = rescale(pow(expBase, cv), 1.f, expBase, 0.f, 1.f); v[c / 4] *= cv; } } diff --git a/src/VCF.cpp b/src/VCF.cpp index fc3c903..5109284 100644 --- a/src/VCF.cpp +++ b/src/VCF.cpp @@ -128,12 +128,10 @@ struct VCF : Module { // Drive gain float_4 drive = driveParam; - if (inputs[DRIVE_INPUT].isConnected()) { - if (inputs[DRIVE_INPUT].isMonophonic()) - drive += inputs[DRIVE_INPUT].getVoltage() / 10.f; - else - drive += float_4::load(inputs[DRIVE_INPUT].getVoltages(c)) / 10.f; - } + if (inputs[DRIVE_INPUT].isPolyphonic()) + drive += float_4::load(inputs[DRIVE_INPUT].getVoltages(c)) / 10.f; + else + drive += inputs[DRIVE_INPUT].getVoltage() / 10.f; drive = clamp(drive, 0.f, 1.f); float_4 gain = simd::pow(1.f + drive, 5); input *= gain; @@ -143,23 +141,19 @@ struct VCF : Module { // Set resonance float_4 resonance = resParam; - if (inputs[RES_INPUT].isConnected()) { - if (inputs[RES_INPUT].isMonophonic()) - resonance += inputs[RES_INPUT].getVoltage() / 10.f; - else - resonance += float_4::load(inputs[RES_INPUT].getVoltages(c)) / 10.f; - } + if (inputs[RES_INPUT].isPolyphonic()) + resonance += float_4::load(inputs[RES_INPUT].getVoltages(c)) / 10.f; + else + resonance += inputs[RES_INPUT].getVoltage() / 10.f; resonance = clamp(resonance, 0.f, 1.f); filter->resonance = simd::pow(resonance, 2) * 10.f; // Get pitch float_4 pitch = 0.f; - if (inputs[FREQ_INPUT].isConnected()) { - if (inputs[FREQ_INPUT].isMonophonic()) - pitch += inputs[FREQ_INPUT].getVoltage() * freqCvParam; - else - pitch += float_4::load(inputs[FREQ_INPUT].getVoltages(c)) * freqCvParam; - } + if (inputs[FREQ_INPUT].isPolyphonic()) + pitch += float_4::load(inputs[FREQ_INPUT].getVoltages(c)) * freqCvParam; + else + pitch += inputs[FREQ_INPUT].getVoltage() * freqCvParam; pitch += freqParam; pitch += fineParam; // Set cutoff diff --git a/src/Viz.cpp b/src/Viz.cpp index 0d459c0..21f6935 100644 --- a/src/Viz.cpp +++ b/src/Viz.cpp @@ -17,7 +17,7 @@ struct Viz : Module { NUM_LIGHTS }; - int lastChannels = 0; + int lastChannel = 0; dsp::ClockDivider lightDivider; Viz() { @@ -27,7 +27,7 @@ struct Viz : Module { void process(const ProcessArgs &args) override { if (lightDivider.process()) { - lastChannels = inputs[POLY_INPUT].getChannels(); + lastChannel = inputs[POLY_INPUT].getChannels(); float deltaTime = args.sampleTime * lightDivider.getDivision(); for (int c = 0; c < 16; c++) { @@ -58,7 +58,7 @@ struct VizDisplay : Widget { nvgFontSize(args.vg, 11); nvgTextLetterSpacing(args.vg, 0.0); nvgTextAlign(args.vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); - if (module && c < module->lastChannels) + if (module && c < module->lastChannel) nvgFillColor(args.vg, nvgRGB(255, 255, 255)); else nvgFillColor(args.vg, nvgRGB(99, 99, 99));