diff --git a/plugins/Cardinal/plugin.json b/plugins/Cardinal/plugin.json
index 80c8f6b..22f67f4 100644
--- a/plugins/Cardinal/plugin.json
+++ b/plugins/Cardinal/plugin.json
@@ -11,5 +11,25 @@
"manualUrl": "https://github.com/DISTRHO/Cardinal/wiki",
"sourceUrl": "https://github.com/DISTRHO/Cardinal",
"changelogUrl": "",
- "modules": []
+ "modules":
+ [
+ {
+ "slug": "HostParameters",
+ "disabled": false,
+ "name": "Host Parameters",
+ "description": "Exposes host-controlled plugin parameters as module",
+ "tags": [
+ "Utility"
+ ]
+ },
+ {
+ "slug": "HostTime",
+ "disabled": false,
+ "name": "Host Time",
+ "description": "Exposes host-provided timing information as module",
+ "tags": [
+ "Utility"
+ ]
+ }
+ ]
}
diff --git a/plugins/Cardinal/res/HostParameters.svg b/plugins/Cardinal/res/HostParameters.svg
new file mode 100644
index 0000000..6d5ce0c
--- /dev/null
+++ b/plugins/Cardinal/res/HostParameters.svg
@@ -0,0 +1,237 @@
+
+
+
+
diff --git a/plugins/Cardinal/res/distrho.svg b/plugins/Cardinal/res/distrho.svg
new file mode 100644
index 0000000..30b9d9b
--- /dev/null
+++ b/plugins/Cardinal/res/distrho.svg
@@ -0,0 +1,99 @@
+
+
+
+
\ No newline at end of file
diff --git a/plugins/Cardinal/src/HostParameters.cpp b/plugins/Cardinal/src/HostParameters.cpp
index 75f2de6..c56cd5c 100644
--- a/plugins/Cardinal/src/HostParameters.cpp
+++ b/plugins/Cardinal/src/HostParameters.cpp
@@ -17,6 +17,26 @@
#include "plugin.hpp"
+// -----------------------------------------------------------------------------------------------------------
+// from PluginContext.hpp
+
+namespace DISTRHO {
+
+static constexpr const uint kModuleParameters = 24;
+
+struct CardinalPluginContext : rack::Context {
+ uint32_t bufferSize;
+ double sampleRate;
+ float parameters[kModuleParameters];
+ // more stuff follows, but we dont care..
+};
+
+}
+
+using namespace DISTRHO;
+
+// -----------------------------------------------------------------------------------------------------------
+
struct HostParameters : Module {
enum ParamIds {
NUM_PARAMS
@@ -25,18 +45,55 @@ struct HostParameters : Module {
NUM_INPUTS
};
enum OutputIds {
- NUM_OUTPUTS
+ NUM_OUTPUTS = 24
};
enum LightIds {
NUM_LIGHTS
};
- HostParameters() {
+ rack::dsp::SlewLimiter parameters[kModuleParameters];
+ float sampleTime = 0.0f;
+
+ HostParameters()
+ {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
+
+ CardinalPluginContext* const pcontext = reinterpret_cast(APP);
+
+ if (pcontext == nullptr)
+ throw rack::Exception("Plugin context is null.");
+
+ const float fsampleRate = static_cast(pcontext->sampleRate);
+ SampleRateChangeEvent e = {
+ fsampleRate,
+ 1.0f / fsampleRate
+ };
+ onSampleRateChange(e);
}
- void process(const ProcessArgs&) override {
- // TODO
+ void process(const ProcessArgs&) override
+ {
+ if (CardinalPluginContext* const pcontext = reinterpret_cast(APP))
+ {
+ for (uint i=0; iparameters[i]));
+ }
+ }
+
+ void onSampleRateChange(const SampleRateChangeEvent& e) override
+ {
+ if (CardinalPluginContext* const pcontext = reinterpret_cast(APP))
+ {
+ const double fall = 1.0 / (double(pcontext->bufferSize) / e.sampleRate);
+
+ for (uint i=0; iwindow->loadSvg(asset::plugin(pluginInstance, "res/HostParameters.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)));
+
+ const float startX = 10.0f;
+ const float startY = 170.0f;
+ const float padding = 30.0f;
+
+ for (int i=0; i<24; ++i)
+ {
+ const float x = startX + int(i / 6) * padding;
+ const float y = startY + int(i % 6) * padding;
+ addOutput(createOutput(Vec(x, y), module, i));
+ }
}
};
diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp
index df7bf86..925c744 100644
--- a/plugins/plugins.cpp
+++ b/plugins/plugins.cpp
@@ -769,9 +769,8 @@ static void initStatic__Cardinal()
const StaticPluginLoader spl(p, "Cardinal");
if (spl.ok())
{
- // TODO implement these
- // p->addModel(modelHostParameters);
- // p->addModel(modelHostTime);
+ p->addModel(modelHostParameters);
+ p->addModel(modelHostTime);
}
}
diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp
index 99d3d6d..ff932cf 100644
--- a/src/CardinalPlugin.cpp
+++ b/src/CardinalPlugin.cpp
@@ -119,7 +119,6 @@ static const Initializer& getInitializerInstance()
class CardinalPlugin : public CardinalBasePlugin
{
- CardinalPluginContext* const fContext;
float* fAudioBufferIn;
float* fAudioBufferOut;
std::string fAutosavePath;
@@ -129,15 +128,15 @@ class CardinalPlugin : public CardinalBasePlugin
rack::audio::Device* fCurrentDevice;
Mutex fDeviceMutex;
- float fParameters[kModuleParameters + kWindowParameterCount];
+ float fWindowParameters[kWindowParameterCount];
struct ScopedContext {
const MutexLocker cml;
ScopedContext(const CardinalPlugin* const plugin)
- : cml(plugin->contextMutex)
+ : cml(plugin->context->mutex)
{
- rack::contextSet(plugin->fContext);
+ rack::contextSet(plugin->context);
}
~ScopedContext()
@@ -149,18 +148,15 @@ class CardinalPlugin : public CardinalBasePlugin
public:
CardinalPlugin()
: CardinalBasePlugin(kModuleParameters + kWindowParameterCount, 0, 1),
- fContext(new CardinalPluginContext(this)),
fAudioBufferIn(nullptr),
fAudioBufferOut(nullptr),
fIsActive(false),
fCurrentDevice(nullptr)
{
- std::memset(fParameters, 0, sizeof(fParameters));
-
- fParameters[kModuleParameters + kWindowParameterCableOpacity] = 50.0f;
- fParameters[kModuleParameters + kWindowParameterCableTension] = 50.0f;
- fParameters[kModuleParameters + kWindowParameterRackBrightness] = 100.0f;
- fParameters[kModuleParameters + kWindowParameterHaloBrightness] = 25.0f;
+ fWindowParameters[kWindowParameterCableOpacity] = 50.0f;
+ fWindowParameters[kWindowParameterCableTension] = 50.0f;
+ fWindowParameters[kWindowParameterRackBrightness] = 100.0f;
+ fWindowParameters[kWindowParameterHaloBrightness] = 25.0f;
// create unique temporary path for this instance
try {
@@ -183,18 +179,18 @@ public:
const ScopedContext sc(this);
- fContext->engine = new rack::engine::Engine;
- fContext->history = new rack::history::State;
- fContext->patch = new rack::patch::Manager;
- fContext->patch->autosavePath = fAutosavePath;
- fContext->patch->templatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "template.vcv";
+ context->engine = new rack::engine::Engine;
+ context->history = new rack::history::State;
+ context->patch = new rack::patch::Manager;
+ context->patch->autosavePath = fAutosavePath;
+ context->patch->templatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "template.vcv";
- fContext->event = new rack::widget::EventState;
- fContext->scene = new rack::app::Scene;
- fContext->event->rootWidget = fContext->scene;
+ context->event = new rack::widget::EventState;
+ context->scene = new rack::app::Scene;
+ context->event->rootWidget = context->scene;
- fContext->patch->loadTemplate();
- fContext->engine->startFallbackThread();
+ context->patch->loadTemplate();
+ context->engine->startFallbackThread();
}
~CardinalPlugin() override
@@ -202,13 +198,13 @@ public:
{
const ScopedContext sc(this);
/*
- delete fContext->scene;
- fContext->scene = nullptr;
+ delete context->scene;
+ context->scene = nullptr;
- delete fContext->event;
- fContext->event = nullptr;
+ delete context->event;
+ context->event = nullptr;
*/
- delete fContext;
+ delete context;
}
if (! fAutosavePath.empty())
@@ -217,7 +213,7 @@ public:
CardinalPluginContext* getRackContext() const noexcept
{
- return fContext;
+ return context;
}
protected:
@@ -365,14 +361,34 @@ protected:
/* --------------------------------------------------------------------------------------------------------
* Internal data */
- float getParameterValue(const uint32_t index) const override
+ float getParameterValue(uint32_t index) const override
{
- return fParameters[index];
+ if (index < kModuleParameters)
+ return context->parameters[index];
+
+ index -= kModuleParameters;
+
+ if (index < kWindowParameterCount)
+ return fWindowParameters[index];
+
+ return 0.0f;
}
- void setParameterValue(const uint32_t index, float value) override
+ void setParameterValue(uint32_t index, float value) override
{
- fParameters[index] = value;
+ if (index < kModuleParameters)
+ {
+ context->parameters[index] = value;
+ return;
+ }
+
+ index -= kModuleParameters;
+
+ if (index < kWindowParameterCount)
+ {
+ fWindowParameters[index] = value;
+ return;
+ }
}
String getState(const char* const key) const override
@@ -387,9 +403,9 @@ protected:
{
const ScopedContext sc(this);
- fContext->engine->prepareSave();
- fContext->patch->saveAutosave();
- fContext->patch->cleanAutosave();
+ context->engine->prepareSave();
+ context->patch->saveAutosave();
+ context->patch->cleanAutosave();
data = rack::system::archiveDirectory(fAutosavePath, 1);
}
@@ -412,7 +428,7 @@ protected:
rack::system::createDirectories(fAutosavePath);
rack::system::unarchiveToDirectory(data, fAutosavePath);
- fContext->patch->loadAutosave();
+ context->patch->loadAutosave();
}
/* --------------------------------------------------------------------------------------------------------
@@ -450,8 +466,8 @@ protected:
void run(const float** const inputs, float** const outputs, const uint32_t frames) override
{
/*
- fContext->engine->setFrame(getTimePosition().frame);
- fContext->engine->stepBlock(frames);
+ context->engine->setFrame(getTimePosition().frame);
+ context->engine->stepBlock(frames);
*/
const MutexLocker cml(fDeviceMutex);
@@ -482,13 +498,6 @@ protected:
}
}
- /*
- void sampleRateChanged(const double newSampleRate) override
- {
- fContext->engine->setSampleRate(newSampleRate);
- }
- */
-
// -------------------------------------------------------------------------------------------------------
private:
diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp
index c47da0d..76ddc40 100644
--- a/src/CardinalUI.cpp
+++ b/src/CardinalUI.cpp
@@ -63,7 +63,7 @@ class CardinalUI : public UI,
ScopedContext(CardinalUI* const ui)
: context(ui->fContext),
- cml(context->plugin->contextMutex)
+ cml(context->mutex)
{
rack::contextSet(context);
WindowParametersRestore(context->window);
@@ -71,7 +71,7 @@ class CardinalUI : public UI,
ScopedContext(CardinalUI* const ui, const int mods)
: context(ui->fContext),
- cml(context->plugin->contextMutex)
+ cml(context->mutex)
{
rack::contextSet(context);
rack::window::WindowMods(context->window, mods);
diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp
index 6b62074..bfbfae6 100644
--- a/src/PluginContext.hpp
+++ b/src/PluginContext.hpp
@@ -33,27 +33,51 @@ START_NAMESPACE_DISTRHO
static constexpr const uint kModuleParameters = 24;
+// -----------------------------------------------------------------------------------------------------------
+
+struct CardinalPluginContext : rack::Context {
+ uint32_t bufferSize;
+ double sampleRate;
+ float parameters[kModuleParameters];
+
+ Mutex mutex;
+ Plugin* const plugin;
+
+ CardinalPluginContext(Plugin* const p)
+ : bufferSize(p->getBufferSize()),
+ sampleRate(p->getSampleRate()),
+ plugin(p)
+ {
+ std::memset(parameters, 0, sizeof(parameters));
+ }
+};
+
+// -----------------------------------------------------------------------------------------------------------
+
class CardinalBasePlugin : public Plugin {
public:
+ CardinalPluginContext* const context;
+
CardinalBasePlugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount)
- : Plugin(parameterCount, programCount, stateCount) {}
+ : Plugin(parameterCount, programCount, stateCount),
+ context(new CardinalPluginContext(this)) {}
~CardinalBasePlugin() override {}
virtual bool isActive() const noexcept = 0;
virtual bool canAssignDevice() const noexcept = 0;
virtual void assignDevice(rack::audio::Device* dev) noexcept = 0;
virtual bool clearDevice(rack::audio::Device* dev) noexcept = 0;
- // ensure context validity through UI and setState
- Mutex contextMutex;
-};
+protected:
+ void bufferSizeChanged(const uint32_t newBufferSize) override
+ {
+ context->bufferSize = newBufferSize;
+ }
-// -----------------------------------------------------------------------------------------------------------
-
-struct CardinalPluginContext : rack::Context {
- CardinalBasePlugin* const plugin;
-
- CardinalPluginContext(CardinalBasePlugin* const p)
- : plugin(p) {}
+ void sampleRateChanged(const double newSampleRate) override
+ {
+ context->sampleRate = newSampleRate;
+ // context->engine->setSampleRate(newSampleRate);
+ }
};
// -----------------------------------------------------------------------------------------------------------
@@ -144,7 +168,7 @@ struct CardinalAudioDriver : rack::audio::Driver {
CardinalPluginContext* const pluginContext = reinterpret_cast(port->context);
DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr, nullptr);
- CardinalBasePlugin* const plugin = pluginContext->plugin;
+ CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin);
DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr);
if (! plugin->canAssignDevice())
@@ -168,7 +192,7 @@ struct CardinalAudioDriver : rack::audio::Driver {
CardinalPluginContext* const pluginContext = reinterpret_cast(port->context);
DISTRHO_SAFE_ASSERT_RETURN(pluginContext != nullptr,);
- CardinalBasePlugin* const plugin = pluginContext->plugin;
+ CardinalBasePlugin* const plugin = reinterpret_cast(pluginContext->plugin);
DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr,);
if (plugin->clearDevice(device))
diff --git a/src/template.vcv b/src/template.vcv
index 6791d96..73b50de 100644
--- a/src/template.vcv
+++ b/src/template.vcv
@@ -1,5 +1,11 @@
{
"version": "2.0",
+ "unsaved": true,
+ "zoom": 1.0,
+ "gridOffset": [
+ -3.5333333015441895,
+ -0.078947365283966064
+ ],
"modules": [
{
"id": 1,
@@ -12,10 +18,11 @@
"id": 0
}
],
+ "rightModuleId": 4245168092954973,
"data": {
"audio": {
"driver": 0,
- "deviceName": "Plugin Device",
+ "deviceName": "Cardinal",
"sampleRate": 48000.0,
"blockSize": 512,
"inputOffset": 0,
@@ -27,8 +34,20 @@
0,
0
]
+ },
+ {
+ "id": 4245168092954973,
+ "plugin": "Cardinal",
+ "model": "HostParameters",
+ "version": "2.0",
+ "params": [],
+ "leftModuleId": 1,
+ "pos": [
+ 5,
+ 0
+ ]
}
],
"cables": [],
"masterModuleId": 1
-}
+}
\ No newline at end of file