Browse Source

A few more details for mini variant

Signed-off-by: falkTX <falktx@falktx.com>
tags/23.02
falkTX 2 years ago
parent
commit
a53f15af77
13 changed files with 361 additions and 74 deletions
  1. +119
    -0
      patches/init/mini.vcv
  2. +12
    -4
      plugins/Makefile
  3. +42
    -0
      plugins/plugins-mini.cpp
  4. +47
    -29
      src/CardinalCommon.cpp
  5. +5
    -0
      src/CardinalCommon.hpp
  6. +19
    -0
      src/CardinalMini/CardinalCommon-UI.cpp
  7. +0
    -1
      src/CardinalMini/CardinalCommon.cpp
  8. +19
    -0
      src/CardinalMini/CardinalCommon.cpp
  9. +27
    -2
      src/CardinalPlugin.cpp
  10. +52
    -13
      src/CardinalUI.cpp
  11. +1
    -3
      src/Makefile.cardinal.mk
  12. +0
    -4
      src/PluginContext.hpp
  13. +18
    -18
      src/custom/RemoteNanoVG.cpp

+ 119
- 0
patches/init/mini.vcv View File

@@ -0,0 +1,119 @@
{
"version": "2.1",
"zoom": 1.0,
"modules": [
{
"id": 2799203590388841,
"plugin": "Cardinal",
"model": "TextEditor",
"version": "2.0",
"params": [],
"leftModuleId": 4,
"data": {
"filepath": "",
"lang": "None",
"etext": "Welcome to Cardinal!\n\nThis is the mini variant\nIt has 2 audio ports, 5 CV ports, plus MIDI\n\nThe most relevant modules for host\nintegration are in this default patch\n\nHave fun!\n\n",
"width": 23
},
"pos": [
42,
0
]
},
{
"id": 2,
"plugin": "Cardinal",
"model": "HostMIDI",
"version": "2.0",
"params": [],
"leftModuleId": 7249509538355161,
"rightModuleId": 3,
"data": {
"pwRange": 0.0,
"smooth": false,
"channels": 1,
"polyMode": 0,
"lastPitch": 8192,
"lastMod": 0,
"inputChannel": 0,
"outputChannel": 0
},
"pos": [
16,
0
]
},
{
"id": 3,
"plugin": "Cardinal",
"model": "HostTime",
"version": "2.0",
"params": [],
"leftModuleId": 2,
"rightModuleId": 4,
"pos": [
25,
0
]
},
{
"id": 4,
"plugin": "Cardinal",
"model": "HostParameters",
"version": "2.0",
"params": [],
"leftModuleId": 3,
"rightModuleId": 2799203590388841,
"pos": [
33,
0
]
},
{
"id": 7249509538355161,
"plugin": "Cardinal",
"model": "HostCV",
"version": "2.0",
"params": [
{
"value": 0.0,
"id": 0
},
{
"value": 0.0,
"id": 1
},
{
"value": 0.0,
"id": 2
},
{
"value": 0.0,
"id": 3
}
],
"leftModuleId": 3606136179759592,
"rightModuleId": 2,
"pos": [
8,
0
]
},
{
"id": 3606136179759592,
"plugin": "Cardinal",
"model": "HostAudio2",
"version": "2.0",
"params": [],
"rightModuleId": 7249509538355161,
"data": {
"dcFilter": false
},
"pos": [
0,
0
]
}
],
"cables": []
}

+ 12
- 4
plugins/Makefile View File

@@ -311,6 +311,11 @@ endif
PLUGIN_FILES += $(filter-out Fundamental/src/plugin.cpp,$(wildcard Fundamental/src/*.cpp))
PLUGIN_FILES += Fundamental/src/dr_wav.c

MINIPLUGIN_FILES += Fundamental/src/ADSR.cpp
MINIPLUGIN_FILES += Fundamental/src/LFO.cpp
MINIPLUGIN_FILES += Fundamental/src/VCF.cpp
MINIPLUGIN_FILES += Fundamental/src/VCO.cpp

# modules/types which are present in other plugins
FUNDAMENTAL_CUSTOM = $(DRWAV)

@@ -1294,7 +1299,7 @@ endif
ifeq ($(NOPLUGINS),true)
TARGETS = noplugins$(TARGET_SUFFIX).a
else
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini.a
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini$(TARGET_SUFFIX).a
endif

all: $(TARGETS)
@@ -1375,11 +1380,14 @@ JACK_RESOURCES += $(CURDIR)/surgext/build/surge-data/wavetables
JACK_RESOURCES += $(CURDIR)/surgext/build/surge-data/windows.wt
endif

MINIPLUGIN_LIST = Cardinal
MINIRESOURCE_FILES = $(wildcard Cardinal/res/*.svg)

RESOURCE_FILES += Cardinal/res/Miku/Miku.png

MINIPLUGIN_LIST = Cardinal Fundamental
MINIRESOURCE_FILES = $(wildcard Cardinal/res/*.svg)
MINIRESOURCE_FILES += $(wildcard Fundamental/res/*.svg)
MINIRESOURCE_FILES += $(wildcard Fundamental/res/components/*.svg)
MINIRESOURCE_FILES += Fundamental/presets

# MOD builds only have LV2 main and FX variant
ifeq ($(MOD_BUILD),true)



+ 42
- 0
plugins/plugins-mini.cpp View File

@@ -23,11 +23,15 @@
// Cardinal (built-in)
#include "Cardinal/src/plugin.hpp"

// Fundamental
#include "Fundamental/src/plugin.hpp"

// known terminal modules
std::vector<Model*> hostTerminalModels;

// plugin instances
Plugin* pluginInstance__Cardinal;
Plugin* pluginInstance__Fundamental;

namespace rack {

@@ -175,9 +179,47 @@ static void initStatic__Cardinal()
}
}

static void initStatic__Fundamental()
{
Plugin* const p = new Plugin;
pluginInstance__Fundamental = p;

const StaticPluginLoader spl(p, "Fundamental");
if (spl.ok())
{
p->addModel(modelADSR);
p->addModel(modelLFO);
p->addModel(modelVCF);
p->addModel(modelVCO);
spl.removeModule("VCO2");
spl.removeModule("VCA-1");
spl.removeModule("VCA");
spl.removeModule("LFO2");
spl.removeModule("Delay");
spl.removeModule("Mixer");
spl.removeModule("VCMixer");
spl.removeModule("8vert");
spl.removeModule("Mutes");
spl.removeModule("Pulses");
spl.removeModule("Scope");
spl.removeModule("SEQ3");
spl.removeModule("SequentialSwitch1");
spl.removeModule("SequentialSwitch2");
spl.removeModule("Octave");
spl.removeModule("Quantizer");
spl.removeModule("Split");
spl.removeModule("Merge");
spl.removeModule("Sum");
spl.removeModule("MidSide");
spl.removeModule("Noise");
spl.removeModule("Random");
}
}

void initStaticPlugins()
{
initStatic__Cardinal();
initStatic__Fundamental();
}

void destroyStaticPlugins()


+ 47
- 29
src/CardinalCommon.cpp View File

@@ -62,12 +62,14 @@
# error wrong build
#endif

#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
# define HEADLESS
#if defined(CARDINAL_COMMON_DSP_ONLY) || defined(HEADLESS)
# define HEADLESS_BEHAVIOUR
#endif

#if CARDINAL_VARIANT_FX
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
#elif CARDINAL_VARIANT_MINI
# define CARDINAL_TEMPLATE_NAME "init/mini.vcv"
#elif CARDINAL_VARIANT_NATIVE
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
#elif CARDINAL_VARIANT_SYNTH
@@ -93,10 +95,12 @@ START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------------------------------------------

#ifndef HEADLESS
void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index, bool started)
{
DISTRHO_SAFE_ASSERT_RETURN(pcontext->ui != nullptr,);

#ifndef CARDINAL_COMMON_DSP_ONLY
if (started)
{
pcontext->ui->editParameter(index, true);
@@ -106,26 +110,40 @@ void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index,
{
pcontext->ui->editParameter(index, false);
}
#endif
}
#endif

// --------------------------------------------------------------------------------------------------------------------

#ifndef HEADLESS
bool CardinalPluginContext::addIdleCallback(IdleCallback* const cb) const
{
if (ui == nullptr)
return false;
#ifndef CARDINAL_COMMON_DSP_ONLY
if (ui != nullptr)
{
ui->addIdleCallback(cb);
return true;
}
#else
// unused
(void)cb;
#endif

ui->addIdleCallback(cb);
return true;
return false;
}

void CardinalPluginContext::removeIdleCallback(IdleCallback* const cb) const
{
if (ui == nullptr)
return;

ui->removeIdleCallback(cb);
#ifndef CARDINAL_COMMON_DSP_ONLY
if (ui != nullptr)
ui->removeIdleCallback(cb);
#else
// unused
(void)cb;
#endif
}
#endif

void CardinalPluginContext::writeMidiMessage(const rack::midi::Message& message, const uint8_t channel)
{
@@ -296,7 +314,7 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
settings::skipLoadOnLaunch = true;
settings::showTipsOnLaunch = false;
settings::windowPos = math::Vec(0, 0);
#ifdef HEADLESS
#ifdef HEADLESS_BEHAVIOUR
settings::headless = true;
#endif

@@ -348,17 +366,17 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
if (!system::exists(system::join(asset::systemDir, "res")))
#endif
{
#if defined(DISTRHO_OS_WASM)
#if defined(DISTRHO_OS_WASM)
asset::systemDir = "/resources";
#elif defined(ARCH_MAC)
#elif defined(ARCH_MAC)
asset::systemDir = "/Library/Application Support/Cardinal";
#elif defined(ARCH_WIN)
#elif defined(ARCH_WIN)
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
if (! commonprogfiles.empty())
asset::systemDir = system::join(commonprogfiles, "Cardinal");
#else
#else
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
#endif
#endif

asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
}
@@ -542,7 +560,7 @@ namespace patchUtils

using namespace rack;

#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
static void promptClear(const char* const message, const std::function<void()> action)
{
if (APP->history->isSaved() || APP->scene->rack->hasModules())
@@ -554,7 +572,7 @@ static void promptClear(const char* const message, const std::function<void()> a

void loadDialog()
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
promptClear("The current patch is unsaved. Clear it and open a new patch?", []() {
std::string dir;
if (! APP->patch->path.empty())
@@ -579,7 +597,7 @@ void loadDialog()

void loadPathDialog(const std::string& path, const bool asTemplate)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
promptClear("The current patch is unsaved. Clear it and open the new patch?", [path, asTemplate]() {
APP->patch->loadAction(path);

@@ -618,7 +636,7 @@ void loadSelectionDialog()

void loadTemplateDialog()
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
promptClear("The current patch is unsaved. Clear it and start a new patch?", []() {
APP->patch->loadTemplate();
});
@@ -627,7 +645,7 @@ void loadTemplateDialog()

void revertDialog()
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
if (APP->patch->path.empty())
return;
promptClear("Revert patch to the last saved state?", []{
@@ -638,7 +656,7 @@ void revertDialog()

void saveDialog(const std::string& path)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
if (path.empty()) {
return;
}
@@ -656,7 +674,7 @@ void saveDialog(const std::string& path)
#endif
}

#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
static void saveAsDialog(const bool uncompressed)
{
std::string dir;
@@ -683,14 +701,14 @@ static void saveAsDialog(const bool uncompressed)

void saveAsDialog()
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
saveAsDialog(false);
#endif
}

void saveAsDialogUncompressed()
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
saveAsDialog(true);
#endif
}
@@ -716,7 +734,7 @@ void async_dialog_filebrowser(const bool saving,
const char* const title,
const std::function<void(char* path)> action)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
CardinalPluginContext* const pcontext = static_cast<CardinalPluginContext*>(APP);
DISTRHO_SAFE_ASSERT_RETURN(pcontext != nullptr,);

@@ -739,14 +757,14 @@ void async_dialog_filebrowser(const bool saving,

void async_dialog_message(const char* const message)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
asyncDialog::create(message);
#endif
}

void async_dialog_message(const char* const message, const std::function<void()> action)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
asyncDialog::create(message, action);
#endif
}
@@ -754,7 +772,7 @@ void async_dialog_message(const char* const message, const std::function<void()>
void async_dialog_text_input(const char* const message, const char* const text,
const std::function<void(char* newText)> action)
{
#ifndef HEADLESS
#ifndef HEADLESS_BEHAVIOUR
asyncDialog::textInput(message, text, action);
#endif
}

+ 5
- 0
src/CardinalCommon.hpp View File

@@ -104,6 +104,7 @@ START_NAMESPACE_DISTRHO

class CardinalBasePlugin;
class CardinalBaseUI;
struct CardinalPluginContext;

struct Initializer
#ifdef CARDINAL_INIT_OSC_THREAD
@@ -124,6 +125,10 @@ struct Initializer
#endif
};

#ifndef HEADLESS
void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index, bool started);
#endif

END_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------------------------------------------

+ 19
- 0
src/CardinalMini/CardinalCommon-UI.cpp View File

@@ -0,0 +1,19 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
*
* 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.
*/

#define CARDINAL_COMMON_UI_ONLY
#include "CardinalCommon.cpp"

+ 0
- 1
src/CardinalMini/CardinalCommon.cpp View File

@@ -1 +0,0 @@
../CardinalCommon.cpp

+ 19
- 0
src/CardinalMini/CardinalCommon.cpp View File

@@ -0,0 +1,19 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
*
* 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.
*/

#define CARDINAL_COMMON_DSP_ONLY
#include "../CardinalCommon.cpp"

+ 27
- 2
src/CardinalPlugin.cpp View File

@@ -609,7 +609,27 @@ protected:
switch (index)
{
case 0:
state.hints = kStateIsBase64Blob | kStateIsOnlyForDSP;
state.hints = kStateIsBase64Blob;
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
state.hints |= kStateIsOnlyForDSP;
#endif
if (FILE* const f = std::fopen(context->patch->factoryTemplatePath.c_str(), "r"))
{
std::fseek(f, 0, SEEK_END);
if (const long fileSize = std::ftell(f))
{
std::fseek(f, 0, SEEK_SET);
char* const fileContent = new char[fileSize];
if (std::fread(fileContent, fileSize, 1, f) == 1)
{
state.defaultValue = String::asBase64(fileContent, fileSize);
}
delete[] fileContent;
}
std::fclose(f);
}
state.key = "patch";
state.label = "Patch";
break;
@@ -624,12 +644,17 @@ protected:
state.label = "Comment";
break;
case 3:
state.hints = kStateIsOnlyForUI;
state.hints = 0x0;
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
state.hints |= kStateIsOnlyForDSP;
#endif
state.defaultValue = "{}";
state.key = "moduleInfos";
state.label = "moduleInfos";
break;
case 4:
state.hints = kStateIsOnlyForUI;
// state.defaultValue = String("%d:%d", DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT);
state.key = "windowSize";
state.label = "Window size";
break;


+ 52
- 13
src/CardinalUI.cpp View File

@@ -51,6 +51,7 @@
#include "CardinalCommon.hpp"
#include "PluginContext.hpp"
#include "WindowParameters.hpp"
#include "extra/Base64.hpp"

#ifndef DISTRHO_OS_WASM
# include "extra/SharedResourcePointer.hpp"
@@ -376,8 +377,7 @@ public:
context->history = new rack::history::State;
context->patch = new rack::patch::Manager;
context->patch->autosavePath = fAutosavePath;
context->patch->templatePath = fInitializer->templatePath;
context->patch->factoryTemplatePath = fInitializer->factoryTemplatePath;
context->patch->templatePath = context->patch->factoryTemplatePath = fInitializer->templatePath;

context->event = new rack::widget::EventState;
context->scene = new rack::app::Scene;
@@ -385,10 +385,7 @@ public:

context->window = new rack::window::Window;

context->patch->loadTemplate();
context->scene->rackScroll->reset();
// swap to factory template after first load
context->patch->templatePath = context->patch->factoryTemplatePath;
#endif

Window& window(getWindow());
@@ -806,17 +803,59 @@ protected:

void stateChanged(const char* const key, const char* const value) override
{
if (std::strcmp(key, "windowSize") != 0)
return;
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
if (std::strcmp(key, "patch") == 0)
{
if (fAutosavePath.empty())
return;

const std::vector<uint8_t> data(d_getChunkFromBase64String(value));

DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,);

rack::system::removeRecursively(fAutosavePath);
rack::system::createDirectories(fAutosavePath);

static constexpr const char zstdMagic[] = "\x28\xb5\x2f\xfd";

if (std::memcmp(data.data(), zstdMagic, sizeof(zstdMagic)) != 0)
{
FILE* const f = std::fopen(rack::system::join(fAutosavePath, "patch.json").c_str(), "w");
DISTRHO_SAFE_ASSERT_RETURN(f != nullptr,);

std::fwrite(data.data(), data.size(), 1, f);
std::fclose(f);
}
else
{
try {
rack::system::unarchiveToDirectory(data, fAutosavePath);
} DISTRHO_SAFE_EXCEPTION_RETURN("setState unarchiveToDirectory",);
}

const ScopedContext sc(this);

int width = 0;
int height = 0;
std::sscanf(value, "%i:%i", &width, &height);
try {
context->patch->loadAutosave();
} DISTRHO_SAFE_EXCEPTION_RETURN("setState loadAutosave",);

return;
}
#endif

if (width > 0 && height > 0)
if (std::strcmp(key, "windowSize") == 0)
{
const double scaleFactor = getScaleFactor();
setSize(width * scaleFactor, height * scaleFactor);
int width = 0;
int height = 0;
std::sscanf(value, "%d:%d", &width, &height);

if (width > 0 && height > 0)
{
const double scaleFactor = getScaleFactor();
setSize(width * scaleFactor, height * scaleFactor);
}

return;
}
}



+ 1
- 3
src/Makefile.cardinal.mk View File

@@ -248,14 +248,12 @@ endif
ifeq ($(CARDINAL_VARIANT),mini)
ifneq ($(HEADLESS)$(MOD_BUILD),true)
FILES_UI = CardinalUI.cpp
FILES_UI += CardinalCommon.cpp
FILES_UI += CardinalCommon-UI.cpp
FILES_UI += common.cpp
FILES_UI += glfw.cpp
FILES_UI += Window.cpp
EXTRA_UI_DEPENDENCIES = $(subst -headless,,$(EXTRA_DSP_DEPENDENCIES))
EXTRA_UI_LIBS = -Wl,--start-group
EXTRA_UI_LIBS += $(subst -headless,,$(EXTRA_DSP_LIBS))
EXTRA_UI_LIBS += -Wl,--end-group
endif
endif



+ 0
- 4
src/PluginContext.hpp View File

@@ -124,10 +124,6 @@ struct CardinalPluginContext : rack::Context {
#endif
};

#ifndef HEADLESS
void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index, bool started);
#endif

// -----------------------------------------------------------------------------------------------------------

CardinalPluginContext* getRackContextFromPlugin(void* ptr);


+ 18
- 18
src/custom/RemoteNanoVG.cpp View File

@@ -21,27 +21,27 @@
# error wrong build
#endif

#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
# define HEADLESS
#endif
#ifndef HEADLESS
# include "OpenGL.hpp"
#endif
// #if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
// # define HEADLESS
// #endif
//
// #ifndef HEADLESS
// # include "OpenGL.hpp"
// #endif

#include "nanovg.h"

#ifdef HEADLESS
// #ifdef HEADLESS
struct NVGLUframebuffer;
void nvgluBindFramebuffer(NVGLUframebuffer* fb) {}
NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int w, int h, int imageFlags) { return nullptr; }
void nvgluDeleteFramebuffer(NVGLUframebuffer* fb) {}
#else
# define NANOVG_GLES2_IMPLEMENTATION
# define NANOVG_FBO_VALID 1
# include "nanovg_gl.h"
# include "nanovg_gl_utils.h"
#endif
// #else
// # define NANOVG_GLES2_IMPLEMENTATION
// # define NANOVG_FBO_VALID 1
// # include "nanovg_gl.h"
// # include "nanovg_gl_utils.h"
// #endif

#if defined(__GNUC__) && (__GNUC__ >= 6)
# pragma GCC diagnostic push
@@ -72,7 +72,7 @@ GLFWAPI double glfwGetTime(void) { return 0.0; }

}

#ifndef HEADLESS
# define STB_IMAGE_WRITE_IMPLEMENTATION
# include "../src/Rack/dep/glfw/deps/stb_image_write.h"
#endif
// #ifndef HEADLESS
// # define STB_IMAGE_WRITE_IMPLEMENTATION
// # include "../src/Rack/dep/glfw/deps/stb_image_write.h"
// #endif

Loading…
Cancel
Save