Browse Source

Optimize VCA-1 with simd library.

tags/v1.0.1
Andrew Belt 6 years ago
parent
commit
0354679cf7
1 changed files with 47 additions and 19 deletions
  1. +47
    -19
      src/VCA.cpp

+ 47
- 19
src/VCA.cpp View File

@@ -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]);
}
};



Loading…
Cancel
Save