diff --git a/plugins/Cardinal/orig/HostAudio.svg b/plugins/Cardinal/orig/HostAudio.svg
new file mode 100644
index 0000000..7d5247d
--- /dev/null
+++ b/plugins/Cardinal/orig/HostAudio.svg
@@ -0,0 +1,103 @@
+
+
+
+
diff --git a/plugins/Cardinal/plugin.json b/plugins/Cardinal/plugin.json
index 0265114..5f1f06c 100644
--- a/plugins/Cardinal/plugin.json
+++ b/plugins/Cardinal/plugin.json
@@ -13,13 +13,29 @@
"changelogUrl": "",
"modules":
[
+ {
+ "slug": "HostAudio2",
+ "name": "Audio 2",
+ "description": "Exposes host-provided audio ports in a module",
+ "tags": [
+ "External"
+ ]
+ },
+ {
+ "slug": "HostAudio8",
+ "name": "Audio 8",
+ "description": "Exposes host-provided audio ports in a module",
+ "tags": [
+ "External"
+ ]
+ },
{
"slug": "HostCV",
"disabled": false,
"name": "Host CV",
"description": "Exposes host-provided CV ports in a module",
"tags": [
- "Utility"
+ "External"
]
},
{
@@ -28,7 +44,7 @@
"name": "Host Parameters",
"description": "Exposes host-controlled plugin parameters in a module",
"tags": [
- "Utility"
+ "External"
]
},
{
@@ -37,7 +53,7 @@
"name": "Host Time",
"description": "Exposes host-provided time/transport information in a module",
"tags": [
- "Utility"
+ "External"
]
},
{
diff --git a/plugins/Cardinal/res/HostAudio.svg b/plugins/Cardinal/res/HostAudio.svg
new file mode 100644
index 0000000..8d56ae9
--- /dev/null
+++ b/plugins/Cardinal/res/HostAudio.svg
@@ -0,0 +1,133 @@
+
+
+
+
diff --git a/plugins/Cardinal/src/HostAudio.cpp b/plugins/Cardinal/src/HostAudio.cpp
new file mode 100644
index 0000000..802bc7d
--- /dev/null
+++ b/plugins/Cardinal/src/HostAudio.cpp
@@ -0,0 +1,197 @@
+/*
+ * DISTRHO Cardinal Plugin
+ * Copyright (C) 2021-2022 Filipe Coelho
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * For a full copy of the GNU General Public License see the LICENSE file.
+ */
+
+#include "plugincontext.hpp"
+
+// -----------------------------------------------------------------------------------------------------------
+
+USE_NAMESPACE_DISTRHO;
+
+template
+struct HostAudio : Module {
+ CardinalPluginContext* const pcontext;
+ const int numParams;
+ const int numInputs;
+ const int numOutputs;
+ int dataFrame = 0;
+ int64_t lastBlockFrame = -1;
+
+ // for rack core audio module compatibility
+ dsp::RCFilter dcFilters[numIO];
+ bool dcFilterEnabled = (numIO == 2);
+
+ HostAudio()
+ : pcontext(static_cast(APP)),
+ numParams(numIO == 2 ? 1 : 0),
+ numInputs(pcontext->variant == kCardinalVariantSynth ? 0 : std::max(pcontext->variant != kCardinalVariantMain ? 2 : 8, numIO)),
+ numOutputs(std::max(pcontext->variant != kCardinalVariantMain ? 2 : 8, numIO))
+ {
+ if (pcontext == nullptr)
+ throw rack::Exception("Plugin context is null");
+
+ config(numParams, numIO, numIO, 0);
+
+ if (numParams != 0)
+ configParam(0, 0.f, 2.f, 1.f, "Level", " dB", -10, 40);
+
+ const float sampleTime = pcontext->engine->getSampleTime();
+ for (int i = 0; i < numIO; i++) {
+ dcFilters[i].setCutoffFreq(10.f * sampleTime);
+ }
+ }
+
+ void onReset() override
+ {
+ dcFilterEnabled = (numIO == 2);
+ }
+
+ void onSampleRateChange(const SampleRateChangeEvent& e) override
+ {
+ for (int i = 0; i < numIO; i++)
+ dcFilters[i].setCutoffFreq(10.f * e.sampleTime);
+ }
+
+ void process(const ProcessArgs&) override
+ {
+ const float* const* const dataIns = pcontext->dataIns;
+ float** const dataOuts = pcontext->dataOuts;
+
+ const int64_t blockFrame = pcontext->engine->getBlockFrame();
+
+ if (lastBlockFrame != blockFrame)
+ {
+ dataFrame = 0;
+ lastBlockFrame = blockFrame;
+ }
+
+ const int k = dataFrame++;
+ DISTRHO_SAFE_ASSERT_RETURN(k < pcontext->engine->getBlockFrames(),);
+
+ const float gain = numParams != 0 ? std::pow(params[0].getValue(), 2.f) : 1.0f;
+
+ // from host into cardinal, shows as output plug
+ for (int i=0; i
+struct HostAudioWidget : ModuleWidget {
+ static constexpr const float startX_In = 14.0f;
+ static constexpr const float startX_Out = 96.0f;
+ static constexpr const float startY = 74.0f;
+ static constexpr const float padding = 29.0f;
+ static constexpr const float middleX = startX_In + (startX_Out - startX_In) * 0.5f + padding * 0.25f;
+
+ HostAudio* const module;
+
+ HostAudioWidget(HostAudio* const m)
+ : module(m)
+ {
+ setModule(m);
+ setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/HostAudio.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)));
+
+ for (uint i=0; i(Vec(startX_In, startY + padding * i), m, i));
+
+ for (uint i=0; i(Vec(startX_Out, startY + padding * i), m, i));
+ }
+
+ void drawTextLine(NVGcontext* const vg, const uint offset, const char* const text)
+ {
+ const float y = startY + offset * padding;
+ nvgBeginPath(vg);
+ nvgFillColor(vg, color::WHITE);
+ nvgText(vg, middleX, y + 16, text, nullptr);
+ }
+
+ void draw(const DrawArgs& args) override
+ {
+ nvgBeginPath(args.vg);
+ nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
+ nvgFillPaint(args.vg, nvgLinearGradient(args.vg, 0, 0, 0, box.size.y,
+ nvgRGB(0x18, 0x19, 0x19), nvgRGB(0x21, 0x22, 0x22)));
+ nvgFill(args.vg);
+
+ nvgFontFaceId(args.vg, 0);
+ nvgFontSize(args.vg, 11);
+ nvgTextAlign(args.vg, NVG_ALIGN_CENTER);
+
+ nvgBeginPath(args.vg);
+ nvgRoundedRect(args.vg, startX_Out - 4.0f, startY - 2.0f, padding, padding * numIO, 4);
+ nvgFillColor(args.vg, nvgRGB(0xd0, 0xd0, 0xd0));
+ nvgFill(args.vg);
+
+ for (int i=0; i('0'+i+1),'\0'};
+ drawTextLine(args.vg, i, text);
+ }
+
+ ModuleWidget::draw(args);
+ }
+
+ void appendContextMenu(Menu* const menu) override {
+ menu->addChild(new MenuSeparator);
+ menu->addChild(createBoolPtrMenuItem("DC blocker", "", &module->dcFilterEnabled));
+ }
+};
+
+// --------------------------------------------------------------------------------------------------------------------
+
+Model* modelHostAudio2 = createModel, HostAudioWidget<2>>("HostAudio2");
+Model* modelHostAudio8 = createModel, HostAudioWidget<8>>("HostAudio8");
+
+// --------------------------------------------------------------------------------------------------------------------
diff --git a/plugins/Cardinal/src/HostCV.cpp b/plugins/Cardinal/src/HostCV.cpp
index f0e4202..36d7d45 100644
--- a/plugins/Cardinal/src/HostCV.cpp
+++ b/plugins/Cardinal/src/HostCV.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -24,6 +24,10 @@
USE_NAMESPACE_DISTRHO;
struct HostCV : Module {
+ CardinalPluginContext* const pcontext;
+ int dataFrame = 0;
+ int64_t lastBlockFrame = -1;
+
enum ParamIds {
BIPOLAR_INPUTS_1_5,
BIPOLAR_INPUTS_6_10,
@@ -42,62 +46,54 @@ struct HostCV : Module {
};
HostCV()
+ : pcontext(static_cast(APP))
{
+ if (pcontext == nullptr)
+ throw rack::Exception("Plugin context is null");
+
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
configParam(BIPOLAR_INPUTS_1_5, 0.f, 1.f, 0.f, "Bipolar Inputs 1-5")->randomizeEnabled = false;
configParam(BIPOLAR_INPUTS_6_10, 0.f, 1.f, 0.f, "Bipolar Inputs 6-10")->randomizeEnabled = false;
configParam(BIPOLAR_OUTPUTS_1_5, 0.f, 1.f, 0.f, "Bipolar Outputs 1-5")->randomizeEnabled = false;
configParam(BIPOLAR_OUTPUTS_6_10, 0.f, 1.f, 0.f, "Bipolar Outputs 6-10")->randomizeEnabled = false;
-
- CardinalPluginContext* const pcontext = static_cast(APP);
-
- if (pcontext == nullptr)
- throw rack::Exception("Plugin context is null.");
-
- if (pcontext->loadedHostCV)
- throw rack::Exception("Another instance of a Host CV module is already loaded, only one can be used at a time.");
-
- pcontext->loadedHostCV = true;
}
- ~HostCV() override
+ void process(const ProcessArgs&) override
{
- CardinalPluginContext* const pcontext = static_cast(APP);
- DISTRHO_SAFE_ASSERT_RETURN(pcontext != nullptr,);
+ if (pcontext->variant != kCardinalVariantMain)
+ return;
- pcontext->loadedHostCV = false;
- }
+ const float* const* const dataIns = pcontext->dataIns;
+ float** const dataOuts = pcontext->dataOuts;
- void process(const ProcessArgs&) override
- {
- if (CardinalPluginContext* const pcontext = static_cast(APP))
- {
- const float** dataIns = pcontext->dataIns;
- float** dataOuts = pcontext->dataOuts;
+ const int64_t blockFrame = pcontext->engine->getBlockFrame();
- if (dataIns == nullptr || dataOuts == nullptr)
- return;
+ if (lastBlockFrame != blockFrame)
+ {
+ dataFrame = 0;
+ lastBlockFrame = blockFrame;
+ }
- const uint32_t dataFrame = pcontext->dataFrame++;
- float inputOffset, outputOffset;
+ const int k = dataFrame++;
+ DISTRHO_SAFE_ASSERT_RETURN(k < pcontext->engine->getBlockFrames(),);
- 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;
+ 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;
- for (int i=0; i<5; ++i)
- {
- outputs[i].setVoltage(dataIns[i+CARDINAL_AUDIO_IO_OFFSET][dataFrame] - outputOffset);
- dataOuts[i+CARDINAL_AUDIO_IO_OFFSET][dataFrame] = inputs[i].getVoltage() + inputOffset;
- }
+ for (int i=0; i<5; ++i)
+ {
+ outputs[i].setVoltage(dataIns[i+CARDINAL_AUDIO_IO_OFFSET][k] - outputOffset);
+ dataOuts[i+CARDINAL_AUDIO_IO_OFFSET][k] = inputs[i].getVoltage() + inputOffset;
+ }
- inputOffset = params[BIPOLAR_INPUTS_6_10].getValue() > 0.1f ? 5.0f : 0.0f;
- outputOffset = params[BIPOLAR_OUTPUTS_6_10].getValue() > 0.1f ? 5.0f : 0.0f;
+ inputOffset = params[BIPOLAR_INPUTS_6_10].getValue() > 0.1f ? 5.0f : 0.0f;
+ outputOffset = params[BIPOLAR_OUTPUTS_6_10].getValue() > 0.1f ? 5.0f : 0.0f;
- for (int i=5; i<10; ++i)
- {
- outputs[i].setVoltage(dataIns[i+CARDINAL_AUDIO_IO_OFFSET][dataFrame] - outputOffset);
- dataOuts[i+CARDINAL_AUDIO_IO_OFFSET][dataFrame] = inputs[i].getVoltage() + inputOffset;
- }
+ for (int i=5; i<10; ++i)
+ {
+ outputs[i].setVoltage(dataIns[i+CARDINAL_AUDIO_IO_OFFSET][k] - outputOffset);
+ dataOuts[i+CARDINAL_AUDIO_IO_OFFSET][k] = inputs[i].getVoltage() + inputOffset;
}
}
};
diff --git a/plugins/Cardinal/src/HostParameters.cpp b/plugins/Cardinal/src/HostParameters.cpp
index 2ad13eb..aaf442b 100644
--- a/plugins/Cardinal/src/HostParameters.cpp
+++ b/plugins/Cardinal/src/HostParameters.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -36,6 +36,7 @@ struct HostParameters : Module {
};
rack::dsp::SlewLimiter parameters[kModuleParameters];
+ bool parametersConnected[kModuleParameters] = {};
float sampleTime = 0.0f;
HostParameters()
@@ -60,7 +61,18 @@ struct HostParameters : Module {
if (const CardinalPluginContext* const pcontext = static_cast(APP))
{
for (uint32_t i=0; iparameters[i]));
+ {
+ const bool connected = outputs[i].isConnected();
+
+ if (parametersConnected[i] != connected)
+ {
+ parametersConnected[i] = connected;
+ parameters[i].reset();
+ }
+
+ if (connected)
+ outputs[i].setVoltage(parameters[i].process(sampleTime, pcontext->parameters[i]));
+ }
}
}
diff --git a/plugins/Cardinal/src/plugin.hpp b/plugins/Cardinal/src/plugin.hpp
index cdc93a0..436e91a 100644
--- a/plugins/Cardinal/src/plugin.hpp
+++ b/plugins/Cardinal/src/plugin.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -31,6 +31,8 @@ extern Model* modelAudioFile;
extern Model* modelCarla;
extern Model* modelCardinalBlank;
extern Model* modelGlBars;
+extern Model* modelHostAudio2;
+extern Model* modelHostAudio8;
extern Model* modelHostCV;
extern Model* modelHostParameters;
extern Model* modelHostTime;
diff --git a/plugins/Cardinal/src/plugincontext.hpp b/plugins/Cardinal/src/plugincontext.hpp
index 803e721..618e981 100644
--- a/plugins/Cardinal/src/plugincontext.hpp
+++ b/plugins/Cardinal/src/plugincontext.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -33,6 +33,12 @@ START_NAMESPACE_DISTRHO
static constexpr const uint32_t kModuleParameters = 24;
+enum CardinalVariant {
+ kCardinalVariantMain,
+ kCardinalVariantFX,
+ kCardinalVariantSynth,
+};
+
class Plugin;
class UI;
@@ -40,14 +46,14 @@ struct CardinalPluginContext : rack::Context {
uint32_t bufferSize;
double sampleRate;
float parameters[kModuleParameters];
- bool playing, reset, bbtValid, loadedHostCV;
+ CardinalVariant variant;
+ bool playing, reset, bbtValid;
int32_t bar, beat, beatsPerBar, beatType;
uint64_t frame;
double barStartTick, beatsPerMinute;
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
uintptr_t nativeWindowId;
- uint32_t dataFrame;
- const float** dataIns;
+ const float* const* dataIns;
float** dataOuts;
Plugin* const plugin;
#ifndef HEADLESS
diff --git a/plugins/Makefile b/plugins/Makefile
index 3b0e745..3a96dc6 100644
--- a/plugins/Makefile
+++ b/plugins/Makefile
@@ -188,6 +188,7 @@ PLUGIN_FILES = plugins.cpp
PLUGIN_FILES += Cardinal/src/Blank.cpp
PLUGIN_FILES += Cardinal/src/glBars.cpp
+PLUGIN_FILES += Cardinal/src/HostAudio.cpp
PLUGIN_FILES += Cardinal/src/HostCV.cpp
PLUGIN_FILES += Cardinal/src/HostParameters.cpp
PLUGIN_FILES += Cardinal/src/HostTime.cpp
diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp
index a487e9d..d8f3d10 100644
--- a/plugins/plugins.cpp
+++ b/plugins/plugins.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -679,6 +679,8 @@ static void initStatic__Cardinal()
{
p->addModel(modelCardinalBlank);
p->addModel(modelGlBars);
+ p->addModel(modelHostAudio2);
+ p->addModel(modelHostAudio8);
p->addModel(modelHostCV);
p->addModel(modelHostParameters);
p->addModel(modelHostTime);
diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp
index b377fbb..bb73bbb 100644
--- a/src/CardinalPlugin.cpp
+++ b/src/CardinalPlugin.cpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -182,9 +182,6 @@ struct Initializer
"Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str());
}
- INFO("Initializing audio driver");
- audio::addDriver(0, new CardinalAudioDriver);
-
INFO("Initializing midi driver");
midi::addDriver(0, new CardinalMidiDriver);
@@ -336,14 +333,11 @@ class CardinalPlugin : public CardinalBasePlugin
{
SharedResourcePointer fInitializer;
- float* fAudioBufferIn;
- float* fAudioBufferOut;
+ float** fAudioBufferCopy;
std::string fAutosavePath;
String fWindowSize;
// for base/context handling
- bool fIsActive;
- CardinalAudioDevice* fCurrentAudioDevice;
CardinalMidiInputDevice** fCurrentMidiInputs;
CardinalMidiOutputDevice** fCurrentMidiOutputs;
uint64_t fPreviousFrame;
@@ -358,10 +352,7 @@ public:
CardinalPlugin()
: CardinalBasePlugin(kModuleParameters + kWindowParameterCount, 0, kCardinalStateCount),
fInitializer(this),
- fAudioBufferIn(nullptr),
- fAudioBufferOut(nullptr),
- fIsActive(false),
- fCurrentAudioDevice(nullptr),
+ fAudioBufferCopy(nullptr),
fCurrentMidiInputs(nullptr),
fCurrentMidiOutputs(nullptr),
fPreviousFrame(0)
@@ -443,7 +434,6 @@ public:
{
const MutexLocker cml(fDeviceMutex);
- fCurrentAudioDevice = nullptr;
delete[] fCurrentMidiInputs;
fCurrentMidiInputs = nullptr;
delete[] fCurrentMidiOutputs;
@@ -463,36 +453,6 @@ protected:
/* --------------------------------------------------------------------------------------------------------
* Cardinal Base things */
- bool isActive() const noexcept override
- {
- return fIsActive;
- }
-
- bool canAssignAudioDevice() const noexcept override
- {
- const MutexLocker cml(fDeviceMutex);
- return fCurrentAudioDevice == nullptr;
- }
-
- void assignAudioDevice(CardinalAudioDevice* const dev) noexcept override
- {
- DISTRHO_SAFE_ASSERT_RETURN(fCurrentAudioDevice == nullptr,);
-
- const MutexLocker cml(fDeviceMutex);
- fCurrentAudioDevice = dev;
- }
-
- bool clearAudioDevice(CardinalAudioDevice* const dev) noexcept override
- {
- const MutexLocker cml(fDeviceMutex);
-
- if (fCurrentAudioDevice != dev)
- return false;
-
- fCurrentAudioDevice = nullptr;
- return true;
- }
-
void assignMidiInputDevice(CardinalMidiInputDevice* const dev) noexcept override
{
CardinalMidiInputDevice** const oldDevs = fCurrentMidiInputs;
@@ -625,13 +585,15 @@ protected:
int64_t getUniqueId() const override
{
-#if CARDINAL_VARIANT_SYNTH
- return d_cconst('d', 'C', 'n', 'S');
-#elif CARDINAL_VARIANT_FX
- return d_cconst('d', 'C', 'n', 'F');
-#else
+ #if CARDINAL_VARIANT_MAIN
return d_cconst('d', 'C', 'd', 'n');
-#endif
+ #elif CARDINAL_VARIANT_FX
+ return d_cconst('d', 'C', 'n', 'F');
+ #elif CARDINAL_VARIANT_SYNTH
+ return d_cconst('d', 'C', 'n', 'S');
+ #else
+ #error cardinal variant not set
+ #endif
}
/* --------------------------------------------------------------------------------------------------------
@@ -892,42 +854,25 @@ protected:
void activate() override
{
+ #if DISTRHO_PLUGIN_NUM_INPUTS != 0
const uint32_t bufferSize = getBufferSize();
- fAudioBufferOut = new float[bufferSize * DISTRHO_PLUGIN_NUM_OUTPUTS];
-
- const uint32_t numInputs = std::max(1, DISTRHO_PLUGIN_NUM_INPUTS);
- fAudioBufferIn = new float[bufferSize * numInputs];
- std::memset(fAudioBufferIn, 0, sizeof(float)*bufferSize * numInputs);
+ fAudioBufferCopy = new float*[DISTRHO_PLUGIN_NUM_INPUTS];
+ for (int i=0; ionStartStream();
- }
- }
}
void deactivate() override
{
+ if (fAudioBufferCopy != nullptr)
{
- const MutexLocker cml(fDeviceMutex);
-
- if (fCurrentAudioDevice != nullptr)
- {
- rack::contextSet(context);
- fCurrentAudioDevice->onStopStream();
- }
+ for (int i=0; ihandleMessagesFromHost(midiEvents, midiEventCount);
}
- if (fCurrentAudioDevice != nullptr)
+ // separate buffers, use them
+ if (inputs != outputs && (inputs == nullptr || inputs[0] != outputs[0]))
{
-#if CARDINAL_NUM_AUDIO_INPUTS != 0
- for (uint32_t i=0, j=0; iprocessInput(fAudioBufferIn, CARDINAL_NUM_AUDIO_INPUTS, frames);
-#else
- std::memset(fAudioBufferIn, 0, sizeof(float)*frames);
- fCurrentAudioDevice->processInput(fAudioBufferIn, 1, frames);
-#endif
- }
-
-#if CARDINAL_VARIANT_MAIN
- context->dataFrame = 0;
- context->dataIns = inputs;
- context->dataOuts = outputs;
-#endif
-
- context->engine->stepBlock(frames);
-
- if (fCurrentAudioDevice != nullptr)
- {
- std::memset(fAudioBufferOut, 0, sizeof(float)*frames*CARDINAL_NUM_AUDIO_OUTPUTS);
- fCurrentAudioDevice->processOutput(fAudioBufferOut, CARDINAL_NUM_AUDIO_OUTPUTS, frames);
-
- for (uint32_t i=0, j=0; idataIns = inputs;
+ context->dataOuts = outputs;
}
+ // inline processing, use a safe copy
else
{
- for (uint32_t k=0; kdataIns = fAudioBufferCopy;
+ context->dataOuts = outputs;
}
+
+ for (int i=0; iengine->stepBlock(frames);
}
void bufferSizeChanged(const uint32_t newBufferSize) override
diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp
index 96c0051..4d261a6 100644
--- a/src/PluginContext.hpp
+++ b/src/PluginContext.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -39,20 +39,26 @@ START_NAMESPACE_DISTRHO
static constexpr const uint kModuleParameters = 24;
+enum CardinalVariant {
+ kCardinalVariantMain,
+ kCardinalVariantFX,
+ kCardinalVariantSynth,
+};
+
// -----------------------------------------------------------------------------------------------------------
struct CardinalPluginContext : rack::Context {
uint32_t bufferSize;
double sampleRate;
float parameters[kModuleParameters];
- bool playing, reset, bbtValid, loadedHostCV;
+ CardinalVariant variant;
+ bool playing, reset, bbtValid;
int32_t bar, beat, beatsPerBar, beatType;
uint64_t frame;
double barStartTick, beatsPerMinute;
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
uintptr_t nativeWindowId;
- uint32_t dataFrame;
- const float** dataIns;
+ const float* const* dataIns;
float** dataOuts;
Plugin* const plugin;
#ifndef HEADLESS
@@ -62,10 +68,18 @@ struct CardinalPluginContext : rack::Context {
CardinalPluginContext(Plugin* const p)
: bufferSize(p->getBufferSize()),
sampleRate(p->getSampleRate()),
+ #if CARDINAL_VARIANT_MAIN
+ variant(kCardinalVariantMain),
+ #elif CARDINAL_VARIANT_FX
+ variant(kCardinalVariantFX),
+ #elif CARDINAL_VARIANT_SYNTH
+ variant(kCardinalVariantSynth),
+ #else
+ #error cardinal variant not set
+ #endif
playing(false),
reset(false),
bbtValid(false),
- loadedHostCV(false),
bar(1),
beat(1),
beatsPerBar(4),
@@ -79,7 +93,6 @@ struct CardinalPluginContext : rack::Context {
ticksPerClock(0.0),
ticksPerFrame(0.0),
nativeWindowId(0),
- dataFrame(0),
dataIns(nullptr),
dataOuts(nullptr),
plugin(p)
@@ -116,10 +129,6 @@ public:
: Plugin(parameterCount, programCount, stateCount),
context(new CardinalPluginContext(this)) {}
~CardinalBasePlugin() override {}
- virtual bool isActive() const noexcept = 0;
- virtual bool canAssignAudioDevice() const noexcept = 0;
- virtual bool clearAudioDevice(CardinalAudioDevice* dev) noexcept = 0;
- virtual void assignAudioDevice(CardinalAudioDevice* dev) noexcept = 0;
virtual void assignMidiInputDevice(CardinalMidiInputDevice* dev) noexcept = 0;
virtual void assignMidiOutputDevice(CardinalMidiOutputDevice* dev) noexcept = 0;
virtual void clearMidiInputDevice(CardinalMidiInputDevice* dev) noexcept = 0;
diff --git a/src/PluginDriver.hpp b/src/PluginDriver.hpp
index c0a234d..d9d21dc 100644
--- a/src/PluginDriver.hpp
+++ b/src/PluginDriver.hpp
@@ -1,6 +1,6 @@
/*
* DISTRHO Cardinal Plugin
- * Copyright (C) 2021 Filipe Coelho
+ * Copyright (C) 2021-2022 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -23,145 +23,6 @@ START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
-struct CardinalAudioDevice : rack::audio::Device
-{
- CardinalBasePlugin* const fPlugin;
-
- CardinalAudioDevice(CardinalBasePlugin* const plugin)
- : fPlugin(plugin) {}
-
- std::string getName() override
- {
- return "Cardinal";
- }
-
- int getNumInputs() override
- {
- return CARDINAL_NUM_AUDIO_INPUTS;
- }
-
- int getNumOutputs() override
- {
- return CARDINAL_NUM_AUDIO_OUTPUTS;
- }
-
- int getBlockSize() override
- {
- return fPlugin->getBufferSize();
- }
-
- float getSampleRate() override
- {
- return fPlugin->getSampleRate();
- }
-
- std::set getBlockSizes() override
- {
- return std::set({ getBlockSize() });
- }
-
- std::set getSampleRates() override
- {
- return std::set({ getSampleRate() });
- }
-
- void setBlockSize(int) override {}
- void setSampleRate(float) override {}
-
- void processInput(const float* const input, const int inputStride, const int frames)
- {
- for (rack::audio::Port* port : subscribed)
- port->processInput(input + port->inputOffset, inputStride, frames);
- }
-
- void processOutput(float* const output, const int outputStride, const int frames)
- {
- for (rack::audio::Port* port : subscribed)
- port->processOutput(output + port->outputOffset, outputStride, frames);
- }
-};
-
-// -----------------------------------------------------------------------------------------------------------
-
-struct CardinalAudioDriver : rack::audio::Driver
-{
- CardinalAudioDriver() {}
-
- std::string getName() override
- {
- return "Plugin Driver";
- }
-
- std::vector getDeviceIds() override
- {
- return std::vector({ 0 });
- }
-
- int getDefaultDeviceId() override
- {
- return 0;
- }
-
- std::string getDeviceName(int) override
- {
- return "Plugin Device";
- }
-
- int getDeviceNumInputs(int) override
- {
- return CARDINAL_NUM_AUDIO_INPUTS;
- }
-
- int getDeviceNumOutputs(int) override
- {
- return CARDINAL_NUM_AUDIO_OUTPUTS;
- }
-
- rack::audio::Device* subscribe(int, rack::audio::Port* const port) override
- {
- CardinalPluginContext* const pluginContext = reinterpret_cast(port->context);
- DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr, nullptr);
-
- CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin);
- DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr);
-
- if (! plugin->canAssignAudioDevice())
- throw rack::Exception("Plugin driver only allows one audio device to be used simultaneously");
-
- CardinalAudioDevice* const device = new CardinalAudioDevice(plugin);
- device->subscribe(port);
-
- if (plugin->isActive())
- device->onStartStream();
-
- plugin->assignAudioDevice(device);
- return device;
- }
-
- void unsubscribe(int, rack::audio::Port* const port) override
- {
- CardinalAudioDevice* const device = reinterpret_cast(port->device);
- DISTRHO_SAFE_ASSERT_RETURN(device != nullptr,);
-
- CardinalPluginContext* const pluginContext = reinterpret_cast(port->context);
- DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr,);
-
- CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin);
- DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr,);
-
- if (plugin->clearAudioDevice(device))
- {
- if (plugin->isActive())
- device->onStopStream();
-
- device->unsubscribe(port);
- delete device;
- }
- }
-};
-
-// -----------------------------------------------------------------------------------------------------------
-
struct CardinalMidiInputDevice : rack::midi::InputDevice
{
CardinalBasePlugin* const fPlugin;
diff --git a/src/template.vcv b/src/template.vcv
index b6f65d5..e19bcdc 100644
--- a/src/template.vcv
+++ b/src/template.vcv
@@ -4,8 +4,8 @@
"modules": [
{
"id": 1,
- "plugin": "Core",
- "model": "AudioInterface2",
+ "plugin": "Cardinal",
+ "model": "HostAudio2",
"version": "2.0",
"params": [
{
@@ -15,14 +15,6 @@
],
"rightModuleId": 2,
"data": {
- "audio": {
- "driver": 0,
- "deviceName": "Cardinal",
- "sampleRate": 48000.0,
- "blockSize": 512,
- "inputOffset": 0,
- "outputOffset": 0
- },
"dcFilter": true
},
"pos": [