Browse Source

Clean up various modules with polyphony and SIMD.

tags/v1.0.1
Andrew Belt 6 years ago
parent
commit
495bef3464
7 changed files with 41 additions and 49 deletions
  1. +9
    -9
      src/LFO.cpp
  2. +2
    -1
      src/Merge.cpp
  3. +2
    -2
      src/Scope.cpp
  4. +1
    -1
      src/Split.cpp
  5. +12
    -15
      src/VCA.cpp
  6. +12
    -18
      src/VCF.cpp
  7. +3
    -3
      src/Viz.cpp

+ 9
- 9
src/LFO.cpp View File

@@ -131,18 +131,18 @@ struct LFO : Module {
// FM1, polyphonic // FM1, polyphonic
pitch += float_4::load(inputs[FM1_INPUT].getVoltages(c)) * fm1Param; pitch += float_4::load(inputs[FM1_INPUT].getVoltages(c)) * fm1Param;
// FM2, polyphonic or monophonic // 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; pitch += float_4::load(inputs[FM2_INPUT].getVoltages(c)) * fm2Param;
else
pitch += inputs[FM2_INPUT].getVoltage() * fm2Param;
oscillator->setPitch(pitch); oscillator->setPitch(pitch);


// Pulse width // Pulse width
float_4 pw = pwParam; 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; pw += float_4::load(inputs[PW_INPUT].getVoltages(c)) / 10.f * pwmParam;
else
pw += inputs[PW_INPUT].getVoltage() / 10.f * pwmParam;
oscillator->setPulseWidth(pw); oscillator->setPulseWidth(pw);


// Settings // Settings
@@ -284,10 +284,10 @@ struct LFO2 : Module {
// Wave // Wave
float_4 wave = waveParam; float_4 wave = waveParam;
inputs[WAVE_INPUT].getVoltage(); 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; 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); wave = clamp(wave, 0.f, 3.f);


// Settings // Settings


+ 2
- 1
src/Merge.cpp View File

@@ -42,7 +42,8 @@ struct Merge : Module {
outputs[POLY_OUTPUT].setVoltage(v, c); 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 // Set channel lights infrequently
if (lightDivider.process()) { if (lightDivider.process()) {


+ 2
- 2
src/Scope.cpp View File

@@ -85,13 +85,13 @@ struct Scope : Module {
int frameCount = (int) std::ceil(deltaTime * args.sampleRate); int frameCount = (int) std::ceil(deltaTime * args.sampleRate);


// Set channels // Set channels
int channelsX = inputs[X_INPUT].isConnected() ? inputs[X_INPUT].getChannels() : 0;
int channelsX = inputs[X_INPUT].getChannels();
if (channelsX != this->channelsX) { if (channelsX != this->channelsX) {
std::memset(bufferX, 0, sizeof(bufferX)); std::memset(bufferX, 0, sizeof(bufferX));
this->channelsX = channelsX; this->channelsX = channelsX;
} }


int channelsY = inputs[Y_INPUT].isConnected() ? inputs[Y_INPUT].getChannels() : 0;
int channelsY = inputs[Y_INPUT].getChannels();
if (channelsY != this->channelsY) { if (channelsY != this->channelsY) {
std::memset(bufferY, 0, sizeof(bufferY)); std::memset(bufferY, 0, sizeof(bufferY));
this->channelsY = channelsY; this->channelsY = channelsY;


+ 1
- 1
src/Split.cpp View File

@@ -28,7 +28,7 @@ struct Split : Module {
void process(const ProcessArgs &args) override { void process(const ProcessArgs &args) override {
for (int c = 0; c < 16; c++) { for (int c = 0; c < 16; c++) {
float v = inputs[POLY_INPUT].getVoltage(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); outputs[MONO_OUTPUTS + c].setVoltage(v);
} }




+ 12
- 15
src/VCA.cpp View File

@@ -29,9 +29,6 @@ struct VCA : Module {
} }


void processChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) { void processChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) {
if (!in.isConnected() || !out.isConnected())
return;

// Get input // Get input
int channels = in.getChannels(); int channels = in.getChannels();
simd::float_4 v[4]; simd::float_4 v[4];
@@ -47,17 +44,17 @@ struct VCA : Module {


// Apply linear CV gain // Apply linear CV gain
if (lin.isConnected()) { 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) { 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; v[c / 4] *= cv;
} }
} }
else { else {
float cv = lin.getVoltage() / 10.f;
cv = clamp(cv, 0.f, 1.f);
for (int c = 0; c < channels; c += 4) { 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; v[c / 4] *= cv;
} }
} }
@@ -66,19 +63,19 @@ struct VCA : Module {
// Apply exponential CV gain // Apply exponential CV gain
const float expBase = 50.f; const float expBase = 50.f;
if (exp.isConnected()) { 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) { 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; v[c / 4] *= cv;
} }
} }
else { 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) { 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; v[c / 4] *= cv;
} }
} }


+ 12
- 18
src/VCF.cpp View File

@@ -128,12 +128,10 @@ struct VCF : Module {


// Drive gain // Drive gain
float_4 drive = driveParam; 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); drive = clamp(drive, 0.f, 1.f);
float_4 gain = simd::pow(1.f + drive, 5); float_4 gain = simd::pow(1.f + drive, 5);
input *= gain; input *= gain;
@@ -143,23 +141,19 @@ struct VCF : Module {


// Set resonance // Set resonance
float_4 resonance = resParam; 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); resonance = clamp(resonance, 0.f, 1.f);
filter->resonance = simd::pow(resonance, 2) * 10.f; filter->resonance = simd::pow(resonance, 2) * 10.f;


// Get pitch // Get pitch
float_4 pitch = 0.f; 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 += freqParam;
pitch += fineParam; pitch += fineParam;
// Set cutoff // Set cutoff


+ 3
- 3
src/Viz.cpp View File

@@ -17,7 +17,7 @@ struct Viz : Module {
NUM_LIGHTS NUM_LIGHTS
}; };


int lastChannels = 0;
int lastChannel = 0;
dsp::ClockDivider lightDivider; dsp::ClockDivider lightDivider;


Viz() { Viz() {
@@ -27,7 +27,7 @@ struct Viz : Module {


void process(const ProcessArgs &args) override { void process(const ProcessArgs &args) override {
if (lightDivider.process()) { if (lightDivider.process()) {
lastChannels = inputs[POLY_INPUT].getChannels();
lastChannel = inputs[POLY_INPUT].getChannels();
float deltaTime = args.sampleTime * lightDivider.getDivision(); float deltaTime = args.sampleTime * lightDivider.getDivision();


for (int c = 0; c < 16; c++) { for (int c = 0; c < 16; c++) {
@@ -58,7 +58,7 @@ struct VizDisplay : Widget {
nvgFontSize(args.vg, 11); nvgFontSize(args.vg, 11);
nvgTextLetterSpacing(args.vg, 0.0); nvgTextLetterSpacing(args.vg, 0.0);
nvgTextAlign(args.vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); 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)); nvgFillColor(args.vg, nvgRGB(255, 255, 255));
else else
nvgFillColor(args.vg, nvgRGB(99, 99, 99)); nvgFillColor(args.vg, nvgRGB(99, 99, 99));


Loading…
Cancel
Save