From 1a10253ae3853366384f90337a89242af38c7fbc Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sun, 13 Jan 2019 07:55:22 -0500 Subject: [PATCH] Update to Rack v1 API --- src/8vert.cpp | 111 +++++++++++++---------- src/ADSR.cpp | 138 ++++++++++++++-------------- src/Delay.cpp | 169 ++++++++++++++++++----------------- src/Fundamental.cpp | 2 - src/Fundamental.hpp | 3 +- src/LFO.cpp | 188 +++++++++++++++++++++------------------ src/Mutes.cpp | 105 +++++++++++----------- src/SEQ3.cpp | 67 ++++++++------ src/Scope.cpp | 175 +++++++++++++++++++----------------- src/SequentialSwitch.cpp | 51 ++++++----- src/Unity.cpp | 126 +++++++++++++------------- src/VCA.cpp | 81 +++++++++-------- src/VCF.cpp | 48 +++++----- src/VCMixer.cpp | 51 ++++++----- src/VCO.cpp | 24 ++--- 15 files changed, 712 insertions(+), 627 deletions(-) diff --git a/src/8vert.cpp b/src/8vert.cpp index 9b53c7e..ee0e7db 100644 --- a/src/8vert.cpp +++ b/src/8vert.cpp @@ -3,32 +3,45 @@ struct _8vert : Module { enum ParamIds { - NUM_PARAMS = 8 + ENUMS(GAIN_PARAMS, 8), + NUM_PARAMS }; enum InputIds { - NUM_INPUTS = 8 + ENUMS(IN_INPUTS, 8), + NUM_INPUTS }; enum OutputIds { - NUM_OUTPUTS = 8 + ENUMS(OUT_OUTPUTS, 8), + NUM_OUTPUTS }; enum LightIds { - NUM_LIGHTS = 16 + ENUMS(OUT_LIGHTS, 8*2), + NUM_LIGHTS }; - _8vert() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; + _8vert() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[GAIN_PARAMS + 0].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 1].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 2].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 3].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 4].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 5].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 6].config(-1.f, 1.f, 0.f); + params[GAIN_PARAMS + 7].config(-1.f, 1.f, 0.f); + } -void _8vert::step() { - float lastIn = 10.0f; - for (int i = 0; i < 8; i++) { - lastIn = inputs[i].normalize(lastIn); - float out = lastIn * params[i].value; - outputs[i].value = out; - lights[2*i + 0].setBrightnessSmooth(fmaxf(0.0f, out / 5.0f)); - lights[2*i + 1].setBrightnessSmooth(fmaxf(0.0f, -out / 5.0f)); + void step() override { + float lastIn = 10.f; + for (int i = 0; i < 8; i++) { + lastIn = inputs[i].normalize(lastIn); + float out = lastIn * params[i].value; + outputs[i].value = out; + lights[2*i + 0].setBrightnessSmooth(std::max(0.f, out / 5.f)); + lights[2*i + 1].setBrightnessSmooth(std::max(0.f, -out / 5.f)); + } } -} +}; struct _8vertWidget : ModuleWidget { @@ -36,48 +49,48 @@ struct _8vertWidget : ModuleWidget { }; _8vertWidget::_8vertWidget(_8vert *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/8vert.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/8vert.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x - 30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x - 30, 365))); - addParam(createParam(Vec(45.308, 47.753), module, 0, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 86.198), module, 1, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 124.639), module, 2, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 163.084), module, 3, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 201.529), module, 4, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 239.974), module, 5, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 278.415), module, 6, -1.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(45.308, 316.86), module, 7, -1.0f, 1.0f, 0.0f)); + addParam(createParam(Vec(45.308, 47.753), module, _8vert::GAIN_PARAMS + 0)); + addParam(createParam(Vec(45.308, 86.198), module, _8vert::GAIN_PARAMS + 1)); + addParam(createParam(Vec(45.308, 124.639), module, _8vert::GAIN_PARAMS + 2)); + addParam(createParam(Vec(45.308, 163.084), module, _8vert::GAIN_PARAMS + 3)); + addParam(createParam(Vec(45.308, 201.529), module, _8vert::GAIN_PARAMS + 4)); + addParam(createParam(Vec(45.308, 239.974), module, _8vert::GAIN_PARAMS + 5)); + addParam(createParam(Vec(45.308, 278.415), module, _8vert::GAIN_PARAMS + 6)); + addParam(createParam(Vec(45.308, 316.86), module, _8vert::GAIN_PARAMS + 7)); - addInput(createPort(Vec(9.507, 50.397), PortWidget::INPUT, module, 0)); - addInput(createPort(Vec(9.507, 88.842), PortWidget::INPUT, module, 1)); - addInput(createPort(Vec(9.507, 127.283), PortWidget::INPUT, module, 2)); - addInput(createPort(Vec(9.507, 165.728), PortWidget::INPUT, module, 3)); - addInput(createPort(Vec(9.507, 204.173), PortWidget::INPUT, module, 4)); - addInput(createPort(Vec(9.507, 242.614), PortWidget::INPUT, module, 5)); - addInput(createPort(Vec(9.507, 281.059), PortWidget::INPUT, module, 6)); - addInput(createPort(Vec(9.507, 319.504), PortWidget::INPUT, module, 7)); + addInput(createInput(Vec(9.507, 50.397), module, _8vert::IN_INPUTS + 0)); + addInput(createInput(Vec(9.507, 88.842), module, _8vert::IN_INPUTS + 1)); + addInput(createInput(Vec(9.507, 127.283), module, _8vert::IN_INPUTS + 2)); + addInput(createInput(Vec(9.507, 165.728), module, _8vert::IN_INPUTS + 3)); + addInput(createInput(Vec(9.507, 204.173), module, _8vert::IN_INPUTS + 4)); + addInput(createInput(Vec(9.507, 242.614), module, _8vert::IN_INPUTS + 5)); + addInput(createInput(Vec(9.507, 281.059), module, _8vert::IN_INPUTS + 6)); + addInput(createInput(Vec(9.507, 319.504), module, _8vert::IN_INPUTS + 7)); - addOutput(createPort(Vec(86.393, 50.397), PortWidget::OUTPUT, module, 0)); - addOutput(createPort(Vec(86.393, 88.842), PortWidget::OUTPUT, module, 1)); - addOutput(createPort(Vec(86.393, 127.283), PortWidget::OUTPUT, module, 2)); - addOutput(createPort(Vec(86.393, 165.728), PortWidget::OUTPUT, module, 3)); - addOutput(createPort(Vec(86.393, 204.173), PortWidget::OUTPUT, module, 4)); - addOutput(createPort(Vec(86.393, 242.614), PortWidget::OUTPUT, module, 5)); - addOutput(createPort(Vec(86.393, 281.059), PortWidget::OUTPUT, module, 6)); - addOutput(createPort(Vec(86.393, 319.504), PortWidget::OUTPUT, module, 7)); + addOutput(createOutput(Vec(86.393, 50.397), module, _8vert::OUT_OUTPUTS + 0)); + addOutput(createOutput(Vec(86.393, 88.842), module, _8vert::OUT_OUTPUTS + 1)); + addOutput(createOutput(Vec(86.393, 127.283), module, _8vert::OUT_OUTPUTS + 2)); + addOutput(createOutput(Vec(86.393, 165.728), module, _8vert::OUT_OUTPUTS + 3)); + addOutput(createOutput(Vec(86.393, 204.173), module, _8vert::OUT_OUTPUTS + 4)); + addOutput(createOutput(Vec(86.393, 242.614), module, _8vert::OUT_OUTPUTS + 5)); + addOutput(createOutput(Vec(86.393, 281.059), module, _8vert::OUT_OUTPUTS + 6)); + addOutput(createOutput(Vec(86.393, 319.504), module, _8vert::OUT_OUTPUTS + 7)); - addChild(createLight>(Vec(107.702, 50.414), module, 0)); - addChild(createLight>(Vec(107.702, 88.859), module, 2)); - addChild(createLight>(Vec(107.702, 127.304), module, 4)); - addChild(createLight>(Vec(107.702, 165.745), module, 6)); - addChild(createLight>(Vec(107.702, 204.19), module, 8)); - addChild(createLight>(Vec(107.702, 242.635), module, 10)); - addChild(createLight>(Vec(107.702, 281.076), module, 12)); - addChild(createLight>(Vec(107.702, 319.521), module, 14)); + addChild(createLight>(Vec(107.702, 50.414), module, _8vert::OUT_LIGHTS + 0*2)); + addChild(createLight>(Vec(107.702, 88.859), module, _8vert::OUT_LIGHTS + 1*2)); + addChild(createLight>(Vec(107.702, 127.304), module, _8vert::OUT_LIGHTS + 2*2)); + addChild(createLight>(Vec(107.702, 165.745), module, _8vert::OUT_LIGHTS + 3*2)); + addChild(createLight>(Vec(107.702, 204.19), module, _8vert::OUT_LIGHTS + 4*2)); + addChild(createLight>(Vec(107.702, 242.635), module, _8vert::OUT_LIGHTS + 5*2)); + addChild(createLight>(Vec(107.702, 281.076), module, _8vert::OUT_LIGHTS + 6*2)); + addChild(createLight>(Vec(107.702, 319.521), module, _8vert::OUT_LIGHTS + 7*2)); } diff --git a/src/ADSR.cpp b/src/ADSR.cpp index 0971b8a..6021d0d 100644 --- a/src/ADSR.cpp +++ b/src/ADSR.cpp @@ -31,74 +31,78 @@ struct ADSR : Module { }; bool decaying = false; - float env = 0.0f; - SchmittTrigger trigger; - - ADSR() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - + float env = 0.f; + dsp::SchmittTrigger trigger; + + ADSR() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[ATTACK_PARAM].config(0.f, 1.f, 0.5f); + params[DECAY_PARAM].config(0.f, 1.f, 0.5f); + params[SUSTAIN_PARAM].config(0.f, 1.f, 0.5f); + params[RELEASE_PARAM].config(0.f, 1.f, 0.5f); + } -void ADSR::step() { - float attack = clamp(params[ATTACK_PARAM].value + inputs[ATTACK_INPUT].value / 10.0f, 0.0f, 1.0f); - float decay = clamp(params[DECAY_PARAM].value + inputs[DECAY_INPUT].value / 10.0f, 0.0f, 1.0f); - float sustain = clamp(params[SUSTAIN_PARAM].value + inputs[SUSTAIN_INPUT].value / 10.0f, 0.0f, 1.0f); - float release = clamp(params[RELEASE_PARAM].value + inputs[RELEASE_INPUT].value / 10.0f, 0.0f, 1.0f); - - // Gate and trigger - bool gated = inputs[GATE_INPUT].value >= 1.0f; - if (trigger.process(inputs[TRIG_INPUT].value)) - decaying = false; - - const float base = 20000.0f; - const float maxTime = 10.0f; - if (gated) { - if (decaying) { - // Decay - if (decay < 1e-4) { - env = sustain; + void step() 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); + + // Gate and trigger + bool gated = inputs[GATE_INPUT].value >= 1.f; + if (trigger.process(inputs[TRIG_INPUT].value)) + decaying = false; + + const float base = 20000.f; + const float maxTime = 10.f; + if (gated) { + if (decaying) { + // Decay + if (decay < 1e-4) { + env = sustain; + } + else { + env += std::pow(base, 1 - decay) / maxTime * (sustain - env) * app()->engine->getSampleTime(); + } } else { - env += powf(base, 1 - decay) / maxTime * (sustain - env) * engineGetSampleTime(); + // Attack + // Skip ahead if attack is all the way down (infinitely fast) + if (attack < 1e-4) { + env = 1.f; + } + else { + env += std::pow(base, 1 - attack) / maxTime * (1.01f - env) * app()->engine->getSampleTime(); + } + if (env >= 1.f) { + env = 1.f; + decaying = true; + } } } else { - // Attack - // Skip ahead if attack is all the way down (infinitely fast) - if (attack < 1e-4) { - env = 1.0f; + // Release + if (release < 1e-4) { + env = 0.f; } else { - env += powf(base, 1 - attack) / maxTime * (1.01f - env) * engineGetSampleTime(); + env += std::pow(base, 1 - release) / maxTime * (0.f - env) * app()->engine->getSampleTime(); } - if (env >= 1.0f) { - env = 1.0f; - decaying = true; - } - } - } - else { - // Release - if (release < 1e-4) { - env = 0.0f; + decaying = false; } - else { - env += powf(base, 1 - release) / maxTime * (0.0f - env) * engineGetSampleTime(); - } - decaying = false; - } - bool sustaining = isNear(env, sustain, 1e-3); - bool resting = isNear(env, 0.0f, 1e-3); + bool sustaining = isNear(env, sustain, 1e-3); + bool resting = isNear(env, 0.f, 1e-3); - outputs[ENVELOPE_OUTPUT].value = 10.0f * env; + outputs[ENVELOPE_OUTPUT].value = 10.f * env; - // Lights - lights[ATTACK_LIGHT].value = (gated && !decaying) ? 1.0f : 0.0f; - lights[DECAY_LIGHT].value = (gated && decaying && !sustaining) ? 1.0f : 0.0f; - lights[SUSTAIN_LIGHT].value = (gated && decaying && sustaining) ? 1.0f : 0.0f; - lights[RELEASE_LIGHT].value = (!gated && !resting) ? 1.0f : 0.0f; -} + // Lights + lights[ATTACK_LIGHT].value = (gated && !decaying) ? 1.f : 0.f; + lights[DECAY_LIGHT].value = (gated && decaying && !sustaining) ? 1.f : 0.f; + lights[SUSTAIN_LIGHT].value = (gated && decaying && sustaining) ? 1.f : 0.f; + lights[RELEASE_LIGHT].value = (!gated && !resting) ? 1.f : 0.f; + } +}; struct ADSRWidget : ModuleWidget { @@ -106,26 +110,26 @@ struct ADSRWidget : ModuleWidget { }; ADSRWidget::ADSRWidget(ADSR *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/ADSR.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/ADSR.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x-30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x-30, 365))); - addParam(createParam(Vec(62, 57), module, ADSR::ATTACK_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(62, 124), module, ADSR::DECAY_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(62, 191), module, ADSR::SUSTAIN_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(62, 257), module, ADSR::RELEASE_PARAM, 0.0f, 1.0f, 0.5f)); + addParam(createParam(Vec(62, 57), module, ADSR::ATTACK_PARAM)); + addParam(createParam(Vec(62, 124), module, ADSR::DECAY_PARAM)); + addParam(createParam(Vec(62, 191), module, ADSR::SUSTAIN_PARAM)); + addParam(createParam(Vec(62, 257), module, ADSR::RELEASE_PARAM)); - addInput(createPort(Vec(9, 63), PortWidget::INPUT, module, ADSR::ATTACK_INPUT)); - addInput(createPort(Vec(9, 129), PortWidget::INPUT, module, ADSR::DECAY_INPUT)); - addInput(createPort(Vec(9, 196), PortWidget::INPUT, module, ADSR::SUSTAIN_INPUT)); - addInput(createPort(Vec(9, 263), PortWidget::INPUT, module, ADSR::RELEASE_INPUT)); + addInput(createInput(Vec(9, 63), module, ADSR::ATTACK_INPUT)); + addInput(createInput(Vec(9, 129), module, ADSR::DECAY_INPUT)); + addInput(createInput(Vec(9, 196), module, ADSR::SUSTAIN_INPUT)); + addInput(createInput(Vec(9, 263), module, ADSR::RELEASE_INPUT)); - addInput(createPort(Vec(9, 320), PortWidget::INPUT, module, ADSR::GATE_INPUT)); - addInput(createPort(Vec(48, 320), PortWidget::INPUT, module, ADSR::TRIG_INPUT)); - addOutput(createPort(Vec(87, 320), PortWidget::OUTPUT, module, ADSR::ENVELOPE_OUTPUT)); + addInput(createInput(Vec(9, 320), module, ADSR::GATE_INPUT)); + addInput(createInput(Vec(48, 320), module, ADSR::TRIG_INPUT)); + addOutput(createOutput(Vec(87, 320), module, ADSR::ENVELOPE_OUTPUT)); addChild(createLight>(Vec(94, 41), module, ADSR::ATTACK_LIGHT)); addChild(createLight>(Vec(94, 109), module, ADSR::DECAY_LIGHT)); diff --git a/src/Delay.cpp b/src/Delay.cpp index fc1e9ff..f2477a8 100644 --- a/src/Delay.cpp +++ b/src/Delay.cpp @@ -25,14 +25,20 @@ struct Delay : Module { NUM_OUTPUTS }; - DoubleRingBuffer historyBuffer; - DoubleRingBuffer outBuffer; + dsp::DoubleRingBuffer historyBuffer; + dsp::DoubleRingBuffer outBuffer; SRC_STATE *src; float lastWet = 0.0f; - RCFilter lowpassFilter; - RCFilter highpassFilter; + dsp::RCFilter lowpassFilter; + dsp::RCFilter highpassFilter; + + Delay() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + params[TIME_PARAM].config(0.0f, 1.0f, 0.5f); + params[FEEDBACK_PARAM].config(0.0f, 1.0f, 0.5f); + params[COLOR_PARAM].config(0.0f, 1.0f, 0.5f); + params[MIX_PARAM].config(0.0f, 1.0f, 0.5f); - Delay() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { src = src_new(SRC_SINC_FASTEST, 1, NULL); assert(src); } @@ -41,96 +47,91 @@ struct Delay : Module { src_delete(src); } - void step() override; -}; - - -void Delay::step() { - // 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 dry = in + lastWet * feedback; + void step() 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 dry = in + lastWet * feedback; - // Compute delay time in seconds - float delay = 1e-3 * powf(10.0f / 1e-3, clamp(params[TIME_PARAM].value + inputs[TIME_INPUT].value / 10.0f, 0.0f, 1.0f)); - // Number of delay samples - float index = delay * engineGetSampleRate(); + // 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)); + // Number of delay samples + float index = delay * app()->engine->getSampleRate(); - // Push dry sample into history buffer - if (!historyBuffer.full()) { - historyBuffer.push(dry); - } - - // How many samples do we need consume to catch up? - float consume = index - historyBuffer.size(); + // Push dry sample into history buffer + if (!historyBuffer.full()) { + historyBuffer.push(dry); + } - if (outBuffer.empty()) { - double ratio = 1.f; - if (fabsf(consume) >= 16.f) { - ratio = powf(10.f, clamp(consume / 10000.f, -1.f, 1.f)); + // How many samples do we need consume to catch up? + float consume = index - historyBuffer.size(); + + if (outBuffer.empty()) { + double ratio = 1.f; + if (std::abs(consume) >= 16.f) { + ratio = std::pow(10.f, clamp(consume / 10000.f, -1.f, 1.f)); + } + + SRC_DATA srcData; + srcData.data_in = (const float*) historyBuffer.startData(); + srcData.data_out = (float*) outBuffer.endData(); + srcData.input_frames = std::min((int) historyBuffer.size(), 16); + srcData.output_frames = outBuffer.capacity(); + srcData.end_of_input = false; + srcData.src_ratio = ratio; + src_process(src, &srcData); + historyBuffer.startIncr(srcData.input_frames_used); + outBuffer.endIncr(srcData.output_frames_gen); } - SRC_DATA srcData; - srcData.data_in = (const float*) historyBuffer.startData(); - srcData.data_out = (float*) outBuffer.endData(); - srcData.input_frames = min(historyBuffer.size(), 16); - srcData.output_frames = outBuffer.capacity(); - srcData.end_of_input = false; - srcData.src_ratio = ratio; - src_process(src, &srcData); - historyBuffer.startIncr(srcData.input_frames_used); - outBuffer.endIncr(srcData.output_frames_gen); - } + float wet = 0.0f; + if (!outBuffer.empty()) { + wet = outBuffer.shift(); + } - float wet = 0.0f; - if (!outBuffer.empty()) { - wet = outBuffer.shift(); + // 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 lowpassFreq = 10000.0f * std::pow(10.0f, clamp(2.0f*color, 0.0f, 1.0f)); + lowpassFilter.setCutoff(lowpassFreq / app()->engine->getSampleRate()); + lowpassFilter.process(wet); + wet = lowpassFilter.lowpass(); + float highpassFreq = 10.0f * std::pow(100.0f, clamp(2.0f*color - 1.0f, 0.0f, 1.0f)); + highpassFilter.setCutoff(highpassFreq / app()->engine->getSampleRate()); + highpassFilter.process(wet); + wet = highpassFilter.highpass(); + + lastWet = wet; + + float mix = clamp(params[MIX_PARAM].value + inputs[MIX_INPUT].value / 10.0f, 0.0f, 1.0f); + float out = crossfade(in, wet, mix); + outputs[OUT_OUTPUT].value = out; } - - // 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 lowpassFreq = 10000.0f * powf(10.0f, clamp(2.0f*color, 0.0f, 1.0f)); - lowpassFilter.setCutoff(lowpassFreq / engineGetSampleRate()); - lowpassFilter.process(wet); - wet = lowpassFilter.lowpass(); - float highpassFreq = 10.0f * powf(100.0f, clamp(2.0f*color - 1.0f, 0.0f, 1.0f)); - highpassFilter.setCutoff(highpassFreq / engineGetSampleRate()); - highpassFilter.process(wet); - wet = highpassFilter.highpass(); - - lastWet = wet; - - float mix = clamp(params[MIX_PARAM].value + inputs[MIX_INPUT].value / 10.0f, 0.0f, 1.0f); - float out = crossfade(in, wet, mix); - outputs[OUT_OUTPUT].value = out; -} +}; struct DelayWidget : ModuleWidget { - DelayWidget(Delay *module); + DelayWidget(Delay *module) : ModuleWidget(module) { + setPanel(SVG::load(asset::plugin(plugin, "res/Delay.svg"))); + + addChild(createWidget(Vec(15, 0))); + addChild(createWidget(Vec(box.size.x-30, 0))); + addChild(createWidget(Vec(15, 365))); + addChild(createWidget(Vec(box.size.x-30, 365))); + + addParam(createParam(Vec(67, 57), module, Delay::TIME_PARAM)); + addParam(createParam(Vec(67, 123), module, Delay::FEEDBACK_PARAM)); + addParam(createParam(Vec(67, 190), module, Delay::COLOR_PARAM)); + addParam(createParam(Vec(67, 257), module, Delay::MIX_PARAM)); + + addInput(createInput(Vec(14, 63), module, Delay::TIME_INPUT)); + addInput(createInput(Vec(14, 129), module, Delay::FEEDBACK_INPUT)); + addInput(createInput(Vec(14, 196), module, Delay::COLOR_INPUT)); + addInput(createInput(Vec(14, 263), module, Delay::MIX_INPUT)); + addInput(createInput(Vec(14, 320), module, Delay::IN_INPUT)); + addOutput(createOutput(Vec(73, 320), module, Delay::OUT_OUTPUT)); + } }; -DelayWidget::DelayWidget(Delay *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/Delay.svg"))); - - addChild(createWidget(Vec(15, 0))); - addChild(createWidget(Vec(box.size.x-30, 0))); - addChild(createWidget(Vec(15, 365))); - addChild(createWidget(Vec(box.size.x-30, 365))); - - addParam(createParam(Vec(67, 57), module, Delay::TIME_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(67, 123), module, Delay::FEEDBACK_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(67, 190), module, Delay::COLOR_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(67, 257), module, Delay::MIX_PARAM, 0.0f, 1.0f, 0.5f)); - - addInput(createPort(Vec(14, 63), PortWidget::INPUT, module, Delay::TIME_INPUT)); - addInput(createPort(Vec(14, 129), PortWidget::INPUT, module, Delay::FEEDBACK_INPUT)); - addInput(createPort(Vec(14, 196), PortWidget::INPUT, module, Delay::COLOR_INPUT)); - addInput(createPort(Vec(14, 263), PortWidget::INPUT, module, Delay::MIX_INPUT)); - addInput(createPort(Vec(14, 320), PortWidget::INPUT, module, Delay::IN_INPUT)); - addOutput(createPort(Vec(73, 320), PortWidget::OUTPUT, module, Delay::OUT_OUTPUT)); -} - Model *modelDelay = createModel("Delay"); diff --git a/src/Fundamental.cpp b/src/Fundamental.cpp index e096a6a..5671e48 100644 --- a/src/Fundamental.cpp +++ b/src/Fundamental.cpp @@ -5,8 +5,6 @@ Plugin *plugin; void init(rack::Plugin *p) { plugin = p; - p->slug = TOSTRING(SLUG); - p->version = TOSTRING(VERSION); p->addModel(modelVCO); p->addModel(modelVCO2); diff --git a/src/Fundamental.hpp b/src/Fundamental.hpp index 378decc..3d853a7 100644 --- a/src/Fundamental.hpp +++ b/src/Fundamental.hpp @@ -1,4 +1,5 @@ -#include "rack0.hpp" +#include "rack.hpp" +#include "componentlibrary.hpp" using namespace rack; diff --git a/src/LFO.cpp b/src/LFO.cpp index b1b6d65..be939d0 100644 --- a/src/LFO.cpp +++ b/src/LFO.cpp @@ -2,63 +2,63 @@ struct LowFrequencyOscillator { - float phase = 0.0f; + float phase = 0.f; float pw = 0.5f; - float freq = 1.0f; + float freq = 1.f; bool offset = false; bool invert = false; - SchmittTrigger resetTrigger; + dsp::SchmittTrigger resetTrigger; LowFrequencyOscillator() {} void setPitch(float pitch) { - pitch = fminf(pitch, 10.0f); - freq = powf(2.0f, pitch); + pitch = fminf(pitch, 10.f); + freq = powf(2.f, pitch); } void setPulseWidth(float pw_) { const float pwMin = 0.01f; - pw = clamp(pw_, pwMin, 1.0f - pwMin); + pw = clamp(pw_, pwMin, 1.f - pwMin); } void setReset(float reset) { if (resetTrigger.process(reset / 0.01f)) { - phase = 0.0f; + phase = 0.f; } } void step(float dt) { float deltaPhase = fminf(freq * dt, 0.5f); phase += deltaPhase; - if (phase >= 1.0f) - phase -= 1.0f; + if (phase >= 1.f) + phase -= 1.f; } float sin() { if (offset) - return 1.0f - cosf(2*M_PI * phase) * (invert ? -1.0f : 1.0f); + return 1.f - std::cos(2*M_PI * phase) * (invert ? -1.f : 1.f); else - return sinf(2*M_PI * phase) * (invert ? -1.0f : 1.0f); + return std::sin(2*M_PI * phase) * (invert ? -1.f : 1.f); } float tri(float x) { - return 4.0f * fabsf(x - roundf(x)); + return 4.f * std::abs(x - std::round(x)); } float tri() { if (offset) return tri(invert ? phase - 0.5f : phase); else - return -1.0f + tri(invert ? phase - 0.25f : phase - 0.75f); + return -1.f + tri(invert ? phase - 0.25f : phase - 0.75f); } float saw(float x) { - return 2.0f * (x - roundf(x)); + return 2.f * (x - std::round(x)); } float saw() { if (offset) - return invert ? 2.0f * (1.0f - phase) : 2.0f * phase; + return invert ? 2.f * (1.f - phase) : 2.f * phase; else - return saw(phase) * (invert ? -1.0f : 1.0f); + return saw(phase) * (invert ? -1.f : 1.f); } float sqr() { - float sqr = (phase < pw) ^ invert ? 1.0f : -1.0f; - return offset ? sqr + 1.0f : sqr; + float sqr = (phase < pw) ^ invert ? 1.f : -1.f; + return offset ? sqr + 1.f : sqr; } float light() { - return sinf(2*M_PI * phase); + return std::sin(2*M_PI * phase); } }; @@ -96,27 +96,36 @@ struct LFO : Module { LowFrequencyOscillator oscillator; - LFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; - + LFO() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[OFFSET_PARAM].config(0.f, 1.f, 1.f); + params[INVERT_PARAM].config(0.f, 1.f, 1.f); + params[FREQ_PARAM].config(-8.f, 10.f, 1.f); + params[FM1_PARAM].config(0.f, 1.f, 0.f); + params[PW_PARAM].config(0.f, 1.f, 0.5f); + params[FM2_PARAM].config(0.f, 1.f, 0.f); + params[PWM_PARAM].config(0.f, 1.f, 0.f); + } -void LFO::step() { - 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.0f); - oscillator.offset = (params[OFFSET_PARAM].value > 0.0f); - oscillator.invert = (params[INVERT_PARAM].value <= 0.0f); - oscillator.step(engineGetSampleTime()); - oscillator.setReset(inputs[RESET_INPUT].value); + void step() 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.step(app()->engine->getSampleTime()); + oscillator.setReset(inputs[RESET_INPUT].value); + + 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(); + + lights[PHASE_POS_LIGHT].setBrightnessSmooth(std::max(0.f, oscillator.light())); + lights[PHASE_NEG_LIGHT].setBrightnessSmooth(std::max(0.f, -oscillator.light())); + } - outputs[SIN_OUTPUT].value = 5.0f * oscillator.sin(); - outputs[TRI_OUTPUT].value = 5.0f * oscillator.tri(); - outputs[SAW_OUTPUT].value = 5.0f * oscillator.saw(); - outputs[SQR_OUTPUT].value = 5.0f * oscillator.sqr(); +}; - lights[PHASE_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0f, oscillator.light())); - lights[PHASE_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0f, -oscillator.light())); -} struct LFOWidget : ModuleWidget { @@ -124,31 +133,31 @@ struct LFOWidget : ModuleWidget { }; LFOWidget::LFOWidget(LFO *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/LFO-1.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/LFO-1.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x-30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x-30, 365))); - addParam(createParam(Vec(15, 77), module, LFO::OFFSET_PARAM, 0.0f, 1.0f, 1.0f)); - addParam(createParam(Vec(119, 77), module, LFO::INVERT_PARAM, 0.0f, 1.0f, 1.0f)); + addParam(createParam(Vec(15, 77), module, LFO::OFFSET_PARAM)); + addParam(createParam(Vec(119, 77), module, LFO::INVERT_PARAM)); - addParam(createParam(Vec(47, 61), module, LFO::FREQ_PARAM, -8.0f, 10.0f, 1.0f)); - addParam(createParam(Vec(23, 143), module, LFO::FM1_PARAM, 0.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(91, 143), module, LFO::PW_PARAM, 0.0f, 1.0f, 0.5f)); - addParam(createParam(Vec(23, 208), module, LFO::FM2_PARAM, 0.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(91, 208), module, LFO::PWM_PARAM, 0.0f, 1.0f, 0.0f)); + addParam(createParam(Vec(47, 61), module, LFO::FREQ_PARAM)); + addParam(createParam(Vec(23, 143), module, LFO::FM1_PARAM)); + addParam(createParam(Vec(91, 143), module, LFO::PW_PARAM)); + addParam(createParam(Vec(23, 208), module, LFO::FM2_PARAM)); + addParam(createParam(Vec(91, 208), module, LFO::PWM_PARAM)); - addInput(createPort(Vec(11, 276), PortWidget::INPUT, module, LFO::FM1_INPUT)); - addInput(createPort(Vec(45, 276), PortWidget::INPUT, module, LFO::FM2_INPUT)); - addInput(createPort(Vec(80, 276), PortWidget::INPUT, module, LFO::RESET_INPUT)); - addInput(createPort(Vec(114, 276), PortWidget::INPUT, module, LFO::PW_INPUT)); + addInput(createInput(Vec(11, 276), module, LFO::FM1_INPUT)); + addInput(createInput(Vec(45, 276), module, LFO::FM2_INPUT)); + addInput(createInput(Vec(80, 276), module, LFO::RESET_INPUT)); + addInput(createInput(Vec(114, 276), module, LFO::PW_INPUT)); - addOutput(createPort(Vec(11, 320), PortWidget::OUTPUT, module, LFO::SIN_OUTPUT)); - addOutput(createPort(Vec(45, 320), PortWidget::OUTPUT, module, LFO::TRI_OUTPUT)); - addOutput(createPort(Vec(80, 320), PortWidget::OUTPUT, module, LFO::SAW_OUTPUT)); - addOutput(createPort(Vec(114, 320), PortWidget::OUTPUT, module, LFO::SQR_OUTPUT)); + addOutput(createOutput(Vec(11, 320), module, LFO::SIN_OUTPUT)); + addOutput(createOutput(Vec(45, 320), module, LFO::TRI_OUTPUT)); + addOutput(createOutput(Vec(80, 320), module, LFO::SAW_OUTPUT)); + addOutput(createOutput(Vec(114, 320), module, LFO::SQR_OUTPUT)); addChild(createLight>(Vec(99, 42.5f), module, LFO::PHASE_POS_LIGHT)); } @@ -184,32 +193,37 @@ struct LFO2 : Module { LowFrequencyOscillator oscillator; - LFO2() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; -}; + LFO2() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[OFFSET_PARAM].config(0.f, 1.f, 1.f); + params[INVERT_PARAM].config(0.f, 1.f, 1.f); + params[FREQ_PARAM].config(-8.f, 10.f, 1.f); + params[WAVE_PARAM].config(0.f, 3.f, 1.5f); + params[FM_PARAM].config(0.f, 1.f, 0.5f); + } + void step() override { + 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.step(app()->engine->getSampleTime()); + oscillator.setReset(inputs[RESET_INPUT].value); + + float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value; + wave = clamp(wave, 0.f, 3.f); + float interp; + if (wave < 1.f) + interp = crossfade(oscillator.sin(), oscillator.tri(), wave); + else if (wave < 2.f) + 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; -void LFO2::step() { - oscillator.setPitch(params[FREQ_PARAM].value + params[FM_PARAM].value * inputs[FM_INPUT].value); - oscillator.offset = (params[OFFSET_PARAM].value > 0.0f); - oscillator.invert = (params[INVERT_PARAM].value <= 0.0f); - oscillator.step(engineGetSampleTime()); - oscillator.setReset(inputs[RESET_INPUT].value); - - float wave = params[WAVE_PARAM].value + inputs[WAVE_INPUT].value; - wave = clamp(wave, 0.0f, 3.0f); - float interp; - if (wave < 1.0f) - interp = crossfade(oscillator.sin(), oscillator.tri(), wave); - else if (wave < 2.0f) - interp = crossfade(oscillator.tri(), oscillator.saw(), wave - 1.0f); - else - interp = crossfade(oscillator.saw(), oscillator.sqr(), wave - 2.0f); - outputs[INTERP_OUTPUT].value = 5.0f * interp; - - lights[PHASE_POS_LIGHT].setBrightnessSmooth(fmaxf(0.0f, oscillator.light())); - lights[PHASE_NEG_LIGHT].setBrightnessSmooth(fmaxf(0.0f, -oscillator.light())); -} + lights[PHASE_POS_LIGHT].setBrightnessSmooth(std::max(0.f, oscillator.light())); + lights[PHASE_NEG_LIGHT].setBrightnessSmooth(std::max(0.f, -oscillator.light())); + } +}; struct LFO2Widget : ModuleWidget { @@ -217,25 +231,25 @@ struct LFO2Widget : ModuleWidget { }; LFO2Widget::LFO2Widget(LFO2 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/LFO-2.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/LFO-2.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x-30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x-30, 365))); - addParam(createParam(Vec(62, 150), module, LFO2::OFFSET_PARAM, 0.0f, 1.0f, 1.0f)); - addParam(createParam(Vec(62, 215), module, LFO2::INVERT_PARAM, 0.0f, 1.0f, 1.0f)); + addParam(createParam(Vec(62, 150), module, LFO2::OFFSET_PARAM)); + addParam(createParam(Vec(62, 215), module, LFO2::INVERT_PARAM)); - addParam(createParam(Vec(18, 60), module, LFO2::FREQ_PARAM, -8.0f, 10.0f, 1.0f)); - addParam(createParam(Vec(11, 142), module, LFO2::WAVE_PARAM, 0.0f, 3.0f, 1.5f)); - addParam(createParam(Vec(11, 207), module, LFO2::FM_PARAM, 0.0f, 1.0f, 0.5f)); + addParam(createParam(Vec(18, 60), module, LFO2::FREQ_PARAM)); + addParam(createParam(Vec(11, 142), module, LFO2::WAVE_PARAM)); + addParam(createParam(Vec(11, 207), module, LFO2::FM_PARAM)); - addInput(createPort(Vec(11, 276), PortWidget::INPUT, module, LFO2::FM_INPUT)); - addInput(createPort(Vec(54, 276), PortWidget::INPUT, module, LFO2::RESET_INPUT)); - addInput(createPort(Vec(11, 319), PortWidget::INPUT, module, LFO2::WAVE_INPUT)); + addInput(createInput(Vec(11, 276), module, LFO2::FM_INPUT)); + addInput(createInput(Vec(54, 276), module, LFO2::RESET_INPUT)); + addInput(createInput(Vec(11, 319), module, LFO2::WAVE_INPUT)); - addOutput(createPort(Vec(54, 319), PortWidget::OUTPUT, module, LFO2::INTERP_OUTPUT)); + addOutput(createOutput(Vec(54, 319), module, LFO2::INTERP_OUTPUT)); addChild(createLight>(Vec(68, 42.5f), module, LFO2::PHASE_POS_LIGHT)); } diff --git a/src/Mutes.cpp b/src/Mutes.cpp index 3e3ee8c..203f049 100644 --- a/src/Mutes.cpp +++ b/src/Mutes.cpp @@ -23,12 +23,28 @@ struct Mutes : Module { }; bool state[NUM_CHANNELS]; - SchmittTrigger muteTrigger[NUM_CHANNELS]; + dsp::SchmittTrigger muteTrigger[NUM_CHANNELS]; + + Mutes() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + for (int i = 0; i < NUM_CHANNELS; i++) { + params[MUTE_PARAM + i].config(0.0, 1.0, 0.0, string::f("Ch %d mute", i)); + } - Mutes() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { onReset(); } - void step() override; + + void step() override { + float out = 0.f; + for (int i = 0; i < NUM_CHANNELS; i++) { + if (muteTrigger[i].process(params[MUTE_PARAM + i].value)) + 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; + lights[MUTE_LIGHT + i].setBrightness(state[i] ? 0.9f : 0.f); + } + } void onReset() override { for (int i = 0; i < NUM_CHANNELS; i++) { @@ -37,7 +53,7 @@ struct Mutes : Module { } void onRandomize() override { for (int i = 0; i < NUM_CHANNELS; i++) { - state[i] = (randomUniform() < 0.5f); + state[i] = (random::uniform() < 0.5f); } } @@ -52,6 +68,7 @@ struct Mutes : Module { json_object_set_new(rootJ, "states", statesJ); return rootJ; } + void dataFromJson(json_t *rootJ) override { // states json_t *statesJ = json_object_get(rootJ, "states"); @@ -65,23 +82,11 @@ struct Mutes : Module { } }; -void Mutes::step() { - float out = 0.0f; - for (int i = 0; i < NUM_CHANNELS; i++) { - if (muteTrigger[i].process(params[MUTE_PARAM + i].value)) - state[i] ^= true; - if (inputs[IN_INPUT + i].active) - out = inputs[IN_INPUT + i].value; - outputs[OUT_OUTPUT + i].value = state[i] ? out : 0.0f; - lights[MUTE_LIGHT + i].setBrightness(state[i] ? 0.9f : 0.0f); - } -} - template struct MuteLight : BASE { MuteLight() { - this->box.size = mm2px(Vec(6.0f, 6.0f)); + this->box.size = mm2px(Vec(6.f, 6.f)); } }; @@ -91,45 +96,45 @@ struct MutesWidget : ModuleWidget { }; MutesWidget::MutesWidget(Mutes *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/Mutes.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/Mutes.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x - 30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x - 30, 365))); - addParam(createParam(mm2px(Vec(16.57, 18.165)), module, Mutes::MUTE_PARAM + 0, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 28.164)), module, Mutes::MUTE_PARAM + 1, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 38.164)), module, Mutes::MUTE_PARAM + 2, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 48.165)), module, Mutes::MUTE_PARAM + 3, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 58.164)), module, Mutes::MUTE_PARAM + 4, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 68.165)), module, Mutes::MUTE_PARAM + 5, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 78.164)), module, Mutes::MUTE_PARAM + 6, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 88.164)), module, Mutes::MUTE_PARAM + 7, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 98.165)), module, Mutes::MUTE_PARAM + 8, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(16.57, 108.166)), module, Mutes::MUTE_PARAM + 9, 0.0f, 1.0f, 0.0f)); - - addInput(createPort(mm2px(Vec(4.214, 17.81)), PortWidget::INPUT, module, Mutes::IN_INPUT + 0)); - addInput(createPort(mm2px(Vec(4.214, 27.809)), PortWidget::INPUT, module, Mutes::IN_INPUT + 1)); - addInput(createPort(mm2px(Vec(4.214, 37.809)), PortWidget::INPUT, module, Mutes::IN_INPUT + 2)); - addInput(createPort(mm2px(Vec(4.214, 47.81)), PortWidget::INPUT, module, Mutes::IN_INPUT + 3)); - addInput(createPort(mm2px(Vec(4.214, 57.81)), PortWidget::INPUT, module, Mutes::IN_INPUT + 4)); - addInput(createPort(mm2px(Vec(4.214, 67.809)), PortWidget::INPUT, module, Mutes::IN_INPUT + 5)); - addInput(createPort(mm2px(Vec(4.214, 77.81)), PortWidget::INPUT, module, Mutes::IN_INPUT + 6)); - addInput(createPort(mm2px(Vec(4.214, 87.81)), PortWidget::INPUT, module, Mutes::IN_INPUT + 7)); - addInput(createPort(mm2px(Vec(4.214, 97.809)), PortWidget::INPUT, module, Mutes::IN_INPUT + 8)); - addInput(createPort(mm2px(Vec(4.214, 107.809)), PortWidget::INPUT, module, Mutes::IN_INPUT + 9)); - - addOutput(createPort(mm2px(Vec(28.214, 17.81)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 0)); - addOutput(createPort(mm2px(Vec(28.214, 27.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 1)); - addOutput(createPort(mm2px(Vec(28.214, 37.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 2)); - addOutput(createPort(mm2px(Vec(28.214, 47.81)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 3)); - addOutput(createPort(mm2px(Vec(28.214, 57.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 4)); - addOutput(createPort(mm2px(Vec(28.214, 67.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 5)); - addOutput(createPort(mm2px(Vec(28.214, 77.81)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 6)); - addOutput(createPort(mm2px(Vec(28.214, 87.81)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 7)); - addOutput(createPort(mm2px(Vec(28.214, 97.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 8)); - addOutput(createPort(mm2px(Vec(28.214, 107.809)), PortWidget::OUTPUT, module, Mutes::OUT_OUTPUT + 9)); + addParam(createParam(mm2px(Vec(16.57, 18.165)), module, Mutes::MUTE_PARAM + 0)); + addParam(createParam(mm2px(Vec(16.57, 28.164)), module, Mutes::MUTE_PARAM + 1)); + addParam(createParam(mm2px(Vec(16.57, 38.164)), module, Mutes::MUTE_PARAM + 2)); + addParam(createParam(mm2px(Vec(16.57, 48.165)), module, Mutes::MUTE_PARAM + 3)); + addParam(createParam(mm2px(Vec(16.57, 58.164)), module, Mutes::MUTE_PARAM + 4)); + addParam(createParam(mm2px(Vec(16.57, 68.165)), module, Mutes::MUTE_PARAM + 5)); + addParam(createParam(mm2px(Vec(16.57, 78.164)), module, Mutes::MUTE_PARAM + 6)); + addParam(createParam(mm2px(Vec(16.57, 88.164)), module, Mutes::MUTE_PARAM + 7)); + addParam(createParam(mm2px(Vec(16.57, 98.165)), module, Mutes::MUTE_PARAM + 8)); + addParam(createParam(mm2px(Vec(16.57, 108.166)), module, Mutes::MUTE_PARAM + 9)); + + addInput(createInput(mm2px(Vec(4.214, 17.81)), module, Mutes::IN_INPUT + 0)); + addInput(createInput(mm2px(Vec(4.214, 27.809)), module, Mutes::IN_INPUT + 1)); + addInput(createInput(mm2px(Vec(4.214, 37.809)), module, Mutes::IN_INPUT + 2)); + addInput(createInput(mm2px(Vec(4.214, 47.81)), module, Mutes::IN_INPUT + 3)); + addInput(createInput(mm2px(Vec(4.214, 57.81)), module, Mutes::IN_INPUT + 4)); + addInput(createInput(mm2px(Vec(4.214, 67.809)), module, Mutes::IN_INPUT + 5)); + addInput(createInput(mm2px(Vec(4.214, 77.81)), module, Mutes::IN_INPUT + 6)); + addInput(createInput(mm2px(Vec(4.214, 87.81)), module, Mutes::IN_INPUT + 7)); + addInput(createInput(mm2px(Vec(4.214, 97.809)), module, Mutes::IN_INPUT + 8)); + addInput(createInput(mm2px(Vec(4.214, 107.809)), module, Mutes::IN_INPUT + 9)); + + addOutput(createOutput(mm2px(Vec(28.214, 17.81)), module, Mutes::OUT_OUTPUT + 0)); + addOutput(createOutput(mm2px(Vec(28.214, 27.809)), module, Mutes::OUT_OUTPUT + 1)); + addOutput(createOutput(mm2px(Vec(28.214, 37.809)), module, Mutes::OUT_OUTPUT + 2)); + addOutput(createOutput(mm2px(Vec(28.214, 47.81)), module, Mutes::OUT_OUTPUT + 3)); + addOutput(createOutput(mm2px(Vec(28.214, 57.809)), module, Mutes::OUT_OUTPUT + 4)); + addOutput(createOutput(mm2px(Vec(28.214, 67.809)), module, Mutes::OUT_OUTPUT + 5)); + addOutput(createOutput(mm2px(Vec(28.214, 77.81)), module, Mutes::OUT_OUTPUT + 6)); + addOutput(createOutput(mm2px(Vec(28.214, 87.81)), module, Mutes::OUT_OUTPUT + 7)); + addOutput(createOutput(mm2px(Vec(28.214, 97.809)), module, Mutes::OUT_OUTPUT + 8)); + addOutput(createOutput(mm2px(Vec(28.214, 107.809)), module, Mutes::OUT_OUTPUT + 9)); addChild(createLight>(mm2px(Vec(17.32, 18.915)), module, Mutes::MUTE_LIGHT + 0)); addChild(createLight>(mm2px(Vec(17.32, 28.916)), module, Mutes::MUTE_LIGHT + 1)); diff --git a/src/SEQ3.cpp b/src/SEQ3.cpp index b612af4..55dab2d 100644 --- a/src/SEQ3.cpp +++ b/src/SEQ3.cpp @@ -38,16 +38,29 @@ struct SEQ3 : Module { }; bool running = true; - SchmittTrigger clockTrigger; - SchmittTrigger runningTrigger; - SchmittTrigger resetTrigger; - SchmittTrigger gateTriggers[8]; + dsp::SchmittTrigger clockTrigger; + dsp::SchmittTrigger runningTrigger; + dsp::SchmittTrigger resetTrigger; + dsp::SchmittTrigger gateTriggers[8]; /** Phase of internal LFO */ float phase = 0.f; int index = 0; bool gates[8] = {}; - SEQ3() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { + SEQ3() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[CLOCK_PARAM].config(-2.0f, 6.0f, 2.0f); + params[RUN_PARAM].config(0.0f, 1.0f, 0.0f); + params[RESET_PARAM].config(0.0f, 1.0f, 0.0f); + params[STEPS_PARAM].config(1.0f, 8.0f, 8.0f); + for (int i = 0; i < 8; i++) { + params[ROW1_PARAM + i].config(0.0f, 10.0f, 0.0f); + params[ROW2_PARAM + i].config(0.0f, 10.0f, 0.0f); + params[ROW3_PARAM + i].config(0.0f, 10.0f, 0.0f); + params[GATE_PARAM + i].config(0.0f, 1.0f, 0.0f); + } + + onReset(); } @@ -59,7 +72,7 @@ struct SEQ3 : Module { void onRandomize() override { for (int i = 0; i < 8; i++) { - gates[i] = (randomUniform() > 0.5f); + gates[i] = (random::uniform() > 0.5f); } } @@ -97,7 +110,7 @@ struct SEQ3 : Module { } void setIndex(int index) { - int numSteps = (int) clamp(roundf(params[STEPS_PARAM].value + inputs[STEPS_INPUT].value), 1.0f, 8.0f); + int numSteps = (int) clamp(std::round(params[STEPS_PARAM].value + inputs[STEPS_INPUT].value), 1.0f, 8.0f); phase = 0.f; this->index = index; if (this->index >= numSteps) @@ -121,8 +134,8 @@ struct SEQ3 : Module { } else { // Internal clock - float clockTime = powf(2.0f, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value); - phase += clockTime * engineGetSampleTime(); + float clockTime = std::pow(2.0f, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value); + phase += clockTime * app()->engine->getSampleTime(); if (phase >= 1.0f) { setIndex(index + 1); } @@ -161,41 +174,41 @@ struct SEQ3 : Module { struct SEQ3Widget : ModuleWidget { SEQ3Widget(SEQ3 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/SEQ3.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/SEQ3.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x-30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x-30, 365))); - addParam(createParam(Vec(18, 56), module, SEQ3::CLOCK_PARAM, -2.0f, 6.0f, 2.0f)); - addParam(createParam(Vec(60, 61-1), module, SEQ3::RUN_PARAM, 0.0f, 1.0f, 0.0f)); + addParam(createParam(Vec(18, 56), module, SEQ3::CLOCK_PARAM)); + addParam(createParam(Vec(60, 61-1), module, SEQ3::RUN_PARAM)); addChild(createLight>(Vec(64.4f, 64.4f), module, SEQ3::RUNNING_LIGHT)); - addParam(createParam(Vec(99, 61-1), module, SEQ3::RESET_PARAM, 0.0f, 1.0f, 0.0f)); + addParam(createParam(Vec(99, 61-1), module, SEQ3::RESET_PARAM)); addChild(createLight>(Vec(103.4f, 64.4f), module, SEQ3::RESET_LIGHT)); - addParam(createParam(Vec(132, 56), module, SEQ3::STEPS_PARAM, 1.0f, 8.0f, 8.0f)); + addParam(createParam(Vec(132, 56), module, SEQ3::STEPS_PARAM)); addChild(createLight>(Vec(179.4f, 64.4f), module, SEQ3::GATES_LIGHT)); addChild(createLight>(Vec(218.4f, 64.4f), module, SEQ3::ROW_LIGHTS)); addChild(createLight>(Vec(256.4f, 64.4f), module, SEQ3::ROW_LIGHTS + 1)); addChild(createLight>(Vec(295.4f, 64.4f), module, SEQ3::ROW_LIGHTS + 2)); static const float portX[8] = {20, 58, 96, 135, 173, 212, 250, 289}; - addInput(createPort(Vec(portX[0]-1, 98), PortWidget::INPUT, module, SEQ3::CLOCK_INPUT)); - addInput(createPort(Vec(portX[1]-1, 98), PortWidget::INPUT, module, SEQ3::EXT_CLOCK_INPUT)); - addInput(createPort(Vec(portX[2]-1, 98), PortWidget::INPUT, module, SEQ3::RESET_INPUT)); - addInput(createPort(Vec(portX[3]-1, 98), PortWidget::INPUT, module, SEQ3::STEPS_INPUT)); - addOutput(createPort(Vec(portX[4]-1, 98), PortWidget::OUTPUT, module, SEQ3::GATES_OUTPUT)); - addOutput(createPort(Vec(portX[5]-1, 98), PortWidget::OUTPUT, module, SEQ3::ROW1_OUTPUT)); - addOutput(createPort(Vec(portX[6]-1, 98), PortWidget::OUTPUT, module, SEQ3::ROW2_OUTPUT)); - addOutput(createPort(Vec(portX[7]-1, 98), PortWidget::OUTPUT, module, SEQ3::ROW3_OUTPUT)); + addInput(createInput(Vec(portX[0]-1, 98), module, SEQ3::CLOCK_INPUT)); + addInput(createInput(Vec(portX[1]-1, 98), module, SEQ3::EXT_CLOCK_INPUT)); + addInput(createInput(Vec(portX[2]-1, 98), module, SEQ3::RESET_INPUT)); + addInput(createInput(Vec(portX[3]-1, 98), module, SEQ3::STEPS_INPUT)); + addOutput(createOutput(Vec(portX[4]-1, 98), module, SEQ3::GATES_OUTPUT)); + addOutput(createOutput(Vec(portX[5]-1, 98), module, SEQ3::ROW1_OUTPUT)); + addOutput(createOutput(Vec(portX[6]-1, 98), module, SEQ3::ROW2_OUTPUT)); + addOutput(createOutput(Vec(portX[7]-1, 98), module, SEQ3::ROW3_OUTPUT)); for (int i = 0; i < 8; i++) { - addParam(createParam(Vec(portX[i]-2, 157), module, SEQ3::ROW1_PARAM + i, 0.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(portX[i]-2, 198), module, SEQ3::ROW2_PARAM + i, 0.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(portX[i]-2, 240), module, SEQ3::ROW3_PARAM + i, 0.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(portX[i]+2, 278-1), module, SEQ3::GATE_PARAM + i, 0.0f, 1.0f, 0.0f)); + addParam(createParam(Vec(portX[i]-2, 157), module, SEQ3::ROW1_PARAM + i)); + addParam(createParam(Vec(portX[i]-2, 198), module, SEQ3::ROW2_PARAM + i)); + addParam(createParam(Vec(portX[i]-2, 240), module, SEQ3::ROW3_PARAM + i)); + addParam(createParam(Vec(portX[i]+2, 278-1), module, SEQ3::GATE_PARAM + i)); addChild(createLight>(Vec(portX[i]+6.4f, 281.4f), module, SEQ3::GATE_LIGHTS + i)); - addOutput(createPort(Vec(portX[i]-1, 307), PortWidget::OUTPUT, module, SEQ3::GATE_OUTPUT + i)); + addOutput(createOutput(Vec(portX[i]-1, 307), module, SEQ3::GATE_OUTPUT + i)); } } }; diff --git a/src/Scope.cpp b/src/Scope.cpp index 7be2f65..37cc0b1 100644 --- a/src/Scope.cpp +++ b/src/Scope.cpp @@ -2,7 +2,8 @@ #include "Fundamental.hpp" -#define BUFFER_SIZE 512 +static const int BUFFER_SIZE = 512; + struct Scope : Module { enum ParamIds { @@ -38,14 +39,82 @@ struct Scope : Module { int bufferIndex = 0; float frameIndex = 0; - SchmittTrigger sumTrigger; - SchmittTrigger extTrigger; + dsp::SchmittTrigger sumTrigger; + dsp::SchmittTrigger extTrigger; bool lissajous = false; bool external = false; - SchmittTrigger resetTrigger; + dsp::SchmittTrigger resetTrigger; + + Scope() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[X_SCALE_PARAM].config(-2.0f, 8.0f, 0.0f); + params[X_POS_PARAM].config(-10.0f, 10.0f, 0.0f); + params[Y_SCALE_PARAM].config(-2.0f, 8.0f, 0.0f); + params[Y_POS_PARAM].config(-10.0f, 10.0f, 0.0f); + params[TIME_PARAM].config(6.0f, 16.0f, 14.0f); + params[LISSAJOUS_PARAM].config(0.0f, 1.0f, 0.0f); + params[TRIG_PARAM].config(-10.0f, 10.0f, 0.0f); + params[EXTERNAL_PARAM].config(0.0f, 1.0f, 0.0f); + } + + void step() override { + // Modes + if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { + 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)) { + 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); + int frameCount = (int) std::ceil(deltaTime * app()->engine->getSampleRate()); + + // 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; + bufferIndex++; + } + } - Scope() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; + // Are we waiting on the next trigger? + if (bufferIndex >= BUFFER_SIZE) { + // Trigger immediately if external but nothing plugged in, or in Lissajous mode + if (lissajous || (external && !inputs[TRIG_INPUT].active)) { + bufferIndex = 0; + frameIndex = 0; + return; + } + + // Reset the Schmitt trigger so we don't trigger immediately if the input is high + if (frameIndex == 0) { + resetTrigger.reset(); + } + frameIndex++; + + // Must go below 0.1fV to trigger + float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value; + + // 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 >= app()->engine->getSampleRate() * holdTime)) { + bufferIndex = 0; frameIndex = 0; return; + } + + // Reset if we've waited too long + if (frameIndex >= app()->engine->getSampleRate() * holdTime) { + bufferIndex = 0; frameIndex = 0; return; + } + } + } json_t *dataToJson() override { json_t *rootJ = json_object(); @@ -71,66 +140,6 @@ struct Scope : Module { }; -void Scope::step() { - // Modes - if (sumTrigger.process(params[LISSAJOUS_PARAM].value)) { - 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)) { - 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); - int frameCount = (int) std::ceil(deltaTime * engineGetSampleRate()); - - // 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; - bufferIndex++; - } - } - - // Are we waiting on the next trigger? - if (bufferIndex >= BUFFER_SIZE) { - // Trigger immediately if external but nothing plugged in, or in Lissajous mode - if (lissajous || (external && !inputs[TRIG_INPUT].active)) { - bufferIndex = 0; - frameIndex = 0; - return; - } - - // Reset the Schmitt trigger so we don't trigger immediately if the input is high - if (frameIndex == 0) { - resetTrigger.reset(); - } - frameIndex++; - - // Must go below 0.1fV to trigger - float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value; - - // 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 >= engineGetSampleRate() * holdTime)) { - bufferIndex = 0; frameIndex = 0; return; - } - - // Reset if we've waited too long - if (frameIndex >= engineGetSampleRate() * holdTime) { - bufferIndex = 0; frameIndex = 0; return; - } - } -} - - struct ScopeDisplay : TransparentWidget { Scope *module; int frame = 0; @@ -145,17 +154,17 @@ struct ScopeDisplay : TransparentWidget { for (int i = 0; i < BUFFER_SIZE; i++) { float v = values[i]; vrms += v*v; - vmax = fmaxf(vmax, v); - vmin = fminf(vmin, v); + vmax = std::max(vmax, v); + vmin = std::min(vmin, v); } - vrms = sqrtf(vrms / BUFFER_SIZE); + vrms = std::sqrt(vrms / BUFFER_SIZE); vpp = vmax - vmin; } }; Stats statsX, statsY; ScopeDisplay() { - font = Font::load(assetPlugin(plugin, "res/fonts/Sudo.ttf")); + font = Font::load(asset::plugin(plugin, "res/fonts/Sudo.ttf")); } void drawWaveform(NVGcontext *vg, float *valuesX, float *valuesY) { @@ -306,7 +315,7 @@ struct ScopeWidget : ModuleWidget { }; ScopeWidget::ScopeWidget(Scope *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/Scope.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/Scope.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x-30, 0))); @@ -321,18 +330,18 @@ ScopeWidget::ScopeWidget(Scope *module) : ModuleWidget(module) { addChild(display); } - addParam(createParam(Vec(15, 209), module, Scope::X_SCALE_PARAM, -2.0f, 8.0f, 0.0f)); - addParam(createParam(Vec(15, 263), module, Scope::X_POS_PARAM, -10.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(61, 209), module, Scope::Y_SCALE_PARAM, -2.0f, 8.0f, 0.0f)); - addParam(createParam(Vec(61, 263), module, Scope::Y_POS_PARAM, -10.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(107, 209), module, Scope::TIME_PARAM, 6.0f, 16.0f, 14.0f)); - addParam(createParam(Vec(106, 262), module, Scope::LISSAJOUS_PARAM, 0.0f, 1.0f, 0.0f)); - addParam(createParam(Vec(153, 209), module, Scope::TRIG_PARAM, -10.0f, 10.0f, 0.0f)); - addParam(createParam(Vec(152, 262), module, Scope::EXTERNAL_PARAM, 0.0f, 1.0f, 0.0f)); - - addInput(createPort(Vec(17, 319), PortWidget::INPUT, module, Scope::X_INPUT)); - addInput(createPort(Vec(63, 319), PortWidget::INPUT, module, Scope::Y_INPUT)); - addInput(createPort(Vec(154, 319), PortWidget::INPUT, module, Scope::TRIG_INPUT)); + addParam(createParam(Vec(15, 209), module, Scope::X_SCALE_PARAM)); + addParam(createParam(Vec(15, 263), module, Scope::X_POS_PARAM)); + addParam(createParam(Vec(61, 209), module, Scope::Y_SCALE_PARAM)); + addParam(createParam(Vec(61, 263), module, Scope::Y_POS_PARAM)); + addParam(createParam(Vec(107, 209), module, Scope::TIME_PARAM)); + addParam(createParam(Vec(106, 262), module, Scope::LISSAJOUS_PARAM)); + addParam(createParam(Vec(153, 209), module, Scope::TRIG_PARAM)); + addParam(createParam(Vec(152, 262), module, Scope::EXTERNAL_PARAM)); + + addInput(createInput(Vec(17, 319), module, Scope::X_INPUT)); + addInput(createInput(Vec(63, 319), module, Scope::Y_INPUT)); + addInput(createInput(Vec(154, 319), module, Scope::TRIG_INPUT)); addChild(createLight>(Vec(104, 251), module, Scope::PLOT_LIGHT)); addChild(createLight>(Vec(104, 296), module, Scope::LISSAJOUS_LIGHT)); diff --git a/src/SequentialSwitch.cpp b/src/SequentialSwitch.cpp index 6fa3677..37fc712 100644 --- a/src/SequentialSwitch.cpp +++ b/src/SequentialSwitch.cpp @@ -22,12 +22,15 @@ struct SequentialSwitch : Module { NUM_LIGHTS }; - SchmittTrigger clockTrigger; - SchmittTrigger resetTrigger; + dsp::SchmittTrigger clockTrigger; + dsp::SchmittTrigger resetTrigger; int channel = 0; - SlewLimiter channelFilter[4]; + dsp::SlewLimiter channelFilter[4]; + + SequentialSwitch() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[CHANNELS_PARAM].config(0.0, 2.0, 0.0); - SequentialSwitch() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { for (int i = 0; i < 4; i++) { channelFilter[i].rise = 0.01f; channelFilter[i].fall = 0.01f; @@ -47,7 +50,7 @@ struct SequentialSwitch : Module { // Filter channels for (int i = 0; i < 4; i++) { - channelFilter[i].process(channel == i ? 1.0f : 0.0f); + channelFilter[i].process(channel == i ? 1.f : 0.f); } // Set outputs @@ -58,7 +61,7 @@ struct SequentialSwitch : Module { } } else { - float out = 0.0f; + float out = 0.f; for (int i = 0; i < 4; i++) { out += channelFilter[i].out * inputs[IN_INPUT + i].value; } @@ -79,21 +82,21 @@ struct SequentialSwitch1Widget : ModuleWidget { SequentialSwitch1Widget::SequentialSwitch1Widget(SequentialSwitch<1> *module) : ModuleWidget(module) { typedef SequentialSwitch<1> TSequentialSwitch; - setPanel(SVG::load(assetPlugin(plugin, "res/SequentialSwitch1.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/SequentialSwitch1.svg"))); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); - addParam(createParam(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM, 0.0f, 2.0f, 0.0f)); + addParam(createParam(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM)); - addInput(createPort(mm2px(Vec(3.51398, 17.694)), PortWidget::INPUT, module, TSequentialSwitch::CLOCK_INPUT)); - addInput(createPort(mm2px(Vec(3.51398, 32.1896)), PortWidget::INPUT, module, TSequentialSwitch::RESET_INPUT)); - addInput(createPort(mm2px(Vec(3.51536, 62.8096)), PortWidget::INPUT, module, TSequentialSwitch::IN_INPUT + 0)); + addInput(createInput(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); + addInput(createInput(mm2px(Vec(3.51398, 32.1896)), module, TSequentialSwitch::RESET_INPUT)); + addInput(createInput(mm2px(Vec(3.51536, 62.8096)), module, TSequentialSwitch::IN_INPUT + 0)); - addOutput(createPort(mm2px(Vec(3.51536, 77.8095)), PortWidget::OUTPUT, module, TSequentialSwitch::OUT_OUTPUT + 0)); - addOutput(createPort(mm2px(Vec(3.51398, 87.8113)), PortWidget::OUTPUT, module, TSequentialSwitch::OUT_OUTPUT + 1)); - addOutput(createPort(mm2px(Vec(3.51398, 97.809)), PortWidget::OUTPUT, module, TSequentialSwitch::OUT_OUTPUT + 2)); - addOutput(createPort(mm2px(Vec(3.51398, 107.809)), PortWidget::OUTPUT, module, TSequentialSwitch::OUT_OUTPUT + 3)); + addOutput(createOutput(mm2px(Vec(3.51536, 77.8095)), module, TSequentialSwitch::OUT_OUTPUT + 0)); + addOutput(createOutput(mm2px(Vec(3.51398, 87.8113)), module, TSequentialSwitch::OUT_OUTPUT + 1)); + addOutput(createOutput(mm2px(Vec(3.51398, 97.809)), module, TSequentialSwitch::OUT_OUTPUT + 2)); + addOutput(createOutput(mm2px(Vec(3.51398, 107.809)), module, TSequentialSwitch::OUT_OUTPUT + 3)); addChild(createLight>(mm2px(Vec(10.8203, 77.7158)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); addChild(createLight>(mm2px(Vec(10.8203, 87.7163)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); @@ -111,21 +114,21 @@ struct SequentialSwitch2Widget : ModuleWidget { SequentialSwitch2Widget::SequentialSwitch2Widget(SequentialSwitch<2> *module) : ModuleWidget(module) { typedef SequentialSwitch<2> TSequentialSwitch; - setPanel(SVG::load(assetPlugin(plugin, "res/SequentialSwitch2.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/SequentialSwitch2.svg"))); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); - addParam(createParam(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM, 0.0f, 2.0f, 0.0f)); + addParam(createParam(mm2px(Vec(5.24619, 46.9153)), module, TSequentialSwitch::CHANNELS_PARAM)); - addInput(createPort(mm2px(Vec(3.51398, 17.694)), PortWidget::INPUT, module, TSequentialSwitch::CLOCK_INPUT)); - addInput(createPort(mm2px(Vec(3.51398, 32.191)), PortWidget::INPUT, module, TSequentialSwitch::RESET_INPUT)); - addInput(createPort(mm2px(Vec(3.51398, 62.811)), PortWidget::INPUT, module, TSequentialSwitch::IN_INPUT + 0)); - addInput(createPort(mm2px(Vec(3.51398, 72.8114)), PortWidget::INPUT, module, TSequentialSwitch::IN_INPUT + 1)); - addInput(createPort(mm2px(Vec(3.51398, 82.8091)), PortWidget::INPUT, module, TSequentialSwitch::IN_INPUT + 2)); - addInput(createPort(mm2px(Vec(3.51398, 92.8109)), PortWidget::INPUT, module, TSequentialSwitch::IN_INPUT + 3)); + addInput(createInput(mm2px(Vec(3.51398, 17.694)), module, TSequentialSwitch::CLOCK_INPUT)); + addInput(createInput(mm2px(Vec(3.51398, 32.191)), module, TSequentialSwitch::RESET_INPUT)); + addInput(createInput(mm2px(Vec(3.51398, 62.811)), module, TSequentialSwitch::IN_INPUT + 0)); + addInput(createInput(mm2px(Vec(3.51398, 72.8114)), module, TSequentialSwitch::IN_INPUT + 1)); + addInput(createInput(mm2px(Vec(3.51398, 82.8091)), module, TSequentialSwitch::IN_INPUT + 2)); + addInput(createInput(mm2px(Vec(3.51398, 92.8109)), module, TSequentialSwitch::IN_INPUT + 3)); - addOutput(createPort(mm2px(Vec(3.51398, 107.622)), PortWidget::OUTPUT, module, TSequentialSwitch::OUT_OUTPUT + 0)); + addOutput(createOutput(mm2px(Vec(3.51398, 107.622)), module, TSequentialSwitch::OUT_OUTPUT + 0)); addChild(createLight>(mm2px(Vec(10.7321, 62.6277)), module, TSequentialSwitch::CHANNEL_LIGHT + 0)); addChild(createLight>(mm2px(Vec(10.7321, 72.6281)), module, TSequentialSwitch::CHANNEL_LIGHT + 1)); diff --git a/src/Unity.cpp b/src/Unity.cpp index 3b54174..4be8402 100644 --- a/src/Unity.cpp +++ b/src/Unity.cpp @@ -27,8 +27,50 @@ struct Unity : Module { bool merge = false; - Unity() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} - void step() override; + Unity() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[AVG1_PARAM].config(0.0, 1.0, 0.0); + params[AVG2_PARAM].config(0.0, 1.0, 0.0); + } + + void step() override { + float mix[2] = {}; + int count[2] = {}; + + for (int i = 0; i < 2; i++) { + // Inputs + for (int j = 0; j < 6; j++) { + mix[i] += inputs[IN1_INPUT + 6*i + j].value; + if (inputs[IN1_INPUT + 6*i + j].active) + count[i]++; + } + } + + // Combine + if (merge) { + mix[0] += mix[1]; + mix[1] = mix[0]; + count[0] += count[1]; + count[1] = count[0]; + } + + for (int i = 0; i < 2; i++) { + // Params + if ((int) params[AVG1_PARAM + i].value == 1 && count[i] > 0) + mix[i] /= count[i]; + + // Outputs + outputs[MIX1_OUTPUT + 2*i].value = mix[i]; + outputs[INV1_OUTPUT + 2*i].value = -mix[i]; + // Lights + dsp::VUMeter vuMeter; + vuMeter.dBInterval = 6.0f; + vuMeter.setValue(mix[i] / 10.0f); + for (int j = 0; j < 5; j++) { + lights[VU1_LIGHT + 5*i + j].setBrightnessSmooth(vuMeter.getBrightness(j)); + } + } + } void onReset() override { merge = false; @@ -49,44 +91,6 @@ struct Unity : Module { } }; -void Unity::step() { - float mix[2] = {}; - int count[2] = {}; - - for (int i = 0; i < 2; i++) { - // Inputs - for (int j = 0; j < 6; j++) { - mix[i] += inputs[IN1_INPUT + 6*i + j].value; - if (inputs[IN1_INPUT + 6*i + j].active) - count[i]++; - } - } - - // Combine - if (merge) { - mix[0] += mix[1]; - mix[1] = mix[0]; - count[0] += count[1]; - count[1] = count[0]; - } - - for (int i = 0; i < 2; i++) { - // Params - if ((int) params[AVG1_PARAM + i].value == 1 && count[i] > 0) - mix[i] /= count[i]; - - // Outputs - outputs[MIX1_OUTPUT + 2*i].value = mix[i]; - outputs[INV1_OUTPUT + 2*i].value = -mix[i]; - // Lights - VUMeter vuMeter; - vuMeter.dBInterval = 6.0f; - vuMeter.setValue(mix[i] / 10.0f); - for (int j = 0; j < 5; j++) { - lights[VU1_LIGHT + 5*i + j].setBrightnessSmooth(vuMeter.getBrightness(j)); - } - } -} struct UnityWidget : ModuleWidget { @@ -95,33 +99,33 @@ struct UnityWidget : ModuleWidget { }; UnityWidget::UnityWidget(Unity *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/Unity.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/Unity.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x - 30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x - 30, 365))); - addParam(createParam(mm2px(Vec(12.867, 52.961)), module, Unity::AVG1_PARAM, 0.0f, 1.0f, 0.0f)); - addParam(createParam(mm2px(Vec(12.867, 107.006)), module, Unity::AVG2_PARAM, 0.0f, 1.0f, 0.0f)); - - addInput(createPort(mm2px(Vec(2.361, 17.144)), PortWidget::INPUT, module, Unity::IN1_INPUT + 0)); - addInput(createPort(mm2px(Vec(19.907, 17.144)), PortWidget::INPUT, module, Unity::IN1_INPUT + 1)); - addInput(createPort(mm2px(Vec(2.361, 28.145)), PortWidget::INPUT, module, Unity::IN1_INPUT + 2)); - addInput(createPort(mm2px(Vec(19.907, 28.145)), PortWidget::INPUT, module, Unity::IN1_INPUT + 3)); - addInput(createPort(mm2px(Vec(2.361, 39.145)), PortWidget::INPUT, module, Unity::IN1_INPUT + 4)); - addInput(createPort(mm2px(Vec(19.907, 39.145)), PortWidget::INPUT, module, Unity::IN1_INPUT + 5)); - addInput(createPort(mm2px(Vec(2.361, 71.145)), PortWidget::INPUT, module, Unity::IN2_INPUT + 0)); - addInput(createPort(mm2px(Vec(19.907, 71.145)), PortWidget::INPUT, module, Unity::IN2_INPUT + 1)); - addInput(createPort(mm2px(Vec(2.361, 82.145)), PortWidget::INPUT, module, Unity::IN2_INPUT + 2)); - addInput(createPort(mm2px(Vec(19.907, 82.145)), PortWidget::INPUT, module, Unity::IN2_INPUT + 3)); - addInput(createPort(mm2px(Vec(2.361, 93.144)), PortWidget::INPUT, module, Unity::IN2_INPUT + 4)); - addInput(createPort(mm2px(Vec(19.907, 93.144)), PortWidget::INPUT, module, Unity::IN2_INPUT + 5)); - - addOutput(createPort(mm2px(Vec(2.361, 54.15)), PortWidget::OUTPUT, module, Unity::MIX1_OUTPUT)); - addOutput(createPort(mm2px(Vec(19.907, 54.15)), PortWidget::OUTPUT, module, Unity::INV1_OUTPUT)); - addOutput(createPort(mm2px(Vec(2.361, 108.144)), PortWidget::OUTPUT, module, Unity::MIX2_OUTPUT)); - addOutput(createPort(mm2px(Vec(19.907, 108.144)), PortWidget::OUTPUT, module, Unity::INV2_OUTPUT)); + addParam(createParam(mm2px(Vec(12.867, 52.961)), module, Unity::AVG1_PARAM)); + addParam(createParam(mm2px(Vec(12.867, 107.006)), module, Unity::AVG2_PARAM)); + + addInput(createInput(mm2px(Vec(2.361, 17.144)), module, Unity::IN1_INPUT + 0)); + addInput(createInput(mm2px(Vec(19.907, 17.144)), module, Unity::IN1_INPUT + 1)); + addInput(createInput(mm2px(Vec(2.361, 28.145)), module, Unity::IN1_INPUT + 2)); + addInput(createInput(mm2px(Vec(19.907, 28.145)), module, Unity::IN1_INPUT + 3)); + addInput(createInput(mm2px(Vec(2.361, 39.145)), module, Unity::IN1_INPUT + 4)); + addInput(createInput(mm2px(Vec(19.907, 39.145)), module, Unity::IN1_INPUT + 5)); + addInput(createInput(mm2px(Vec(2.361, 71.145)), module, Unity::IN2_INPUT + 0)); + addInput(createInput(mm2px(Vec(19.907, 71.145)), module, Unity::IN2_INPUT + 1)); + addInput(createInput(mm2px(Vec(2.361, 82.145)), module, Unity::IN2_INPUT + 2)); + addInput(createInput(mm2px(Vec(19.907, 82.145)), module, Unity::IN2_INPUT + 3)); + addInput(createInput(mm2px(Vec(2.361, 93.144)), module, Unity::IN2_INPUT + 4)); + addInput(createInput(mm2px(Vec(19.907, 93.144)), module, Unity::IN2_INPUT + 5)); + + addOutput(createOutput(mm2px(Vec(2.361, 54.15)), module, Unity::MIX1_OUTPUT)); + addOutput(createOutput(mm2px(Vec(19.907, 54.15)), module, Unity::INV1_OUTPUT)); + addOutput(createOutput(mm2px(Vec(2.361, 108.144)), module, Unity::MIX2_OUTPUT)); + addOutput(createOutput(mm2px(Vec(19.907, 108.144)), module, Unity::INV2_OUTPUT)); addChild(createLight>(mm2px(Vec(13.652, 19.663)), module, Unity::VU1_LIGHT + 0)); addChild(createLight>(mm2px(Vec(13.652, 25.163)), module, Unity::VU1_LIGHT + 1)); diff --git a/src/VCA.cpp b/src/VCA.cpp index 0f3c52a..8115469 100644 --- a/src/VCA.cpp +++ b/src/VCA.cpp @@ -22,25 +22,28 @@ struct VCA : Module { NUM_OUTPUTS }; - VCA() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} - void step() override; -}; + VCA() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + params[LEVEL1_PARAM].config(0.0, 1.0, 0.0); + params[LEVEL2_PARAM].config(0.0, 1.0, 0.0); + } + void stepChannel(InputIds in, ParamIds level, InputIds lin, InputIds exp, OutputIds out) { + float v = inputs[in].value * params[level].value; + if (inputs[lin].active) + v *= clamp(inputs[lin].value / 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; + } -static void stepChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) { - float v = in.value * level.value; - if (lin.active) - v *= clamp(lin.value / 10.0f, 0.0f, 1.0f); - const float expBase = 50.0f; - if (exp.active) - v *= rescale(powf(expBase, clamp(exp.value / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f); - out.value = v; -} + void step() override { + stepChannel(IN1_INPUT, LEVEL1_PARAM, LIN1_INPUT, EXP1_INPUT, OUT1_OUTPUT); + stepChannel(IN2_INPUT, LEVEL2_PARAM, LIN2_INPUT, EXP2_INPUT, OUT2_OUTPUT); + } +}; -void VCA::step() { - stepChannel(inputs[IN1_INPUT], params[LEVEL1_PARAM], inputs[LIN1_INPUT], inputs[EXP1_INPUT], outputs[OUT1_OUTPUT]); - stepChannel(inputs[IN2_INPUT], params[LEVEL2_PARAM], inputs[LIN2_INPUT], inputs[EXP2_INPUT], outputs[OUT2_OUTPUT]); -} struct VCAWidget : ModuleWidget { @@ -48,25 +51,25 @@ struct VCAWidget : ModuleWidget { }; VCAWidget::VCAWidget(VCA *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/VCA.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/VCA.svg"))); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); - addParam(createParam(mm2px(Vec(6.35, 19.11753)), module, VCA::LEVEL1_PARAM, 0.0, 1.0, 0.0)); - addParam(createParam(mm2px(Vec(6.35, 74.80544)), module, VCA::LEVEL2_PARAM, 0.0, 1.0, 0.0)); + addParam(createParam(mm2px(Vec(6.35, 19.11753)), module, VCA::LEVEL1_PARAM)); + addParam(createParam(mm2px(Vec(6.35, 74.80544)), module, VCA::LEVEL2_PARAM)); - addInput(createPort(mm2px(Vec(2.5907, 38.19371)), PortWidget::INPUT, module, VCA::EXP1_INPUT)); - addInput(createPort(mm2px(Vec(14.59752, 38.19371)), PortWidget::INPUT, module, VCA::LIN1_INPUT)); - addInput(createPort(mm2px(Vec(2.5907, 52.80642)), PortWidget::INPUT, module, VCA::IN1_INPUT)); - addInput(createPort(mm2px(Vec(2.5907, 93.53435)), PortWidget::INPUT, module, VCA::EXP2_INPUT)); - addInput(createPort(mm2px(Vec(14.59752, 93.53435)), PortWidget::INPUT, module, VCA::LIN2_INPUT)); - addInput(createPort(mm2px(Vec(2.5907, 108.14706)), PortWidget::INPUT, module, VCA::IN2_INPUT)); + addInput(createInput(mm2px(Vec(2.5907, 38.19371)), module, VCA::EXP1_INPUT)); + addInput(createInput(mm2px(Vec(14.59752, 38.19371)), module, VCA::LIN1_INPUT)); + addInput(createInput(mm2px(Vec(2.5907, 52.80642)), module, VCA::IN1_INPUT)); + addInput(createInput(mm2px(Vec(2.5907, 93.53435)), module, VCA::EXP2_INPUT)); + addInput(createInput(mm2px(Vec(14.59752, 93.53435)), module, VCA::LIN2_INPUT)); + addInput(createInput(mm2px(Vec(2.5907, 108.14706)), module, VCA::IN2_INPUT)); - addOutput(createPort(mm2px(Vec(14.59752, 52.80642)), PortWidget::OUTPUT, module, VCA::OUT1_OUTPUT)); - addOutput(createPort(mm2px(Vec(14.59752, 108.14706)), PortWidget::OUTPUT, module, VCA::OUT2_OUTPUT)); + addOutput(createOutput(mm2px(Vec(14.59752, 52.80642)), module, VCA::OUT1_OUTPUT)); + addOutput(createOutput(mm2px(Vec(14.59752, 108.14706)), module, VCA::OUT2_OUTPUT)); } @@ -91,12 +94,16 @@ struct VCA_1 : Module { float lastCv = 0.f; - VCA_1() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {} + VCA_1() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + params[LEVEL_PARAM].config(0.0, 1.0, 1.0); + params[EXP_PARAM].config(0.0, 1.0, 1.0); + } void step() override { float cv = inputs[CV_INPUT].normalize(10.f) / 10.f; if ((int) params[EXP_PARAM].value == 0) - cv = powf(cv, 4.f); + cv = std::pow(cv, 4.f); lastCv = cv; outputs[OUT_OUTPUT].value = inputs[IN_INPUT].value * params[LEVEL_PARAM].value * cv; } @@ -133,11 +140,11 @@ struct VCA_1VUKnob : Knob { nvgRect(vg, r.pos.x, r.pos.y + r.size.y / segs * i + 0.5, r.size.x, r.size.y / segs - 1.0); if (segValue > 0.f) { - nvgFillColor(vg, colorAlpha(nvgRGBf(0.33, 0.33, 0.33), segValue)); + nvgFillColor(vg, color::alpha(nvgRGBf(0.33, 0.33, 0.33), segValue)); nvgFill(vg); } if (segAmplitude > 0.f) { - nvgFillColor(vg, colorAlpha(COLOR_GREEN, segAmplitude)); + nvgFillColor(vg, color::alpha(color::GREEN, segAmplitude)); nvgFill(vg); } } @@ -147,22 +154,22 @@ struct VCA_1VUKnob : Knob { struct VCA_1Widget : ModuleWidget { VCA_1Widget(VCA_1 *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/VCA-1.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/VCA-1.svg"))); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); - VCA_1VUKnob *levelParam = createParam(mm2px(Vec(2.62103, 12.31692)), module, VCA_1::LEVEL_PARAM, 0.0, 1.0, 1.0); + VCA_1VUKnob *levelParam = createParam(mm2px(Vec(2.62103, 12.31692)), module, VCA_1::LEVEL_PARAM); levelParam->module = module; addParam(levelParam); - addParam(createParam(mm2px(Vec(5.24619, 79.9593)), module, VCA_1::EXP_PARAM, 0.0, 1.0, 1.0)); + addParam(createParam(mm2px(Vec(5.24619, 79.9593)), module, VCA_1::EXP_PARAM)); - addInput(createPort(mm2px(Vec(3.51261, 60.4008)), PortWidget::INPUT, module, VCA_1::CV_INPUT)); - addInput(createPort(mm2px(Vec(3.51398, 97.74977)), PortWidget::INPUT, module, VCA_1::IN_INPUT)); + addInput(createInput(mm2px(Vec(3.51261, 60.4008)), module, VCA_1::CV_INPUT)); + addInput(createInput(mm2px(Vec(3.51398, 97.74977)), module, VCA_1::IN_INPUT)); - addOutput(createPort(mm2px(Vec(3.51398, 108.64454)), PortWidget::OUTPUT, module, VCA_1::OUT_OUTPUT)); + addOutput(createOutput(mm2px(Vec(3.51398, 108.64454)), module, VCA_1::OUT_OUTPUT)); } }; diff --git a/src/VCF.cpp b/src/VCF.cpp index e2b0982..3ec48f7 100644 --- a/src/VCF.cpp +++ b/src/VCF.cpp @@ -1,8 +1,8 @@ #include "Fundamental.hpp" -inline float clip(float x) { - return tanhf(x); +static float clip(float x) { + return std::tanh(x); } struct LadderFilter { @@ -78,7 +78,14 @@ struct VCF : Module { // Decimator lowpassDecimator; // Decimator highpassDecimator; - VCF() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + VCF() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + params[FREQ_PARAM].config(0.f, 1.f, 0.5f); + params[FINE_PARAM].config(0.f, 1.f, 0.5f); + params[RES_PARAM].config(0.f, 1.f, 0.f); + params[FREQ_CV_PARAM].config(-1.f, 1.f, 0.f); + params[DRIVE_PARAM].config(0.f, 1.f, 0.f); + } void onReset() override { filter.reset(); @@ -97,7 +104,7 @@ struct VCF : Module { input *= gain; // Add -60dB noise to bootstrap self-oscillation - input += 1e-6f * (2.f * randomUniform() - 1.f); + 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); @@ -106,16 +113,16 @@ struct VCF : Module { // Set cutoff frequency float pitch = 0.f; if (inputs[FREQ_INPUT].active) - pitch += inputs[FREQ_INPUT].value * quadraticBipolar(params[FREQ_CV_PARAM].value); + pitch += inputs[FREQ_INPUT].value * dsp::quadraticBipolar(params[FREQ_CV_PARAM].value); pitch += params[FREQ_PARAM].value * 10.f - 5.f; - pitch += quadraticBipolar(params[FINE_PARAM].value * 2.f - 1.f) * 7.f / 12.f; + pitch += dsp::quadraticBipolar(params[FINE_PARAM].value * 2.f - 1.f) * 7.f / 12.f; float cutoff = 261.626f * powf(2.f, pitch); cutoff = clamp(cutoff, 1.f, 8000.f); filter.setCutoff(cutoff); /* // Process sample - float dt = engineGetSampleTime() / UPSAMPLE; + float dt = app()->engine->getSampleTime() / UPSAMPLE; float inputBuf[UPSAMPLE]; float lowpassBuf[UPSAMPLE]; float highpassBuf[UPSAMPLE]; @@ -135,7 +142,7 @@ struct VCF : Module { outputs[HPF_OUTPUT].value = 5.f * highpassDecimator.process(highpassBuf); } */ - filter.process(input, engineGetSampleTime()); + filter.process(input, app()->engine->getSampleTime()); outputs[LPF_OUTPUT].value = 5.f * filter.lowpass; outputs[HPF_OUTPUT].value = 5.f * filter.highpass; } @@ -144,29 +151,28 @@ struct VCF : Module { struct VCFWidget : ModuleWidget { VCFWidget(VCF *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/VCF.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/VCF.svg"))); addChild(createWidget(Vec(15, 0))); addChild(createWidget(Vec(box.size.x - 30, 0))); addChild(createWidget(Vec(15, 365))); addChild(createWidget(Vec(box.size.x - 30, 365))); - addParam(createParam(Vec(33, 61), module, VCF::FREQ_PARAM, 0.f, 1.f, 0.5f)); - addParam(createParam(Vec(12, 143), module, VCF::FINE_PARAM, 0.f, 1.f, 0.5f)); - addParam(createParam(Vec(71, 143), module, VCF::RES_PARAM, 0.f, 1.f, 0.f)); - addParam(createParam(Vec(12, 208), module, VCF::FREQ_CV_PARAM, -1.f, 1.f, 0.f)); - addParam(createParam(Vec(71, 208), module, VCF::DRIVE_PARAM, 0.f, 1.f, 0.f)); + addParam(createParam(Vec(33, 61), module, VCF::FREQ_PARAM)); + addParam(createParam(Vec(12, 143), module, VCF::FINE_PARAM)); + addParam(createParam(Vec(71, 143), module, VCF::RES_PARAM)); + addParam(createParam(Vec(12, 208), module, VCF::FREQ_CV_PARAM)); + addParam(createParam(Vec(71, 208), module, VCF::DRIVE_PARAM)); - addInput(createPort(Vec(10, 276), PortWidget::INPUT, module, VCF::FREQ_INPUT)); - addInput(createPort(Vec(48, 276), PortWidget::INPUT, module, VCF::RES_INPUT)); - addInput(createPort(Vec(85, 276), PortWidget::INPUT, module, VCF::DRIVE_INPUT)); - addInput(createPort(Vec(10, 320), PortWidget::INPUT, module, VCF::IN_INPUT)); + addInput(createInput(Vec(10, 276), module, VCF::FREQ_INPUT)); + addInput(createInput(Vec(48, 276), module, VCF::RES_INPUT)); + addInput(createInput(Vec(85, 276), module, VCF::DRIVE_INPUT)); + addInput(createInput(Vec(10, 320), module, VCF::IN_INPUT)); - addOutput(createPort(Vec(48, 320), PortWidget::OUTPUT, module, VCF::LPF_OUTPUT)); - addOutput(createPort(Vec(85, 320), PortWidget::OUTPUT, module, VCF::HPF_OUTPUT)); + addOutput(createOutput(Vec(48, 320), module, VCF::LPF_OUTPUT)); + addOutput(createOutput(Vec(85, 320), module, VCF::HPF_OUTPUT)); } }; - Model *modelVCF = createModel("VCF"); diff --git a/src/VCMixer.cpp b/src/VCMixer.cpp index e4bfad4..3d692bd 100644 --- a/src/VCMixer.cpp +++ b/src/VCMixer.cpp @@ -19,13 +19,20 @@ struct VCMixer : Module { NUM_OUTPUTS }; - VCMixer() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + VCMixer() { + config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS); + params[MIX_LVL_PARAM].config(0.0, 2.0, 1.0); + params[LVL_PARAM + 0].config(0.0, 1.0, 1.0); + params[LVL_PARAM + 1].config(0.0, 1.0, 1.0); + params[LVL_PARAM + 2].config(0.0, 1.0, 1.0); + params[LVL_PARAM + 3].config(0.0, 1.0, 1.0); + } void step() override { float mix = 0.f; for (int i = 0; i < 4; i++) { float ch = inputs[CH_INPUT + i].value; - ch *= powf(params[LVL_PARAM + i].value, 2.f); + ch *= std::pow(params[LVL_PARAM + i].value, 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; @@ -41,35 +48,35 @@ struct VCMixer : Module { struct VCMixerWidget : ModuleWidget { VCMixerWidget(VCMixer *module) : ModuleWidget(module) { - setPanel(SVG::load(assetPlugin(plugin, "res/VCMixer.svg"))); + setPanel(SVG::load(asset::plugin(plugin, "res/VCMixer.svg"))); addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); - addParam(createParam(mm2px(Vec(19.049999, 21.161154)), module, VCMixer::MIX_LVL_PARAM, 0.0, 2.0, 1.0)); - addParam(createParam(mm2px(Vec(5.8993969, 44.33149).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 0, 0.0, 1.0, 1.0)); - addParam(createParam(mm2px(Vec(17.899343, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 1, 0.0, 1.0, 1.0)); - addParam(createParam(mm2px(Vec(29.899292, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 2, 0.0, 1.0, 1.0)); - addParam(createParam(mm2px(Vec(41.90065, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 3, 0.0, 1.0, 1.0)); + addParam(createParam(mm2px(Vec(19.049999, 21.161154)), module, VCMixer::MIX_LVL_PARAM)); + addParam(createParam(mm2px(Vec(5.8993969, 44.33149).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 0)); + addParam(createParam(mm2px(Vec(17.899343, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 1)); + addParam(createParam(mm2px(Vec(29.899292, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 2)); + addParam(createParam(mm2px(Vec(41.90065, 44.331486).plus(Vec(-2, 0))), module, VCMixer::LVL_PARAM + 3)); // Use old interleaved order for backward compatibility with <0.6 - addInput(createPort(mm2px(Vec(3.2935331, 23.404598)), PortWidget::INPUT, module, VCMixer::MIX_CV_INPUT)); - addInput(createPort(mm2px(Vec(3.2935331, 78.531639)), PortWidget::INPUT, module, VCMixer::CH_INPUT + 0)); - addInput(createPort(mm2px(Vec(3.2935331, 93.531586)), PortWidget::INPUT, module, VCMixer::CV_INPUT + 0)); - addInput(createPort(mm2px(Vec(15.29348, 78.531639)), PortWidget::INPUT, module, VCMixer::CH_INPUT + 1)); - addInput(createPort(mm2px(Vec(15.29348, 93.531586)), PortWidget::INPUT, module, VCMixer::CV_INPUT + 1)); - addInput(createPort(mm2px(Vec(27.293465, 78.531639)), PortWidget::INPUT, module, VCMixer::CH_INPUT + 2)); - addInput(createPort(mm2px(Vec(27.293465, 93.531586)), PortWidget::INPUT, module, VCMixer::CV_INPUT + 2)); - addInput(createPort(mm2px(Vec(39.293411, 78.531639)), PortWidget::INPUT, module, VCMixer::CH_INPUT + 3)); - addInput(createPort(mm2px(Vec(39.293411, 93.531586)), PortWidget::INPUT, module, VCMixer::CV_INPUT + 3)); + addInput(createInput(mm2px(Vec(3.2935331, 23.404598)), module, VCMixer::MIX_CV_INPUT)); + addInput(createInput(mm2px(Vec(3.2935331, 78.531639)), module, VCMixer::CH_INPUT + 0)); + addInput(createInput(mm2px(Vec(3.2935331, 93.531586)), module, VCMixer::CV_INPUT + 0)); + addInput(createInput(mm2px(Vec(15.29348, 78.531639)), module, VCMixer::CH_INPUT + 1)); + addInput(createInput(mm2px(Vec(15.29348, 93.531586)), module, VCMixer::CV_INPUT + 1)); + addInput(createInput(mm2px(Vec(27.293465, 78.531639)), module, VCMixer::CH_INPUT + 2)); + addInput(createInput(mm2px(Vec(27.293465, 93.531586)), module, VCMixer::CV_INPUT + 2)); + addInput(createInput(mm2px(Vec(39.293411, 78.531639)), module, VCMixer::CH_INPUT + 3)); + addInput(createInput(mm2px(Vec(39.293411, 93.531586)), module, VCMixer::CV_INPUT + 3)); - addOutput(createPort(mm2px(Vec(39.293411, 23.4046)), PortWidget::OUTPUT, module, VCMixer::MIX_OUTPUT)); - addOutput(createPort(mm2px(Vec(3.2935331, 108.53153)), PortWidget::OUTPUT, module, VCMixer::CH_OUTPUT + 0)); - addOutput(createPort(mm2px(Vec(15.29348, 108.53153)), PortWidget::OUTPUT, module, VCMixer::CH_OUTPUT + 1)); - addOutput(createPort(mm2px(Vec(27.293465, 108.53153)), PortWidget::OUTPUT, module, VCMixer::CH_OUTPUT + 2)); - addOutput(createPort(mm2px(Vec(39.293411, 108.53153)), PortWidget::OUTPUT, module, VCMixer::CH_OUTPUT + 3)); + addOutput(createOutput(mm2px(Vec(39.293411, 23.4046)), module, VCMixer::MIX_OUTPUT)); + addOutput(createOutput(mm2px(Vec(3.2935331, 108.53153)), module, VCMixer::CH_OUTPUT + 0)); + addOutput(createOutput(mm2px(Vec(15.29348, 108.53153)), module, VCMixer::CH_OUTPUT + 1)); + addOutput(createOutput(mm2px(Vec(27.293465, 108.53153)), module, VCMixer::CH_OUTPUT + 2)); + addOutput(createOutput(mm2px(Vec(39.293411, 108.53153)), module, VCMixer::CH_OUTPUT + 3)); } }; diff --git a/src/VCO.cpp b/src/VCO.cpp index 3a382db..63efc9d 100644 --- a/src/VCO.cpp +++ b/src/VCO.cpp @@ -17,11 +17,11 @@ struct VoltageControlledOscillator { bool syncEnabled = false; bool syncDirection = false; - Decimator sinDecimator; - Decimator triDecimator; - Decimator sawDecimator; - Decimator sqrDecimator; - RCFilter sqrFilter; + dsp::Decimator sinDecimator; + dsp::Decimator triDecimator; + dsp::Decimator sawDecimator; + dsp::Decimator sqrDecimator; + dsp::RCFilter sqrFilter; // For analog detuning effect float pitchSlew = 0.0f; @@ -42,11 +42,11 @@ struct VoltageControlledOscillator { } else { // Quantize coarse knob if digital mode - pitch = roundf(pitch); + pitch = std::round(pitch); } pitch += pitchCv; // Note C4 - freq = dsp::FREQ_C4 * powf(2.0f, pitch / 12.0f); + freq = dsp::FREQ_C4 * std::pow(2.0f, pitch / 12.0f); } void setPulseWidth(float pulseWidth) { const float pwMin = 0.01f; @@ -101,9 +101,9 @@ struct VoltageControlledOscillator { if (analog) { // Quadratic approximation of sine, slightly richer harmonics if (phase < 0.5f) - sinBuffer[i] = 1.f - 16.f * powf(phase - 0.25f, 2); + sinBuffer[i] = 1.f - 16.f * std::pow(phase - 0.25f, 2); else - sinBuffer[i] = -1.f + 16.f * powf(phase - 0.75f, 2); + sinBuffer[i] = -1.f + 16.f * std::pow(phase - 0.75f, 2); sinBuffer[i] *= 1.08f; } else { @@ -211,10 +211,10 @@ void VCO::step() { oscillator.analog = params[MODE_PARAM].value > 0.0f; oscillator.soft = params[SYNC_PARAM].value <= 0.0f; - float pitchFine = 3.0f * quadraticBipolar(params[FINE_PARAM].value); + float pitchFine = 3.0f * dsp::quadraticBipolar(params[FINE_PARAM].value); float pitchCv = 12.0f * inputs[PITCH_INPUT].value; if (inputs[FM_INPUT].active) { - pitchCv += quadraticBipolar(params[FM_PARAM].value) * 12.0f * inputs[FM_INPUT].value; + pitchCv += dsp::quadraticBipolar(params[FM_PARAM].value) * 12.0f * inputs[FM_INPUT].value; } oscillator.setPitch(params[FREQ_PARAM].value, pitchFine + pitchCv); oscillator.setPulseWidth(params[PW_PARAM].value + params[PWM_PARAM].value * inputs[PW_INPUT].value / 10.0f); @@ -318,7 +318,7 @@ void VCO2::step() { oscillator.analog = params[MODE_PARAM].value > 0.0f; oscillator.soft = params[SYNC_PARAM].value <= 0.0f; - float pitchCv = params[FREQ_PARAM].value + quadraticBipolar(params[FM_PARAM].value) * 12.0f * inputs[FM_INPUT].value; + float pitchCv = params[FREQ_PARAM].value + dsp::quadraticBipolar(params[FM_PARAM].value) * 12.0f * inputs[FM_INPUT].value; oscillator.setPitch(0.0f, pitchCv); oscillator.syncEnabled = inputs[SYNC_INPUT].active;