Convert the rest of the host modules for zero latency behaviour

Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
falkTX 2022-02-08 03:20:26 +00:00
parent 0000456cf5
commit deeecfd3ab
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
10 changed files with 105 additions and 29 deletions

View file

@ -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<SwitchQuantity>(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 {

View file

@ -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<rack::engine::Output>& outputs, int learnedCcs[16])
bool process(const ProcessArgs& args, std::vector<rack::engine::Output>& 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++)
{

View file

@ -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<rack::engine::Output>& 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)
{

View file

@ -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;

View file

@ -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<rack::engine::Output>& outputs)
bool process(const ProcessArgs& args, std::vector<rack::engine::Output>& 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)
{

View file

@ -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<CardinalPluginContext*>(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; i<kModuleParameters; ++i)
{
const bool connected = outputs[i].isConnected();
@ -70,10 +72,13 @@ struct HostParameters : Module {
}
if (connected)
outputs[i].setVoltage(parameters[i].process(sampleTime, pcontext->parameters[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;
}
};

View file

@ -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 {

View file

@ -47,6 +47,8 @@ extern Model* modelIldaeil;
extern Model* modelMPV;
extern Model* modelTextEditor;
extern std::vector<Model*> hostTerminalModels;
/*
* Find the highest absolute and normalized value within a float array.
*/

View file

@ -511,6 +511,9 @@ extern Model* modelMaude_221;
#endif // NOPLUGINS
// known terminal modules
std::vector<Model*> 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,
};
}
}

View file

@ -52,8 +52,7 @@
// known terminal modules
extern rack::plugin::Model* modelHostAudio2;
extern rack::plugin::Model* modelHostAudio8;
extern std::vector<rack::plugin::Model*> hostTerminalModels;
namespace rack {
@ -577,7 +576,7 @@ std::vector<int64_t> 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<TerminalModule*>(module);
return nullptr;
}