From deeecfd3ab4ce7cbe1a6bd614a005500d373de43 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 8 Feb 2022 03:20:26 +0000 Subject: [PATCH] Convert the rest of the host modules for zero latency behaviour Signed-off-by: falkTX --- plugins/Cardinal/src/HostCV.cpp | 10 ++++++++-- plugins/Cardinal/src/HostMIDI-CC.cpp | 21 ++++++++++++++++---- plugins/Cardinal/src/HostMIDI-Gate.cpp | 20 +++++++++++++++---- plugins/Cardinal/src/HostMIDI-Map.cpp | 9 ++++++--- plugins/Cardinal/src/HostMIDI.cpp | 26 +++++++++++++++++++++---- plugins/Cardinal/src/HostParameters.cpp | 15 ++++++++------ plugins/Cardinal/src/HostTime.cpp | 10 ++++++++-- plugins/Cardinal/src/plugin.hpp | 2 ++ plugins/plugins.cpp | 16 ++++++++++++++- src/override/Engine.cpp | 5 ++--- 10 files changed, 105 insertions(+), 29 deletions(-) diff --git a/plugins/Cardinal/src/HostCV.cpp b/plugins/Cardinal/src/HostCV.cpp index 64f3708..5180e53 100644 --- a/plugins/Cardinal/src/HostCV.cpp +++ b/plugins/Cardinal/src/HostCV.cpp @@ -24,7 +24,7 @@ USE_NAMESPACE_DISTRHO; -struct HostCV : Module { +struct HostCV : TerminalModule { CardinalPluginContext* const pcontext; int dataFrame = 0; int64_t lastBlockFrame = -1; @@ -59,7 +59,7 @@ struct HostCV : Module { configParam(BIPOLAR_OUTPUTS_6_10, 0.f, 1.f, 0.f, "Bipolar Outputs 6-10")->randomizeEnabled = false; } - void process(const ProcessArgs&) override + void processTerminalInput(const ProcessArgs&) override { if (pcontext->variant != kCardinalVariantMain) return; @@ -78,6 +78,9 @@ struct HostCV : Module { const int k = dataFrame++; DISTRHO_SAFE_ASSERT_RETURN(k < pcontext->engine->getBlockFrames(),); + if (isBypassed()) + return; + float inputOffset, outputOffset; inputOffset = params[BIPOLAR_INPUTS_1_5].getValue() > 0.1f ? 5.0f : 0.0f; outputOffset = params[BIPOLAR_OUTPUTS_1_5].getValue() > 0.1f ? 5.0f : 0.0f; @@ -97,6 +100,9 @@ struct HostCV : Module { dataOuts[i+CARDINAL_AUDIO_IO_OFFSET][k] = inputs[i].getVoltage() + inputOffset; } } + + void processTerminalOutput(const ProcessArgs&) override + {} }; struct HostCVWidget : ModuleWidgetWith8HP { diff --git a/plugins/Cardinal/src/HostMIDI-CC.cpp b/plugins/Cardinal/src/HostMIDI-CC.cpp index 3f92cbe..505fc7d 100644 --- a/plugins/Cardinal/src/HostMIDI-CC.cpp +++ b/plugins/Cardinal/src/HostMIDI-CC.cpp @@ -34,7 +34,7 @@ USE_NAMESPACE_DISTRHO; -struct HostMIDICC : Module { +struct HostMIDICC : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -121,7 +121,8 @@ struct HostMIDICC : Module { lsbMode = false; } - bool process(const ProcessArgs& args, std::vector& outputs, int learnedCcs[16]) + bool process(const ProcessArgs& args, std::vector& outputs, int learnedCcs[16], + const bool isBypassed) { // Cardinal specific const int64_t blockFrame = pcontext->engine->getBlockFrame(); @@ -136,6 +137,12 @@ struct HostMIDICC : Module { midiEventFrame = 0; } + if (isBypassed) + { + ++midiEventFrame; + return false; + } + while (midiEventsLeft != 0) { const MidiEvent& midiEvent(*midiEvents); @@ -394,12 +401,18 @@ struct HostMIDICC : Module { midiOutput.reset(); } - void process(const ProcessArgs& args) override + void processTerminalInput(const ProcessArgs& args) override { - if (midiInput.process(args, outputs, learnedCcs)) + if (midiInput.process(args, outputs, learnedCcs, isBypassed())) midiOutput.frame = 0; else ++midiOutput.frame; + } + + void processTerminalOutput(const ProcessArgs&) override + { + if (isBypassed()) + return; for (int i = 0; i < 16; i++) { diff --git a/plugins/Cardinal/src/HostMIDI-Gate.cpp b/plugins/Cardinal/src/HostMIDI-Gate.cpp index 9877af2..08b9a55 100644 --- a/plugins/Cardinal/src/HostMIDI-Gate.cpp +++ b/plugins/Cardinal/src/HostMIDI-Gate.cpp @@ -34,7 +34,7 @@ USE_NAMESPACE_DISTRHO; -struct HostMIDIGate : Module { +struct HostMIDIGate : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -104,7 +104,7 @@ struct HostMIDIGate : Module { } bool process(const ProcessArgs& args, std::vector& outputs, - const bool velocityMode, uint8_t learnedNotes[18]) + const bool velocityMode, uint8_t learnedNotes[18], const bool isBypassed) { // Cardinal specific const int64_t blockFrame = pcontext->engine->getBlockFrame(); @@ -119,6 +119,12 @@ struct HostMIDIGate : Module { midiEventFrame = 0; } + if (isBypassed) + { + ++midiEventFrame; + return blockFrameChanged; + } + while (midiEventsLeft != 0) { const MidiEvent& midiEvent(*midiEvents); @@ -322,12 +328,18 @@ struct HostMIDIGate : Module { midiOutput.reset(); } - void process(const ProcessArgs& args) override + void processTerminalInput(const ProcessArgs& args) override { - if (midiInput.process(args, outputs, velocityMode, learnedNotes)) + if (midiInput.process(args, outputs, velocityMode, learnedNotes, isBypassed())) midiOutput.frame = 0; else ++midiOutput.frame; + } + + void processTerminalOutput(const ProcessArgs&) override + { + if (isBypassed()) + return; for (int i = 0; i < 18; ++i) { diff --git a/plugins/Cardinal/src/HostMIDI-Map.cpp b/plugins/Cardinal/src/HostMIDI-Map.cpp index a02f715..9f8a480 100644 --- a/plugins/Cardinal/src/HostMIDI-Map.cpp +++ b/plugins/Cardinal/src/HostMIDI-Map.cpp @@ -36,7 +36,7 @@ USE_NAMESPACE_DISTRHO; static const int MAX_MIDI_CONTROL = 120; /* 0x77 + 1 */ -struct HostMIDIMap : Module { +struct HostMIDIMap : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -131,7 +131,7 @@ struct HostMIDIMap : Module { mapLen = 1; } - void process(const ProcessArgs& args) override + void processTerminalInput(const ProcessArgs& args) override { // Cardinal specific const int64_t blockFrame = pcontext->engine->getBlockFrame(); @@ -146,7 +146,7 @@ struct HostMIDIMap : Module { midiEventFrame = 0; } - if (!divider.process()) + if (isBypassed() || !divider.process()) { ++midiEventFrame; return; @@ -258,6 +258,9 @@ struct HostMIDIMap : Module { } } + void processTerminalOutput(const ProcessArgs&) override + {} + void clearMap(int id) { nextLearningId = -1; diff --git a/plugins/Cardinal/src/HostMIDI.cpp b/plugins/Cardinal/src/HostMIDI.cpp index f3852f5..3a66ad0 100644 --- a/plugins/Cardinal/src/HostMIDI.cpp +++ b/plugins/Cardinal/src/HostMIDI.cpp @@ -34,7 +34,7 @@ USE_NAMESPACE_DISTRHO; -struct HostMIDI : Module { +struct HostMIDI : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -165,7 +165,7 @@ struct HostMIDI : Module { heldNotes.clear(); } - bool process(const ProcessArgs& args, std::vector& outputs) + bool process(const ProcessArgs& args, std::vector& outputs, const bool isBypassed) { // Cardinal specific const int64_t blockFrame = pcontext->engine->getBlockFrame(); @@ -177,6 +177,13 @@ struct HostMIDI : Module { midiEvents = pcontext->midiEvents; midiEventsLeft = pcontext->midiEventCount; + + if (isBypassed) + { + midiEventFrame = 1; + return true; + } + midiEventFrame = 0; if (pcontext->playing) @@ -196,6 +203,11 @@ struct HostMIDI : Module { stopPulse.trigger(1e-3); } } + else if (isBypassed) + { + ++midiEventFrame; + return false; + } while (midiEventsLeft != 0) { @@ -572,12 +584,18 @@ struct HostMIDI : Module { midiOutput.channel = 0; } - void process(const ProcessArgs& args) override + void processTerminalInput(const ProcessArgs& args) override { - if (midiInput.process(args, outputs)) + if (midiInput.process(args, outputs, isBypassed())) midiOutput.frame = 0; else ++midiOutput.frame; + } + + void processTerminalOutput(const ProcessArgs&) override + { + if (isBypassed()) + return; for (int c = 0; c < inputs[PITCH_INPUT].getChannels(); ++c) { diff --git a/plugins/Cardinal/src/HostParameters.cpp b/plugins/Cardinal/src/HostParameters.cpp index 80bda1c..a46f659 100644 --- a/plugins/Cardinal/src/HostParameters.cpp +++ b/plugins/Cardinal/src/HostParameters.cpp @@ -22,7 +22,7 @@ USE_NAMESPACE_DISTRHO; -struct HostParameters : Module { +struct HostParameters : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -39,7 +39,6 @@ struct HostParameters : Module { CardinalPluginContext* const pcontext; rack::dsp::SlewLimiter parameters[kModuleParameters]; bool parametersConnected[kModuleParameters] = {}; - float sampleTime = 0.0f; HostParameters() : pcontext(static_cast(APP)) @@ -57,8 +56,11 @@ struct HostParameters : Module { onSampleRateChange(e); } - void process(const ProcessArgs&) override + void processTerminalInput(const ProcessArgs& args) override { + if (isBypassed()) + return; + for (uint32_t i=0; iparameters[i])); + outputs[i].setVoltage(parameters[i].process(args.sampleTime, pcontext->parameters[i])); } } + void processTerminalOutput(const ProcessArgs&) override + {} + void onSampleRateChange(const SampleRateChangeEvent& e) override { const double fall = 1.0 / (double(pcontext->bufferSize) / e.sampleRate); @@ -83,8 +88,6 @@ struct HostParameters : Module { parameters[i].reset(); parameters[i].setRiseFall(fall, fall); } - - sampleTime = e.sampleTime; } }; diff --git a/plugins/Cardinal/src/HostTime.cpp b/plugins/Cardinal/src/HostTime.cpp index 3d84828..946fd72 100644 --- a/plugins/Cardinal/src/HostTime.cpp +++ b/plugins/Cardinal/src/HostTime.cpp @@ -17,7 +17,7 @@ #include "plugincontext.hpp" -struct HostTime : Module { +struct HostTime : TerminalModule { enum ParamIds { NUM_PARAMS }; @@ -59,7 +59,7 @@ struct HostTime : Module { config(NUM_PARAMS, NUM_INPUTS, kHostTimeCount, kHostTimeCount); } - void process(const ProcessArgs& args) override + void processTerminalInput(const ProcessArgs& args) override { const int64_t blockFrame = pcontext->engine->getBlockFrame(); @@ -126,6 +126,9 @@ struct HostTime : Module { ? ((float) (timeInfo.beat - 1) + beatPhase) / pcontext->beatsPerBar : 0.0f; + if (isBypassed()) + return; + lights[kHostTimeRolling].setBrightness(playing ? 1.0f : 0.0f); lights[kHostTimeReset].setBrightnessSmooth(hasReset ? 1.0f : 0.0f, args.sampleTime * 0.5f); lights[kHostTimeBar].setBrightnessSmooth(hasBar ? 1.0f : 0.0f, args.sampleTime * 0.5f); @@ -142,6 +145,9 @@ struct HostTime : Module { outputs[kHostTimeBarPhase].setVoltage(barPhase * 10.0f); outputs[kHostTimeBeatPhase].setVoltage(beatPhase * 10.0f); } + + void processTerminalOutput(const ProcessArgs&) override + {} }; struct HostTimeWidget : ModuleWidget { diff --git a/plugins/Cardinal/src/plugin.hpp b/plugins/Cardinal/src/plugin.hpp index 89ac66e..b7f6767 100644 --- a/plugins/Cardinal/src/plugin.hpp +++ b/plugins/Cardinal/src/plugin.hpp @@ -47,6 +47,8 @@ extern Model* modelIldaeil; extern Model* modelMPV; extern Model* modelTextEditor; +extern std::vector hostTerminalModels; + /* * Find the highest absolute and normalized value within a float array. */ diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp index fa67116..ec34049 100644 --- a/plugins/plugins.cpp +++ b/plugins/plugins.cpp @@ -511,6 +511,9 @@ extern Model* modelMaude_221; #endif // NOPLUGINS +// known terminal modules +std::vector hostTerminalModels; + // stuff that reads config files, we dont want that int loadConsoleType() { return 0; } int loadDirectOutMode() { return 0; } @@ -571,7 +574,6 @@ std::string pluginManifest(const std::string& dirname); std::string pluginPath(const std::string& dirname); } -// regular plugins namespace plugin { struct StaticPluginLoader { @@ -689,6 +691,18 @@ static void initStatic__Cardinal() #else spl.removeModule("MPV"); #endif + + hostTerminalModels = { + modelHostAudio2, + modelHostAudio8, + modelHostCV, + modelHostMIDI, + modelHostMIDICC, + modelHostMIDIGate, + modelHostMIDIMap, + modelHostParameters, + modelHostTime, + }; } } diff --git a/src/override/Engine.cpp b/src/override/Engine.cpp index b172cd7..4862219 100644 --- a/src/override/Engine.cpp +++ b/src/override/Engine.cpp @@ -52,8 +52,7 @@ // known terminal modules -extern rack::plugin::Model* modelHostAudio2; -extern rack::plugin::Model* modelHostAudio8; +extern std::vector hostTerminalModels; namespace rack { @@ -577,7 +576,7 @@ std::vector Engine::getModuleIds() { static TerminalModule* asTerminalModule(Module* const module) { const plugin::Model* const model = module->model; - if (model == modelHostAudio2 || model == modelHostAudio8) + if (std::find(hostTerminalModels.begin(), hostTerminalModels.end(), model) != hostTerminalModels.end()) return static_cast(module); return nullptr; }