* try to convert to idomatic Rack code * tightened up Percall/Hexmix polyphony logictags/v1.1.0^2
@@ -76,29 +76,13 @@ struct ABC : Module { | |||||
float mult_C = exponentialBipolar80Pade_5_4(params[levelC].getValue()); | float mult_C = exponentialBipolar80Pade_5_4(params[levelC].getValue()); | ||||
if (inputs[inputA].isConnected()) { | if (inputs[inputA].isConnected()) { | ||||
// if monophonic, broadcast to number of active engines | |||||
if (channelsA == 1) { | |||||
for (int c = 0; c < activeEngines; c += 4) | |||||
inA[c / 4] = float_4(inputs[inputA].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < channelsA; c += 4) | |||||
inA[c / 4] = inputs[inputA].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < activeEngines; c += 4) | |||||
inA[c / 4] = inputs[inputA].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[inputB].isConnected()) { | if (inputs[inputB].isConnected()) { | ||||
// if monophonic, broadcast to number of active engines | |||||
if (channelsB == 1) { | |||||
for (int c = 0; c < activeEngines; c += 4) | |||||
inB[c / 4] = float_4(inputs[inputB].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < channelsB; c += 4) | |||||
inB[c / 4] = inputs[inputB].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < activeEngines; c += 4) | for (int c = 0; c < activeEngines; c += 4) | ||||
inB[c / 4] *= mult_B; | |||||
inB[c / 4] = inputs[inputB].getPolyVoltageSimd<float_4>(c) * mult_B; | |||||
} | } | ||||
else { | else { | ||||
for (int c = 0; c < activeEngines; c += 4) | for (int c = 0; c < activeEngines; c += 4) | ||||
@@ -106,18 +90,8 @@ struct ABC : Module { | |||||
} | } | ||||
if (inputs[inputC].isConnected()) { | if (inputs[inputC].isConnected()) { | ||||
// if monophonic, broadcast to number of active engines | |||||
if (channelsC == 1) { | |||||
for (int c = 0; c < activeEngines; c += 4) | |||||
inC[c / 4] = float_4(inputs[inputC].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < channelsC; c += 4) | |||||
inC[c / 4] = inputs[inputC].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < activeEngines; c += 4) | for (int c = 0; c < activeEngines; c += 4) | ||||
inC[c / 4] *= mult_C; | |||||
inC[c / 4] = inputs[inputC].getPolyVoltageSimd<float_4>(c) * mult_C; | |||||
} | } | ||||
else { | else { | ||||
for (int c = 0; c < activeEngines; c += 4) | for (int c = 0; c < activeEngines; c += 4) | ||||
@@ -150,7 +124,7 @@ struct ABC : Module { | |||||
if (outputs[OUT1_OUTPUT].isConnected()) { | if (outputs[OUT1_OUTPUT].isConnected()) { | ||||
outputs[OUT1_OUTPUT].setChannels(activeEngines1); | outputs[OUT1_OUTPUT].setChannels(activeEngines1); | ||||
for (int c = 0; c < activeEngines1; c += 4) | for (int c = 0; c < activeEngines1; c += 4) | ||||
out1[c / 4].store(outputs[OUT1_OUTPUT].getVoltages(c)); | |||||
outputs[OUT1_OUTPUT].setVoltageSimd(out1[c / 4], c); | |||||
} | } | ||||
else if (outputs[OUT2_OUTPUT].isConnected()) { | else if (outputs[OUT2_OUTPUT].isConnected()) { | ||||
@@ -161,7 +135,7 @@ struct ABC : Module { | |||||
outputs[OUT2_OUTPUT].setChannels(activeEngines2); | outputs[OUT2_OUTPUT].setChannels(activeEngines2); | ||||
for (int c = 0; c < activeEngines2; c += 4) | for (int c = 0; c < activeEngines2; c += 4) | ||||
out2[c / 4].store(outputs[OUT2_OUTPUT].getVoltages(c)); | |||||
outputs[OUT2_OUTPUT].setVoltageSimd(out2[c / 4], c); | |||||
} | } | ||||
// Lights | // Lights | ||||
@@ -61,10 +61,10 @@ struct DualAtenuverter : Module { | |||||
outputs[OUT2_OUTPUT].setChannels(channels2); | outputs[OUT2_OUTPUT].setChannels(channels2); | ||||
for (int c = 0; c < channels1; c += 4) { | for (int c = 0; c < channels1; c += 4) { | ||||
out1[c / 4].store(outputs[OUT1_OUTPUT].getVoltages(c)); | |||||
outputs[OUT1_OUTPUT].setVoltageSimd(out1[c / 4], c); | |||||
} | } | ||||
for (int c = 0; c < channels2; c += 4) { | for (int c = 0; c < channels2; c += 4) { | ||||
out2[c / 4].store(outputs[OUT2_OUTPUT].getVoltages(c)); | |||||
outputs[OUT2_OUTPUT].setVoltageSimd(out2[c / 4], c); | |||||
} | } | ||||
float light1 = outputs[OUT1_OUTPUT].getVoltageSum() / channels1; | float light1 = outputs[OUT1_OUTPUT].getVoltageSum() / channels1; | ||||
@@ -63,8 +63,6 @@ struct EvenVCO : Module { | |||||
int channels_pitch1 = inputs[PITCH1_INPUT].getChannels(); | int channels_pitch1 = inputs[PITCH1_INPUT].getChannels(); | ||||
int channels_pitch2 = inputs[PITCH2_INPUT].getChannels(); | int channels_pitch2 = inputs[PITCH2_INPUT].getChannels(); | ||||
int channels_fm = inputs[FM_INPUT].getChannels(); | |||||
int channels_pwm = inputs[PWM_INPUT].getChannels(); | |||||
int channels = 1; | int channels = 1; | ||||
channels = std::max(channels, channels_pitch1); | channels = std::max(channels, channels_pitch1); | ||||
@@ -78,39 +76,18 @@ struct EvenVCO : Module { | |||||
pitch[c / 4] = float_4(pitch_0); | pitch[c / 4] = float_4(pitch_0); | ||||
if (inputs[PITCH1_INPUT].isConnected()) { | if (inputs[PITCH1_INPUT].isConnected()) { | ||||
// if pitch_1 monophonic, broadcast | |||||
if (channels_pitch1 == 1) { | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += float_4(inputs[PITCH1_INPUT].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels, channels_pitch1); c += 4) | |||||
pitch[c / 4] += inputs[PITCH1_INPUT].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += inputs[PITCH1_INPUT].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[PITCH2_INPUT].isConnected()) { | if (inputs[PITCH2_INPUT].isConnected()) { | ||||
// if pitch_2 monophonic, broadcast | |||||
if (channels_pitch2 == 1) { | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += float_4(inputs[PITCH2_INPUT].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels, channels_pitch2); c += 4) | |||||
pitch[c / 4] += inputs[PITCH2_INPUT].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += inputs[PITCH2_INPUT].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[FM_INPUT].isConnected()) { | |||||
// if FM is monophonic, broadcast | |||||
if (channels_fm == 1) { | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += float_4(inputs[FM_INPUT].getVoltage() / 4.f); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels, channels_fm); c += 4) | |||||
pitch[c / 4] += inputs[FM_INPUT].getVoltageSimd<float_4>(c) / 4.f; | |||||
} | |||||
if (inputs[FM_INPUT].isConnected()) { | |||||
for (int c = 0; c < channels; c += 4) | |||||
pitch[c / 4] += inputs[FM_INPUT].getPolyVoltageSimd<float_4>(c) / 4.f; | |||||
} | } | ||||
float_4 freq[4]; | float_4 freq[4]; | ||||
@@ -126,14 +103,8 @@ struct EvenVCO : Module { | |||||
pw[c / 4] = float_4(pw_0); | pw[c / 4] = float_4(pw_0); | ||||
if (inputs[PWM_INPUT].isConnected()) { | if (inputs[PWM_INPUT].isConnected()) { | ||||
if (channels_pwm == 1) { | |||||
for (int c = 0; c < channels; c += 4) | |||||
pw[c / 4] += float_4(inputs[PWM_INPUT].getVoltage() / 5.f); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels, channels_pwm); c += 4) | |||||
pw[c / 4] += inputs[PWM_INPUT].getVoltageSimd<float_4>(c) / 5.f; | |||||
} | |||||
for (int c = 0; c < channels; c += 4) | |||||
pw[c / 4] += inputs[PWM_INPUT].getPolyVoltageSimd<float_4>(c) / 5.f; | |||||
} | } | ||||
const float_4 minPw_4 = float_4(0.05f); | const float_4 minPw_4 = float_4(0.05f); | ||||
@@ -234,12 +205,11 @@ struct EvenVCO : Module { | |||||
square[c / 4] *= 5.f; | square[c / 4] *= 5.f; | ||||
// Set outputs | // Set outputs | ||||
triOut[c / 4].store(outputs[TRI_OUTPUT].getVoltages(c)); | |||||
sine[c / 4].store(outputs[SINE_OUTPUT].getVoltages(c)); | |||||
even[c / 4].store(outputs[EVEN_OUTPUT].getVoltages(c)); | |||||
saw[c / 4].store(outputs[SAW_OUTPUT].getVoltages(c)); | |||||
square[c / 4].store(outputs[SQUARE_OUTPUT].getVoltages(c)); | |||||
outputs[TRI_OUTPUT].setVoltageSimd(triOut[c / 4], c); | |||||
outputs[SINE_OUTPUT].setVoltageSimd(sine[c / 4], c); | |||||
outputs[EVEN_OUTPUT].setVoltageSimd(even[c / 4], c); | |||||
outputs[SAW_OUTPUT].setVoltageSimd(saw[c / 4], c); | |||||
outputs[SQUARE_OUTPUT].setVoltageSimd(square[c / 4], c); | |||||
} | } | ||||
} | } | ||||
}; | }; | ||||
@@ -1,6 +1,7 @@ | |||||
#include "plugin.hpp" | #include "plugin.hpp" | ||||
#include "Common.hpp" | #include "Common.hpp" | ||||
using simd::float_4; | |||||
static float gainFunction(float x, float shape) { | static float gainFunction(float x, float shape) { | ||||
float lin = x; | float lin = x; | ||||
@@ -49,7 +50,7 @@ struct HexmixVCA : Module { | |||||
} | } | ||||
void process(const ProcessArgs& args) override { | void process(const ProcessArgs& args) override { | ||||
simd::float_4 mix[4] = {}; | |||||
float_4 mix[4] = {0.f}; | |||||
int maxChannels = 1; | int maxChannels = 1; | ||||
// only calculate gains/shapes every 16 samples | // only calculate gains/shapes every 16 samples | ||||
@@ -61,29 +62,33 @@ struct HexmixVCA : Module { | |||||
} | } | ||||
for (int row = 0; row < numRows; ++row) { | for (int row = 0; row < numRows; ++row) { | ||||
bool finalRow = (row == numRows - 1); | |||||
int channels = 1; | int channels = 1; | ||||
simd::float_4 in[4] = {}; | |||||
float_4 in[4] = {0.f}; | |||||
bool inputIsConnected = inputs[IN_INPUT + row].isConnected(); | bool inputIsConnected = inputs[IN_INPUT + row].isConnected(); | ||||
if (inputIsConnected) { | if (inputIsConnected) { | ||||
channels = inputs[row].getChannels(); | channels = inputs[row].getChannels(); | ||||
maxChannels = std::max(maxChannels, channels); | |||||
// if we're in "mixer" mode, an input only counts towards the main output polyphony count if it's | |||||
// not taken out of the mix (i.e. patched in). the final row should count towards polyphony calc. | |||||
if (finalRowIsMix && (finalRow || !outputs[OUT_OUTPUT + row].isConnected())) { | |||||
maxChannels = std::max(maxChannels, channels); | |||||
} | |||||
float cvGain = clamp(inputs[CV_INPUT + row].getNormalVoltage(10.f) / 10.f, 0.f, 1.f); | float cvGain = clamp(inputs[CV_INPUT + row].getNormalVoltage(10.f) / 10.f, 0.f, 1.f); | ||||
float gain = gainFunction(cvGain, shapes[row]) * outputLevels[row]; | float gain = gainFunction(cvGain, shapes[row]) * outputLevels[row]; | ||||
for (int c = 0; c < channels; c += 4) { | for (int c = 0; c < channels; c += 4) { | ||||
in[c / 4] = simd::float_4::load(inputs[row].getVoltages(c)) * gain; | |||||
in[c / 4] = inputs[row].getVoltageSimd<float_4>(c) * gain; | |||||
} | } | ||||
} | } | ||||
bool finalRow = (row == numRows - 1); | |||||
if (!finalRow) { | if (!finalRow) { | ||||
if (outputs[OUT_OUTPUT + row].isConnected()) { | if (outputs[OUT_OUTPUT + row].isConnected()) { | ||||
// if output is connected, we don't add to mix | // if output is connected, we don't add to mix | ||||
outputs[OUT_OUTPUT + row].setChannels(channels); | outputs[OUT_OUTPUT + row].setChannels(channels); | ||||
for (int c = 0; c < channels; c += 4) { | for (int c = 0; c < channels; c += 4) { | ||||
in[c / 4].store(outputs[OUT_OUTPUT + row].getVoltages(c)); | |||||
outputs[OUT_OUTPUT + row].setVoltageSimd(in[c / 4], c); | |||||
} | } | ||||
} | } | ||||
else if (finalRowIsMix) { | else if (finalRowIsMix) { | ||||
@@ -105,14 +110,14 @@ struct HexmixVCA : Module { | |||||
} | } | ||||
for (int c = 0; c < maxChannels; c += 4) { | for (int c = 0; c < maxChannels; c += 4) { | ||||
mix[c / 4].store(outputs[OUT_OUTPUT + row].getVoltages(c)); | |||||
outputs[OUT_OUTPUT + row].setVoltageSimd(mix[c / 4], c); | |||||
} | } | ||||
} | } | ||||
else { | else { | ||||
// same as other rows | // same as other rows | ||||
outputs[OUT_OUTPUT + row].setChannels(channels); | outputs[OUT_OUTPUT + row].setChannels(channels); | ||||
for (int c = 0; c < channels; c += 4) { | for (int c = 0; c < channels; c += 4) { | ||||
in[c / 4].store(outputs[OUT_OUTPUT + row].getVoltages(c)); | |||||
outputs[OUT_OUTPUT + row].setVoltageSimd(in[c / 4], c); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -83,9 +83,9 @@ struct Mixer : Module { | |||||
outputs[OUT2_OUTPUT].setChannels(out_channels); | outputs[OUT2_OUTPUT].setChannels(out_channels); | ||||
for (int c = 0; c < out_channels; c += 4) { | for (int c = 0; c < out_channels; c += 4) { | ||||
out[c / 4].store(outputs[OUT1_OUTPUT].getVoltages(c)); | |||||
outputs[OUT1_OUTPUT].setVoltageSimd(out[c / 4], c); | |||||
out[c / 4] *= -1.f; | out[c / 4] *= -1.f; | ||||
out[c / 4].store(outputs[OUT2_OUTPUT].getVoltages(c)); | |||||
outputs[OUT2_OUTPUT].setVoltageSimd(out[c / 4], c); | |||||
} | } | ||||
if (out_channels == 1) { | if (out_channels == 1) { | ||||
@@ -1,6 +1,7 @@ | |||||
#include "plugin.hpp" | #include "plugin.hpp" | ||||
#include "Common.hpp" | #include "Common.hpp" | ||||
using simd::float_4; | |||||
struct Percall : Module { | struct Percall : Module { | ||||
enum ParamIds { | enum ParamIds { | ||||
@@ -28,7 +29,7 @@ struct Percall : Module { | |||||
ADEnvelope envs[4]; | ADEnvelope envs[4]; | ||||
float gains[4] = {}; | |||||
float gains[4] = {0.f}; | |||||
float strength = 1.0f; | float strength = 1.0f; | ||||
dsp::SchmittTrigger trigger[4]; | dsp::SchmittTrigger trigger[4]; | ||||
@@ -76,7 +77,7 @@ struct Percall : Module { | |||||
} | } | ||||
} | } | ||||
simd::float_4 mix[4] = {}; | |||||
float_4 mix[4] = {0.f}; | |||||
int maxPolyphonyChannels = 1; | int maxPolyphonyChannels = 1; | ||||
// Mixer channels | // Mixer channels | ||||
@@ -95,19 +96,24 @@ struct Percall : Module { | |||||
envs[i].process(args.sampleTime); | envs[i].process(args.sampleTime); | ||||
int polyphonyChannels = 1; | int polyphonyChannels = 1; | ||||
simd::float_4 in[4] = {}; | |||||
float_4 in[4] = {}; | |||||
bool inputIsConnected = inputs[CH_INPUTS + i].isConnected(); | bool inputIsConnected = inputs[CH_INPUTS + i].isConnected(); | ||||
bool inputIsNormed = !inputIsConnected && (i % 2) && inputs[CH_INPUTS + i - 1].isConnected(); | bool inputIsNormed = !inputIsConnected && (i % 2) && inputs[CH_INPUTS + i - 1].isConnected(); | ||||
if ((inputIsConnected || inputIsNormed)) { | if ((inputIsConnected || inputIsNormed)) { | ||||
int channel_to_read_from = inputIsNormed ? CH_INPUTS + i - 1 : CH_INPUTS + i; | |||||
polyphonyChannels = inputs[channel_to_read_from].getChannels(); | |||||
maxPolyphonyChannels = std::max(maxPolyphonyChannels, polyphonyChannels); | |||||
int channelToReadFrom = inputIsNormed ? CH_INPUTS + i - 1 : CH_INPUTS + i; | |||||
polyphonyChannels = inputs[channelToReadFrom].getChannels(); | |||||
// an input only counts towards the main output polyphony count if it's not taken out of the mix | |||||
// (i.e. an output is patched in). the final input should always count towards polyphony count. | |||||
if (i == CH_INPUTS_LAST || !outputs[CH_OUTPUTS + i].isConnected()) { | |||||
maxPolyphonyChannels = std::max(maxPolyphonyChannels, polyphonyChannels); | |||||
} | |||||
// only process input audio if envelope is active | // only process input audio if envelope is active | ||||
if (envs[i].stage != ADEnvelope::STAGE_OFF) { | if (envs[i].stage != ADEnvelope::STAGE_OFF) { | ||||
float gain = gains[i] * envs[i].env; | float gain = gains[i] * envs[i].env; | ||||
for (int c = 0; c < polyphonyChannels; c += 4) { | for (int c = 0; c < polyphonyChannels; c += 4) { | ||||
in[c / 4] = simd::float_4::load(inputs[channel_to_read_from].getVoltages(c)) * gain; | |||||
in[c / 4] = inputs[channelToReadFrom].getVoltageSimd<float_4>(c) * gain; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -117,7 +123,7 @@ struct Percall : Module { | |||||
if (outputs[CH_OUTPUTS + i].isConnected()) { | if (outputs[CH_OUTPUTS + i].isConnected()) { | ||||
outputs[CH_OUTPUTS + i].setChannels(polyphonyChannels); | outputs[CH_OUTPUTS + i].setChannels(polyphonyChannels); | ||||
for (int c = 0; c < polyphonyChannels; c += 4) { | for (int c = 0; c < polyphonyChannels; c += 4) { | ||||
in[c / 4].store(outputs[CH_OUTPUTS + i].getVoltages(c)); | |||||
outputs[CH_OUTPUTS + i].setVoltageSimd(in[c / 4], c); | |||||
} | } | ||||
} | } | ||||
else { | else { | ||||
@@ -138,7 +144,7 @@ struct Percall : Module { | |||||
} | } | ||||
for (int c = 0; c < maxPolyphonyChannels; c += 4) { | for (int c = 0; c < maxPolyphonyChannels; c += 4) { | ||||
mix[c / 4].store(outputs[CH_OUTPUTS + i].getVoltages(c)); | |||||
outputs[CH_OUTPUTS + i].setVoltageSimd(mix[c / 4], c); | |||||
} | } | ||||
} | } | ||||
@@ -135,11 +135,11 @@ struct Rampage : Module { | |||||
// loop over two parts of Rampage: | // loop over two parts of Rampage: | ||||
for (int part = 0; part < 2; part++) { | for (int part = 0; part < 2; part++) { | ||||
float_4 in[4]; | |||||
float_4 in_trig[4]; | |||||
float_4 riseCV[4]; | |||||
float_4 fallCV[4]; | |||||
float_4 cycle[4]; | |||||
float_4 in[4] = {0.f}; | |||||
float_4 in_trig[4] = {0.f}; | |||||
float_4 riseCV[4] = {0.f}; | |||||
float_4 fallCV[4] = {0.f}; | |||||
float_4 cycle[4] = {0.f}; | |||||
// get parameters: | // get parameters: | ||||
float shape = params[SHAPE_A_PARAM + part].getValue(); | float shape = params[SHAPE_A_PARAM + part].getValue(); | ||||
@@ -169,47 +169,20 @@ struct Rampage : Module { | |||||
} | } | ||||
// read inputs: | // read inputs: | ||||
if (inputs[IN_A_INPUT + part].isConnected()) { | |||||
// if IN_<A,B>_INPUT is monophonic, broadcast to the active number of engines (channels[part]) | |||||
if (inputs[IN_A_INPUT + part].getChannels() == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in[c / 4] = float_4(inputs[IN_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in[c / 4] = inputs[IN_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
} | |||||
else { | |||||
std::memset(in, 0, sizeof(in)); | |||||
if (inputs[IN_A_INPUT + part].isConnected()) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in[c / 4] = inputs[IN_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[TRIGG_A_INPUT + part].isConnected()) { | if (inputs[TRIGG_A_INPUT + part].isConnected()) { | ||||
// if TRIGG_<A,B>_INPUT is monophonic, broadcast to the active number of engines (channels[part]) | |||||
if (inputs[TRIGG_A_INPUT + part].getChannels() == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in_trig[c / 4] += float_4(inputs[TRIGG_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in_trig[c / 4] += inputs[TRIGG_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
in_trig[c / 4] += inputs[TRIGG_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[EXP_CV_A_INPUT + part].isConnected()) { | if (inputs[EXP_CV_A_INPUT + part].isConnected()) { | ||||
float_4 expCV[4]; | |||||
int expCVChannels = inputs[EXP_CV_A_INPUT + part].getChannels(); | |||||
// if EXP_CV_<A,B>_INPUT is monophonic, broadcast to the active number of engines (channels[part]) | |||||
if (expCVChannels == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
expCV[c / 4] = float_4(inputs[EXP_CV_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
// otherwise read in the polyphonic expCV data, either to the number of active engines (channels[part]) | |||||
// or the number of channels of expCV, whichever is smaller | |||||
for (int c = 0; c < std::min(channels[part], expCVChannels); c += 4) | |||||
expCV[c / 4] = inputs[EXP_CV_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
float_4 expCV[4]; | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
expCV[c / 4] = inputs[EXP_CV_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
for (int c = 0; c < channels[part]; c += 4) { | for (int c = 0; c < channels[part]; c += 4) { | ||||
riseCV[c / 4] -= expCV[c / 4]; | riseCV[c / 4] -= expCV[c / 4]; | ||||
@@ -217,44 +190,17 @@ struct Rampage : Module { | |||||
} | } | ||||
} | } | ||||
const int riseCVChannels = inputs[RISE_CV_A_INPUT + part].getChannels(); | |||||
// if EXP_CV_<A,B>_INPUT is monophonic, broadcast to the active number of engines (channels[part]) | |||||
if (riseCVChannels == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
riseCV[c / 4] += float_4(inputs[RISE_CV_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
// otherwise read in the polyphonic rise CV data, either to the number of active engines (channels[part]) | |||||
// or the number of channels of expCV, whichever is smaller | |||||
for (int c = 0; c < std::min(channels[part], riseCVChannels); c += 4) | |||||
riseCV[c / 4] += inputs[RISE_CV_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
const int fallCVChannels = inputs[FALL_CV_A_INPUT + part].getChannels(); | |||||
if (fallCVChannels == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
fallCV[c / 4] += float_4(inputs[FALL_CV_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels[part], fallCVChannels); c += 4) | |||||
fallCV[c / 4] += inputs[FALL_CV_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
const int cycleChannels = inputs[CYCLE_A_INPUT + part].getChannels(); | |||||
if (cycleChannels == 1) { | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
cycle[c / 4] += float_4(inputs[CYCLE_A_INPUT + part].getVoltage()); | |||||
} | |||||
else { | |||||
for (int c = 0; c < std::min(channels[part], cycleChannels); c += 4) | |||||
cycle[c / 4] += inputs[CYCLE_A_INPUT + part].getVoltageSimd<float_4>(c); | |||||
} | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
riseCV[c / 4] += inputs[RISE_CV_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
fallCV[c / 4] += inputs[FALL_CV_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
for (int c = 0; c < channels[part]; c += 4) | |||||
cycle[c / 4] += inputs[CYCLE_A_INPUT + part].getPolyVoltageSimd<float_4>(c); | |||||
// start processing: | // start processing: | ||||
for (int c = 0; c < channels[part]; c += 4) { | for (int c = 0; c < channels[part]; c += 4) { | ||||
// process SchmittTriggers | // process SchmittTriggers | ||||
float_4 trig_mask = trigger_4[part][c / 4].process(in_trig[c / 4] / 2.0); | float_4 trig_mask = trigger_4[part][c / 4].process(in_trig[c / 4] / 2.0); | ||||
gate[part][c / 4] = ifelse(trig_mask, float_4::mask(), gate[part][c / 4]); | gate[part][c / 4] = ifelse(trig_mask, float_4::mask(), gate[part][c / 4]); | ||||
in[c / 4] = ifelse(gate[part][c / 4], float_4(10.0f), in[c / 4]); | in[c / 4] = ifelse(gate[part][c / 4], float_4(10.0f), in[c / 4]); | ||||
@@ -295,9 +241,9 @@ struct Rampage : Module { | |||||
out[part][c / 4].store(outputs[OUT_A_OUTPUT + part].getVoltages(c)); | out[part][c / 4].store(outputs[OUT_A_OUTPUT + part].getVoltages(c)); | ||||
out_rising.store(outputs[RISING_A_OUTPUT + part].getVoltages(c)); | |||||
out_falling.store(outputs[FALLING_A_OUTPUT + part].getVoltages(c)); | |||||
out_EOC.store(outputs[EOC_A_OUTPUT + part].getVoltages(c)); | |||||
outputs[RISING_A_OUTPUT + part].setVoltageSimd(out_rising, c); | |||||
outputs[FALLING_A_OUTPUT + part].setVoltageSimd(out_falling, c); | |||||
outputs[EOC_A_OUTPUT + part].setVoltageSimd(out_EOC, c); | |||||
} // for(int c, ...) | } // for(int c, ...) | ||||
@@ -57,20 +57,10 @@ struct SlewLimiter : Module { | |||||
in[c / 4] = inputs[IN_INPUT].getVoltageSimd<float_4>(c); | in[c / 4] = inputs[IN_INPUT].getVoltageSimd<float_4>(c); | ||||
if (inputs[RISE_INPUT].isConnected()) { | if (inputs[RISE_INPUT].isConnected()) { | ||||
if (inputs[RISE_INPUT].getChannels() == 1) { | |||||
riseCV[c / 4] = float_4(inputs[RISE_INPUT].getVoltage()); | |||||
} | |||||
else { | |||||
riseCV[c / 4] = inputs[RISE_INPUT].getVoltageSimd<float_4>(c); | |||||
} | |||||
riseCV[c / 4] = inputs[RISE_INPUT].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
if (inputs[FALL_INPUT].isConnected()) { | if (inputs[FALL_INPUT].isConnected()) { | ||||
if (inputs[FALL_INPUT].getChannels() == 1) { | |||||
fallCV[c / 4] = float_4(inputs[FALL_INPUT].getVoltage()); | |||||
} | |||||
else { | |||||
fallCV[c / 4] = inputs[FALL_INPUT].getVoltageSimd<float_4>(c); | |||||
} | |||||
fallCV[c / 4] = inputs[FALL_INPUT].getPolyVoltageSimd<float_4>(c); | |||||
} | } | ||||
riseCV[c / 4] += param_rise; | riseCV[c / 4] += param_rise; | ||||