Browse Source

Rewrite Sequential Switch algorithm. Replace param/input/output.value with setters/getters.

tags/v1.0.1
Andrew Belt 4 years ago
parent
commit
2db5b769ea
14 changed files with 161 additions and 151 deletions
  1. +1
    -0
      plugin.json
  2. +2
    -2
      src/8vert.cpp
  3. +7
    -7
      src/ADSR.cpp
  4. +6
    -6
      src/Delay.cpp
  5. +15
    -15
      src/LFO.cpp
  6. +3
    -3
      src/Mutes.cpp
  7. +11
    -11
      src/SEQ3.cpp
  8. +12
    -12
      src/Scope.cpp
  9. +52
    -43
      src/SequentialSwitch.cpp
  10. +4
    -4
      src/Unity.cpp
  11. +6
    -6
      src/VCA.cpp
  12. +12
    -12
      src/VCF.cpp
  13. +12
    -12
      src/VCMixer.cpp
  14. +18
    -18
      src/VCO.cpp

+ 1
- 0
plugin.json View File

@@ -6,6 +6,7 @@
"authorEmail": "contact@vcvrack.com",
"pluginUrl": "https://vcvrack.com/Fundamental.html",
"authorUrl": "https://vcvrack.com/",
"manualUrl": "https://vcvrack.com/Fundamental.html#manual",
"sourceUrl": "https://github.com/VCVRack/Fundamental",
"version": "1.0.0",
"modules": {


+ 2
- 2
src/8vert.cpp View File

@@ -30,8 +30,8 @@ struct _8vert : Module {
float lastIn = 10.f;
for (int i = 0; i < 8; i++) {
lastIn = inputs[i].getNormalVoltage(lastIn);
float out = lastIn * params[i].value;
outputs[i].value = out;
float out = lastIn * params[i].getValue();
outputs[i].setVoltage(out);
lights[2*i + 0].setSmoothBrightness(out / 5.f, args.sampleTime);
lights[2*i + 1].setSmoothBrightness(-out / 5.f, args.sampleTime);
}


+ 7
- 7
src/ADSR.cpp View File

@@ -43,14 +43,14 @@ struct ADSR : Module {
}

void process(const ProcessArgs &args) override {
float attack = clamp(params[ATTACK_PARAM].value + inputs[ATTACK_INPUT].value / 10.f, 0.f, 1.f);
float decay = clamp(params[DECAY_PARAM].value + inputs[DECAY_INPUT].value / 10.f, 0.f, 1.f);
float sustain = clamp(params[SUSTAIN_PARAM].value + inputs[SUSTAIN_INPUT].value / 10.f, 0.f, 1.f);
float release = clamp(params[RELEASE_PARAM].value + inputs[RELEASE_INPUT].value / 10.f, 0.f, 1.f);
float attack = clamp(params[ATTACK_PARAM].getValue() + inputs[ATTACK_INPUT].getVoltage() / 10.f, 0.f, 1.f);
float decay = clamp(params[DECAY_PARAM].getValue() + inputs[DECAY_INPUT].getVoltage() / 10.f, 0.f, 1.f);
float sustain = clamp(params[SUSTAIN_PARAM].getValue() + inputs[SUSTAIN_INPUT].getVoltage() / 10.f, 0.f, 1.f);
float release = clamp(params[RELEASE_PARAM].getValue() + inputs[RELEASE_INPUT].getVoltage() / 10.f, 0.f, 1.f);

// Gate and trigger
bool gated = inputs[GATE_INPUT].value >= 1.f;
if (trigger.process(inputs[TRIG_INPUT].value))
bool gated = inputs[GATE_INPUT].getVoltage() >= 1.f;
if (trigger.process(inputs[TRIG_INPUT].getVoltage()))
decaying = false;

const float base = 20000.f;
@@ -94,7 +94,7 @@ struct ADSR : Module {
bool sustaining = isNear(env, sustain, 1e-3);
bool resting = isNear(env, 0.f, 1e-3);

outputs[ENVELOPE_OUTPUT].value = 10.f * env;
outputs[ENVELOPE_OUTPUT].setVoltage(10.f * env);

// Lights
lights[ATTACK_LIGHT].value = (gated && !decaying) ? 1.f : 0.f;


+ 6
- 6
src/Delay.cpp View File

@@ -49,12 +49,12 @@ struct Delay : Module {

void process(const ProcessArgs &args) override {
// Get input to delay block
float in = inputs[IN_INPUT].value;
float feedback = clamp(params[FEEDBACK_PARAM].value + inputs[FEEDBACK_INPUT].value / 10.0f, 0.0f, 1.0f);
float in = inputs[IN_INPUT].getVoltage();
float feedback = clamp(params[FEEDBACK_PARAM].getValue() + inputs[FEEDBACK_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
float dry = in + lastWet * feedback;

// Compute delay time in seconds
float delay = 1e-3 * std::pow(10.0f / 1e-3, clamp(params[TIME_PARAM].value + inputs[TIME_INPUT].value / 10.0f, 0.0f, 1.0f));
float delay = 1e-3 * std::pow(10.0f / 1e-3, clamp(params[TIME_PARAM].getValue() + inputs[TIME_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f));
// Number of delay samples
float index = delay * args.sampleRate;

@@ -91,7 +91,7 @@ struct Delay : Module {

// Apply color to delay wet output
// TODO Make it sound better
float color = clamp(params[COLOR_PARAM].value + inputs[COLOR_INPUT].value / 10.0f, 0.0f, 1.0f);
float color = clamp(params[COLOR_PARAM].getValue() + inputs[COLOR_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
float lowpassFreq = 10000.0f * std::pow(10.0f, clamp(2.0f*color, 0.0f, 1.0f));
lowpassFilter.setCutoff(lowpassFreq / args.sampleRate);
lowpassFilter.process(wet);
@@ -103,9 +103,9 @@ struct Delay : Module {

lastWet = wet;

float mix = clamp(params[MIX_PARAM].value + inputs[MIX_INPUT].value / 10.0f, 0.0f, 1.0f);
float mix = clamp(params[MIX_PARAM].getValue() + inputs[MIX_INPUT].getVoltage() / 10.0f, 0.0f, 1.0f);
float out = crossfade(in, wet, mix);
outputs[OUT_OUTPUT].value = out;
outputs[OUT_OUTPUT].setVoltage(out);
}
};



+ 15
- 15
src/LFO.cpp View File

@@ -108,17 +108,17 @@ struct LFO : Module {
}

void process(const ProcessArgs &args) override {
oscillator.setPitch(params[FREQ_PARAM].value + params[FM1_PARAM].value * inputs[FM1_INPUT].value + params[FM2_PARAM].value * inputs[FM2_INPUT].value);
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.f);
oscillator.offset = (params[OFFSET_PARAM].value > 0.f);
oscillator.invert = (params[INVERT_PARAM].value <= 0.f);
oscillator.setPitch(params[FREQ_PARAM].getValue() + params[FM1_PARAM].getValue() * inputs[FM1_INPUT].getVoltage() + params[FM2_PARAM].getValue() * inputs[FM2_INPUT].getVoltage());
oscillator.setPulseWidth(params[PW_PARAM].getValue() + params[PWM_PARAM].getValue() * inputs[PW_INPUT].getVoltage() / 10.f);
oscillator.offset = (params[OFFSET_PARAM].getValue() > 0.f);
oscillator.invert = (params[INVERT_PARAM].getValue() <= 0.f);
oscillator.step(args.sampleTime);
oscillator.setReset(inputs[RESET_INPUT].value);
oscillator.setReset(inputs[RESET_INPUT].getVoltage());

outputs[SIN_OUTPUT].value = 5.f * oscillator.sin();
outputs[TRI_OUTPUT].value = 5.f * oscillator.tri();
outputs[SAW_OUTPUT].value = 5.f * oscillator.saw();
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr();
outputs[SIN_OUTPUT].setVoltage(5.f * oscillator.sin());
outputs[TRI_OUTPUT].setVoltage(5.f * oscillator.tri());
outputs[SAW_OUTPUT].setVoltage(5.f * oscillator.saw());
outputs[SQR_OUTPUT].setVoltage(5.f * oscillator.sqr());

lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime);
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime);
@@ -203,13 +203,13 @@ struct LFO2 : Module {

void process(const ProcessArgs &args) override {
float deltaTime = args.sampleTime;
oscillator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value);
oscillator.offset = (params[OFFSET_PARAM].value > 0.f);
oscillator.invert = (params[INVERT_PARAM].value <= 0.f);
oscillator.setPitch(params[FREQ_PARAM].getValue() + params[FM_PARAM].getValue() * inputs[FM_INPUT].getVoltage());
oscillator.offset = (params[OFFSET_PARAM].getValue() > 0.f);
oscillator.invert = (params[INVERT_PARAM].getValue() <= 0.f);
oscillator.step(deltaTime);
oscillator.setReset(inputs[RESET_INPUT].value);
oscillator.setReset(inputs[RESET_INPUT].getVoltage());

float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value;
float wave = params[WAVE_PARAM].getValue() + inputs[WAVE_INPUT].getVoltage();
wave = clamp(wave, 0.f, 3.f);
float interp;
if (wave < 1.f)
@@ -218,7 +218,7 @@ struct LFO2 : Module {
interp = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f);
else
interp = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f);
outputs[INTERP_OUTPUT].value = 5.f * interp;
outputs[INTERP_OUTPUT].setVoltage(5.f * interp);

lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime);
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime);


+ 3
- 3
src/Mutes.cpp View File

@@ -37,11 +37,11 @@ struct Mutes : Module {
void process(const ProcessArgs &args) override {
float out = 0.f;
for (int i = 0; i < NUM_CHANNELS; i++) {
if (muteTrigger[i].process(params[MUTE_PARAM + i].value))
if (muteTrigger[i].process(params[MUTE_PARAM + i].getValue()))
state[i] ^= true;
if (inputs[IN_INPUT + i].active)
out = inputs[IN_INPUT + i].value;
outputs[OUT_OUTPUT + i].value = state[i] ? out : 0.f;
out = inputs[IN_INPUT + i].getVoltage();
outputs[OUT_OUTPUT + i].setVoltage(state[i] ? out : 0.f);
lights[MUTE_LIGHT + i].setBrightness(state[i] ? 0.9f : 0.f);
}
}


+ 11
- 11
src/SEQ3.cpp View File

@@ -110,7 +110,7 @@ struct SEQ3 : Module {
}

void setIndex(int index) {
int numSteps = (int) clamp(std::round(params[STEPS_PARAM].value + inputs[STEPS_INPUT].value), 1.0f, 8.0f);
int numSteps = (int) clamp(std::round(params[STEPS_PARAM].getValue() + inputs[STEPS_INPUT].getVoltage()), 1.0f, 8.0f);
phase = 0.f;
this->index = index;
if (this->index >= numSteps)
@@ -119,7 +119,7 @@ struct SEQ3 : Module {

void process(const ProcessArgs &args) override {
// Run
if (runningTrigger.process(params[RUN_PARAM].value)) {
if (runningTrigger.process(params[RUN_PARAM].getValue())) {
running = !running;
}

@@ -127,14 +127,14 @@ struct SEQ3 : Module {
if (running) {
if (inputs[EXT_CLOCK_INPUT].active) {
// External clock
if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].value)) {
if (clockTrigger.process(inputs[EXT_CLOCK_INPUT].getVoltage())) {
setIndex(index + 1);
}
gateIn = clockTrigger.isHigh();
}
else {
// Internal clock
float clockTime = std::pow(2.0f, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value);
float clockTime = std::pow(2.0f, params[CLOCK_PARAM].getValue() + inputs[CLOCK_INPUT].getVoltage());
phase += clockTime * args.sampleTime;
if (phase >= 1.0f) {
setIndex(index + 1);
@@ -144,24 +144,24 @@ struct SEQ3 : Module {
}

// Reset
if (resetTrigger.process(params[RESET_PARAM].value + inputs[RESET_INPUT].value)) {
if (resetTrigger.process(params[RESET_PARAM].getValue() + inputs[RESET_INPUT].getVoltage())) {
setIndex(0);
}

// Gate buttons
for (int i = 0; i < 8; i++) {
if (gateTriggers[i].process(params[GATE_PARAM + i].value)) {
if (gateTriggers[i].process(params[GATE_PARAM + i].getValue())) {
gates[i] = !gates[i];
}
outputs[GATE_OUTPUT + i].value = (running && gateIn && i == index && gates[i]) ? 10.0f : 0.0f;
outputs[GATE_OUTPUT + i].setVoltage((running && gateIn && i == index && gates[i]) ? 10.0f : 0.0f);
lights[GATE_LIGHTS + i].setSmoothBrightness((gateIn && i == index) ? (gates[i] ? 1.f : 0.33) : (gates[i] ? 0.66 : 0.0), args.sampleTime);
}

// Outputs
outputs[ROW1_OUTPUT].value = params[ROW1_PARAM + index].value;
outputs[ROW2_OUTPUT].value = params[ROW2_PARAM + index].value;
outputs[ROW3_OUTPUT].value = params[ROW3_PARAM + index].value;
outputs[GATES_OUTPUT].value = (gateIn && gates[index]) ? 10.0f : 0.0f;
outputs[ROW1_OUTPUT].setVoltage(params[ROW1_PARAM + index].getValue());
outputs[ROW2_OUTPUT].setVoltage(params[ROW2_PARAM + index].getValue());
outputs[ROW3_OUTPUT].setVoltage(params[ROW3_PARAM + index].getValue());
outputs[GATES_OUTPUT].setVoltage((gateIn && gates[index]) ? 10.0f : 0.0f);
lights[RUNNING_LIGHT].value = (running);
lights[RESET_LIGHT].setSmoothBrightness(resetTrigger.isHigh(), args.sampleTime);
lights[GATES_LIGHT].setSmoothBrightness(gateIn, args.sampleTime);


+ 12
- 12
src/Scope.cpp View File

@@ -59,28 +59,28 @@ struct Scope : Module {

void process(const ProcessArgs &args) override {
// Modes
if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) {
if (sumTrigger.process(params[LISSAJOUS_PARAM].getValue())) {
lissajous = !lissajous;
}
lights[PLOT_LIGHT].value = lissajous ? 0.0f : 1.0f;
lights[LISSAJOUS_LIGHT].value = lissajous ? 1.0f : 0.0f;

if (extTrigger.process(params[EXTERNAL_PARAM].value)) {
if (extTrigger.process(params[EXTERNAL_PARAM].getValue())) {
external = !external;
}
lights[INTERNAL_LIGHT].value = external ? 0.0f : 1.0f;
lights[EXTERNAL_LIGHT].value = external ? 1.0f : 0.0f;

// Compute time
float deltaTime = std::pow(2.0f, -params[TIME_PARAM].value);
float deltaTime = std::pow(2.0f, -params[TIME_PARAM].getValue());
int frameCount = (int) std::ceil(deltaTime * args.sampleRate);

// Add frame to buffer
if (bufferIndex < BUFFER_SIZE) {
if (++frameIndex > frameCount) {
frameIndex = 0;
bufferX[bufferIndex] = inputs[X_INPUT].value;
bufferY[bufferIndex] = inputs[Y_INPUT].value;
bufferX[bufferIndex] = inputs[X_INPUT].getVoltage();
bufferY[bufferIndex] = inputs[Y_INPUT].getVoltage();
bufferIndex++;
}
}
@@ -101,11 +101,11 @@ struct Scope : Module {
frameIndex++;

// Must go below 0.1fV to trigger
float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value;
float gate = external ? inputs[TRIG_INPUT].getVoltage() : inputs[X_INPUT].getVoltage();

// Reset if triggered
float holdTime = 0.1f;
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].value - 0.1f, params[TRIG_PARAM].value, 0.f, 1.f)) || (frameIndex >= args.sampleRate * holdTime)) {
if (resetTrigger.process(rescale(gate, params[TRIG_PARAM].getValue() - 0.1f, params[TRIG_PARAM].getValue(), 0.f, 1.f)) || (frameIndex >= args.sampleRate * holdTime)) {
bufferIndex = 0; frameIndex = 0; return;
}

@@ -260,10 +260,10 @@ struct ScopeDisplay : TransparentWidget {
if (!module)
return;

float gainX = std::pow(2.0f, std::round(module->params[Scope::X_SCALE_PARAM].value));
float gainY = std::pow(2.0f, std::round(module->params[Scope::Y_SCALE_PARAM].value));
float offsetX = module->params[Scope::X_POS_PARAM].value;
float offsetY = module->params[Scope::Y_POS_PARAM].value;
float gainX = std::pow(2.0f, std::round(module->params[Scope::X_SCALE_PARAM].getValue()));
float gainY = std::pow(2.0f, std::round(module->params[Scope::Y_SCALE_PARAM].getValue()));
float offsetX = module->params[Scope::X_POS_PARAM].getValue();
float offsetY = module->params[Scope::Y_POS_PARAM].getValue();

float valuesX[BUFFER_SIZE];
float valuesY[BUFFER_SIZE];
@@ -297,7 +297,7 @@ struct ScopeDisplay : TransparentWidget {
drawWaveform(args, valuesX, NULL);
}

float valueTrig = (module->params[Scope::TRIG_PARAM].value + offsetX) * gainX / 10.0f;
float valueTrig = (module->params[Scope::TRIG_PARAM].getValue() + offsetX) * gainX / 10.0f;
drawTrig(args, valueTrig);
}



+ 52
- 43
src/SequentialSwitch.cpp View File

@@ -1,7 +1,8 @@
#include "plugin.hpp"


template <int TYPE>
// Only valid for <1, 4> and <4, 1>
template <int INPUTS, int OUTPUTS>
struct SequentialSwitch : Module {
enum ParamIds {
CHANNELS_PARAM,
@@ -10,11 +11,11 @@ struct SequentialSwitch : Module {
enum InputIds {
CLOCK_INPUT,
RESET_INPUT,
ENUMS(IN_INPUT, TYPE == 1 ? 1 : 4),
ENUMS(IN_INPUTS, INPUTS),
NUM_INPUTS
};
enum OutputIds {
ENUMS(OUT_OUTPUT, TYPE == 1 ? 4 : 1),
ENUMS(OUT_OUTPUTS, OUTPUTS),
NUM_OUTPUTS
};
enum LightIds {
@@ -25,61 +26,69 @@ struct SequentialSwitch : Module {
dsp::SchmittTrigger clockTrigger;
dsp::SchmittTrigger resetTrigger;
int channel = 0;
dsp::SlewLimiter channelFilter[4];
dsp::Counter lightCounter;
dsp::SlewLimiter clickFilters[4];

SequentialSwitch() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
params[CHANNELS_PARAM].config(0.0, 2.0, 0.0, "Channels", "", 0.f, 1.f, 2.f);
params[CHANNELS_PARAM].config(0.0, 2.0, 0.0, "Channels", "", 0, -1, 4);

for (int i = 0; i < 4; i++) {
channelFilter[i].rise = 0.01f;
channelFilter[i].fall = 0.01f;
for (int i = 0; i < OUTPUTS; i++) {
clickFilters[i].rise = 400.f; // Hz
clickFilters[i].fall = 400.f; // Hz
}
lightCounter.setPeriod(512);
}

void process(const ProcessArgs &args) override {
// Determine current channel
if (clockTrigger.process(inputs[CLOCK_INPUT].value / 2.f)) {
if (clockTrigger.process(rescale(inputs[CLOCK_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) {
channel++;
}
if (resetTrigger.process(inputs[RESET_INPUT].value / 2.f)) {
if (resetTrigger.process(rescale(inputs[RESET_INPUT].getVoltage(), 0.1f, 2.f, 0.f, 1.f))) {
channel = 0;
}
int channels = 4 - (int) params[CHANNELS_PARAM].value;
channel %= channels;
int channels = 4 - (int) std::round(params[CHANNELS_PARAM].getValue());
if (channel >= channels)
channel = 0;

// Filter channels
for (int i = 0; i < 4; i++) {
channelFilter[i].process(channel == i ? 1.f : 0.f);
// Get input
float v = 0.f;
if (INPUTS == 1) {
v = inputs[IN_INPUTS + 0].getVoltage();
}

// Set outputs
if (TYPE == 1) {
float out = inputs[IN_INPUT + 0].value;
for (int i = 0; i < 4; i++) {
outputs[OUT_OUTPUT + i].value = channelFilter[i].out * out;
else {
for (int i = 0; i < INPUTS; i++) {
float in = inputs[IN_INPUTS + i].getVoltage();
v += in * clickFilters[i].process(args.sampleTime, channel == i);
}
}

// Set output
if (OUTPUTS == 1) {
outputs[OUT_OUTPUTS + 0].setVoltage(v);
}
else {
float out = 0.f;
for (int i = 0; i < 4; i++) {
out += channelFilter[i].out * inputs[IN_INPUT + i].value;
for (int i = 0; i < OUTPUTS; i++) {
float out = v * clickFilters[i].process(args.sampleTime, channel == i);
outputs[OUT_OUTPUTS + i].setVoltage(out);
}
outputs[OUT_OUTPUT + 0].value = out;
}

// Set lights
for (int i = 0; i < 4; i++) {
lights[CHANNEL_LIGHT + i].setBrightness(channelFilter[i].out);
if (lightCounter.process()) {
for (int i = 0; i < 4; i++) {
lights[CHANNEL_LIGHT + i].setBrightness(channel == i);
}
}
}
};


struct SequentialSwitch1Widget : ModuleWidget {
typedef SequentialSwitch<1> TSequentialSwitch;
typedef SequentialSwitch<1, 4> TSequentialSwitch;

SequentialSwitch1Widget(SequentialSwitch<1> *module) {
SequentialSwitch1Widget(TSequentialSwitch *module) {
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch1.svg")));

@@ -90,12 +99,12 @@ struct SequentialSwitch1Widget : ModuleWidget {

addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUT + 0));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUTS + 0));

addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUT + 0));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUT + 1));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUT + 2));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUT + 3));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUTS + 0));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUTS + 1));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUTS + 2));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUTS + 3));

addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0));
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1));
@@ -105,13 +114,13 @@ struct SequentialSwitch1Widget : ModuleWidget {
};


Model *modelSequentialSwitch1 = createModel<SequentialSwitch<1>, SequentialSwitch1Widget>("SequentialSwitch1");
Model *modelSequentialSwitch1 = createModel<SequentialSwitch<1, 4>, SequentialSwitch1Widget>("SequentialSwitch1");


struct SequentialSwitch2Widget : ModuleWidget {
typedef SequentialSwitch<2> TSequentialSwitch;
typedef SequentialSwitch<4, 1> TSequentialSwitch;

SequentialSwitch2Widget(SequentialSwitch<2> *module) {
SequentialSwitch2Widget(TSequentialSwitch *module) {
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SequentialSwitch2.svg")));

@@ -122,12 +131,12 @@ struct SequentialSwitch2Widget : ModuleWidget {

addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUT + 0));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUT + 1));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUT + 2));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUT + 3));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUTS + 0));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUTS + 1));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUTS + 2));
addInput(createInput<PJ301MPort>(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUTS + 3));

addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUT + 0));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUTS + 0));

addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0));
addChild(createLight<TinyLight<GreenLight>>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1));
@@ -137,4 +146,4 @@ struct SequentialSwitch2Widget : ModuleWidget {
};


Model *modelSequentialSwitch2 = createModel<SequentialSwitch<2>, SequentialSwitch2Widget>("SequentialSwitch2");
Model *modelSequentialSwitch2 = createModel<SequentialSwitch<4, 1>, SequentialSwitch2Widget>("SequentialSwitch2");

+ 4
- 4
src/Unity.cpp View File

@@ -42,7 +42,7 @@ struct Unity : Module {
for (int i = 0; i < 2; i++) {
// Inputs
for (int j = 0; j < 6; j++) {
mix[i] += inputs[IN_INPUTS + 6 * i + j].value;
mix[i] += inputs[IN_INPUTS + 6 * i + j].getVoltage();
if (inputs[IN_INPUTS + 6 * i + j].active)
count[i]++;
}
@@ -58,12 +58,12 @@ struct Unity : Module {

for (int i = 0; i < 2; i++) {
// Params
if (count[i] > 0 && (int) std::round(params[AVG1_PARAM + i].value) == 1)
if (count[i] > 0 && (int) std::round(params[AVG1_PARAM + i].getValue()) == 1)
mix[i] /= count[i];

// Outputs
outputs[MIX1_OUTPUT + 2 * i].value = mix[i];
outputs[INV1_OUTPUT + 2 * i].value = -mix[i];
outputs[MIX1_OUTPUT + 2 * i].setVoltage(mix[i]);
outputs[INV1_OUTPUT + 2 * i].setVoltage(-mix[i]);
vuMeters[i].process(args.sampleTime, mix[i] / 10.f);
}



+ 6
- 6
src/VCA.cpp View File

@@ -29,13 +29,13 @@ struct VCA : Module {
}

void stepChannel(InputIds in, ParamIds level, InputIds lin, InputIds exp, OutputIds out) {
float v = inputs[in].value * params[level].value;
float v = inputs[in].getVoltage() * params[level].getValue();
if (inputs[lin].active)
v *= clamp(inputs[lin].value / 10.0f, 0.0f, 1.0f);
v *= clamp(inputs[lin].getVoltage() / 10.0f, 0.0f, 1.0f);
const float expBase = 50.0f;
if (inputs[exp].active)
v *= rescale(std::pow(expBase, clamp(inputs[exp].value / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f);
outputs[out].value = v;
v *= rescale(std::pow(expBase, clamp(inputs[exp].getVoltage() / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f);
outputs[out].setVoltage(v);
}

void process(const ProcessArgs &args) override {
@@ -104,10 +104,10 @@ struct VCA_1 : Module {

void process(const ProcessArgs &args) override {
float cv = inputs[CV_INPUT].getNormalVoltage(10.f) / 10.f;
if ((int) params[EXP_PARAM].value == 0)
if ((int) params[EXP_PARAM].getValue() == 0)
cv = std::pow(cv, 4.f);
lastCv = cv;
outputs[OUT_OUTPUT].value = inputs[IN_INPUT].value * params[LEVEL_PARAM].value * cv;
outputs[OUT_OUTPUT].setVoltage(inputs[IN_INPUT].getVoltage() * params[LEVEL_PARAM].getValue() * cv);
}
};



+ 12
- 12
src/VCF.cpp View File

@@ -93,13 +93,13 @@ struct VCF : Module {

void process(const ProcessArgs &args) override {
if (!outputs[LPF_OUTPUT].active && !outputs[HPF_OUTPUT].active) {
outputs[LPF_OUTPUT].value = 0.f;
outputs[HPF_OUTPUT].value = 0.f;
outputs[LPF_OUTPUT].setVoltage(0.f);
outputs[HPF_OUTPUT].setVoltage(0.f);
return;
}

float input = inputs[IN_INPUT].value / 5.f;
float drive = clamp(params[DRIVE_PARAM].value + inputs[DRIVE_INPUT].value / 10.f, 0.f, 1.f);
float input = inputs[IN_INPUT].getVoltage() / 5.f;
float drive = clamp(params[DRIVE_PARAM].getValue() + inputs[DRIVE_INPUT].getVoltage() / 10.f, 0.f, 1.f);
float gain = std::pow(1.f + drive, 5);
input *= gain;

@@ -107,15 +107,15 @@ struct VCF : Module {
input += 1e-6f * (2.f * random::uniform() - 1.f);

// Set resonance
float res = clamp(params[RES_PARAM].value + inputs[RES_INPUT].value / 10.f, 0.f, 1.f);
float res = clamp(params[RES_PARAM].getValue() + inputs[RES_INPUT].getVoltage() / 10.f, 0.f, 1.f);
filter.resonance = std::pow(res, 2) * 10.f;

// Set cutoff frequency
float pitch = 0.f;
if (inputs[FREQ_INPUT].active)
pitch += inputs[FREQ_INPUT].value * dsp::quadraticBipolar(params[FREQ_CV_PARAM].value);
pitch += params[FREQ_PARAM].value * 10.f - 5.f;
pitch += dsp::quadraticBipolar(params[FINE_PARAM].value * 2.f - 1.f) * 7.f / 12.f;
pitch += inputs[FREQ_INPUT].getVoltage() * dsp::quadraticBipolar(params[FREQ_CV_PARAM].getValue());
pitch += params[FREQ_PARAM].getValue() * 10.f - 5.f;
pitch += dsp::quadraticBipolar(params[FINE_PARAM].getValue() * 2.f - 1.f) * 7.f / 12.f;
float cutoff = 261.626f * std::pow(2.f, pitch);
cutoff = clamp(cutoff, 1.f, 8000.f);
filter.setCutoff(cutoff);
@@ -136,15 +136,15 @@ struct VCF : Module {

// Set outputs
if (outputs[LPF_OUTPUT].active) {
outputs[LPF_OUTPUT].value = 5.f * lowpassDecimator.process(lowpassBuf);
outputs[LPF_OUTPUT].setVoltage(5.f * lowpassDecimator.process(lowpassBuf));
}
if (outputs[HPF_OUTPUT].active) {
outputs[HPF_OUTPUT].value = 5.f * highpassDecimator.process(highpassBuf);
outputs[HPF_OUTPUT].setVoltage(5.f * highpassDecimator.process(highpassBuf));
}
*/
filter.process(input, args.sampleTime);
outputs[LPF_OUTPUT].value = 5.f * filter.lowpass;
outputs[HPF_OUTPUT].value = 5.f * filter.highpass;
outputs[LPF_OUTPUT].setVoltage(5.f * filter.lowpass);
outputs[HPF_OUTPUT].setVoltage(5.f * filter.highpass);
}
};



+ 12
- 12
src/VCMixer.cpp View File

@@ -21,27 +21,27 @@ struct VCMixer : Module {

VCMixer() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS);
params[MIX_LVL_PARAM].config(0.0, 2.0, 1.0, "Master level");
params[LVL_PARAM + 0].config(0.0, 1.0, 1.0, "Ch 1 level");
params[LVL_PARAM + 1].config(0.0, 1.0, 1.0, "Ch 2 level");
params[LVL_PARAM + 2].config(0.0, 1.0, 1.0, "Ch 3 level");
params[LVL_PARAM + 3].config(0.0, 1.0, 1.0, "Ch 4 level");
params[MIX_LVL_PARAM].config(0.0, 2.0, 1.0, "Master level", "%", 0, 100);
params[LVL_PARAM + 0].config(0.0, 1.0, 1.0, "Ch 1 level", "%", 0, 100);
params[LVL_PARAM + 1].config(0.0, 1.0, 1.0, "Ch 2 level", "%", 0, 100);
params[LVL_PARAM + 2].config(0.0, 1.0, 1.0, "Ch 3 level", "%", 0, 100);
params[LVL_PARAM + 3].config(0.0, 1.0, 1.0, "Ch 4 level", "%", 0, 100);
}

void process(const ProcessArgs &args) override {
float mix = 0.f;
for (int i = 0; i < 4; i++) {
float ch = inputs[CH_INPUT + i].value;
ch *= std::pow(params[LVL_PARAM + i].value, 2.f);
float ch = inputs[CH_INPUT + i].getVoltage();
ch *= std::pow(params[LVL_PARAM + i].getValue(), 2.f);
if (inputs[CV_INPUT + i].active)
ch *= clamp(inputs[CV_INPUT + i].value / 10.f, 0.f, 1.f);
outputs[CH_OUTPUT + i].value = ch;
ch *= clamp(inputs[CV_INPUT + i].getVoltage() / 10.f, 0.f, 1.f);
outputs[CH_OUTPUT + i].setVoltage(ch);
mix += ch;
}
mix *= params[MIX_LVL_PARAM].value;
mix *= params[MIX_LVL_PARAM].getValue();
if (inputs[MIX_CV_INPUT].active)
mix *= clamp(inputs[MIX_CV_INPUT].value / 10.f, 0.f, 1.f);
outputs[MIX_OUTPUT].value = mix;
mix *= clamp(inputs[MIX_CV_INPUT].getVoltage() / 10.f, 0.f, 1.f);
outputs[MIX_OUTPUT].setVoltage(mix);
}
};



+ 18
- 18
src/VCO.cpp View File

@@ -205,29 +205,29 @@ struct VCO : Module {
}

void process(const ProcessArgs &args) override {
oscillator.analog = params[MODE_PARAM].value > 0.f;
oscillator.soft = params[SYNC_PARAM].value <= 0.f;
oscillator.analog = params[MODE_PARAM].getValue() > 0.f;
oscillator.soft = params[SYNC_PARAM].getValue() <= 0.f;

float pitchFine = 3.f * dsp::quadraticBipolar(params[FINE_PARAM].value);
float pitchCv = 12.f * inputs[PITCH_INPUT].value;
float pitchFine = 3.f * dsp::quadraticBipolar(params[FINE_PARAM].getValue());
float pitchCv = 12.f * inputs[PITCH_INPUT].getVoltage();
if (inputs[FM_INPUT].active) {
pitchCv += dsp::quadraticBipolar(params[FM_PARAM].value) * 12.f * inputs[FM_INPUT].value;
pitchCv += dsp::quadraticBipolar(params[FM_PARAM].getValue()) * 12.f * inputs[FM_INPUT].getVoltage();
}
oscillator.setPitch(params[FREQ_PARAM].value, pitchFine + pitchCv);
oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.f);
oscillator.setPitch(params[FREQ_PARAM].getValue(), pitchFine + pitchCv);
oscillator.setPulseWidth(params[PW_PARAM].getValue() + params[PWM_PARAM].getValue() * inputs[PW_INPUT].getVoltage() / 10.f);
oscillator.syncEnabled = inputs[SYNC_INPUT].active;

oscillator.process(args.sampleTime, inputs[SYNC_INPUT].value);
oscillator.process(args.sampleTime, inputs[SYNC_INPUT].getVoltage());

// Set output
if (outputs[SIN_OUTPUT].active)
outputs[SIN_OUTPUT].value = 5.f * oscillator.sin();
outputs[SIN_OUTPUT].setVoltage(5.f * oscillator.sin());
if (outputs[TRI_OUTPUT].active)
outputs[TRI_OUTPUT].value = 5.f * oscillator.tri();
outputs[TRI_OUTPUT].setVoltage(5.f * oscillator.tri());
if (outputs[SAW_OUTPUT].active)
outputs[SAW_OUTPUT].value = 5.f * oscillator.saw();
outputs[SAW_OUTPUT].setVoltage(5.f * oscillator.saw());
if (outputs[SQR_OUTPUT].active)
outputs[SQR_OUTPUT].value = 5.f * oscillator.sqr();
outputs[SQR_OUTPUT].setVoltage(5.f * oscillator.sqr());

lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), args.sampleTime);
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), args.sampleTime);
@@ -310,17 +310,17 @@ struct VCO2 : Module {

void process(const ProcessArgs &args) override {
float deltaTime = args.sampleTime;
oscillator.analog = params[MODE_PARAM].value > 0.f;
oscillator.soft = params[SYNC_PARAM].value <= 0.f;
oscillator.analog = params[MODE_PARAM].getValue() > 0.f;
oscillator.soft = params[SYNC_PARAM].getValue() <= 0.f;

float pitchCv = params[FREQ_PARAM].value + dsp::quadraticBipolar(params[FM_PARAM].value) * 12.f * inputs[FM_INPUT].value;
float pitchCv = params[FREQ_PARAM].getValue() + dsp::quadraticBipolar(params[FM_PARAM].getValue()) * 12.f * inputs[FM_INPUT].getVoltage();
oscillator.setPitch(0.f, pitchCv);
oscillator.syncEnabled = inputs[SYNC_INPUT].active;

oscillator.process(deltaTime, inputs[SYNC_INPUT].value);
oscillator.process(deltaTime, inputs[SYNC_INPUT].getVoltage());

// Set output
float wave = clamp(params[WAVE_PARAM].value + inputs[WAVE_INPUT].value, 0.f, 3.f);
float wave = clamp(params[WAVE_PARAM].getValue() + inputs[WAVE_INPUT].getVoltage(), 0.f, 3.f);
float out;
if (wave < 1.f)
out = crossfade(oscillator.sin(), oscillator.tri(), wave);
@@ -328,7 +328,7 @@ struct VCO2 : Module {
out = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.f);
else
out = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.f);
outputs[OUT_OUTPUT].value = 5.f * out;
outputs[OUT_OUTPUT].setVoltage(5.f * out);

lights[PHASE_POS_LIGHT].setSmoothBrightness(oscillator.light(), deltaTime);
lights[PHASE_NEG_LIGHT].setSmoothBrightness(-oscillator.light(), deltaTime);


Loading…
Cancel
Save