diff --git a/src/VCA.cpp b/src/VCA.cpp index 18b2e15..ae6b0ec 100644 --- a/src/VCA.cpp +++ b/src/VCA.cpp @@ -28,44 +28,72 @@ struct VCA : Module { params[LEVEL2_PARAM].config(0.0, 1.0, 1.0, "Ch 2 level", "%", 0, 100); } - void stepChannel(InputIds in, ParamIds level, InputIds lin, InputIds exp, OutputIds out) { + void processChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) { + if (!in.isConnected() || !out.isConnected()) + return; + // Get input - int channels = inputs[in].getChannels(); - float v[16]; - inputs[in].getVoltages(v); + int channels = in.getChannels(); + simd::f32_4 v[4]; + for (int c = 0; c < channels; c += 4) { + v[c / 4] = simd::f32_4::load(&in.voltages[c]); + } // Apply knob gain - float gain = params[level].getValue(); - for (int c = 0; c < channels; c++) { - v[c] *= gain; + float gain = level.getValue(); + for (int c = 0; c < channels; c += 4) { + v[c / 4] *= gain; } // Apply linear CV gain - if (inputs[lin].isConnected()) { - for (int c = 0; c < channels; c++) { - float cv = clamp(inputs[lin].getPolyVoltage(c) / 10.f, 0.f, 1.f); - v[c] *= cv; + if (lin.isConnected()) { + if (lin.getChannels() == 1) { + float cv = lin.getVoltage() / 10.f; + cv = clamp(cv, 0.f, 1.f); + for (int c = 0; c < channels; c += 4) { + v[c / 4] *= cv; + } + } + else { + for (int c = 0; c < channels; c += 4) { + simd::f32_4 cv = simd::f32_4::load(&lin.voltages[c]) / 10.f; + cv = clamp(cv, 0.f, 1.f); + v[c / 4] *= cv; + } } } // Apply exponential CV gain const float expBase = 50.f; - if (inputs[exp].isConnected()) { - for (int c = 0; c < channels; c++) { - float cv = clamp(inputs[exp].getPolyVoltage(c) / 10.f, 0.f, 1.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); - v[c] *= cv; + for (int c = 0; c < channels; c += 4) { + v[c / 4] *= cv; + } + } + else { + for (int c = 0; c < channels; c += 4) { + simd::f32_4 cv = simd::f32_4::load(&exp.voltages[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; + } } } // Set output - outputs[out].setChannels(channels); - outputs[out].setVoltages(v); + out.setChannels(channels); + for (int c = 0; c < channels; c += 4) { + v[c / 4].store(&out.voltages[c]); + } } void process(const ProcessArgs &args) override { - stepChannel(IN1_INPUT, LEVEL1_PARAM, LIN1_INPUT, EXP1_INPUT, OUT1_OUTPUT); - stepChannel(IN2_INPUT, LEVEL2_PARAM, LIN2_INPUT, EXP2_INPUT, OUT2_OUTPUT); + processChannel(inputs[IN1_INPUT], params[LEVEL1_PARAM], inputs[LIN1_INPUT], inputs[EXP1_INPUT], outputs[OUT1_OUTPUT]); + processChannel(inputs[IN2_INPUT], params[LEVEL2_PARAM], inputs[LIN2_INPUT], inputs[EXP2_INPUT], outputs[OUT2_OUTPUT]); } };