diff --git a/src/CardinalCommon.cpp b/src/CardinalCommon.cpp index c87cc79..bfbd0ff 100644 --- a/src/CardinalCommon.cpp +++ b/src/CardinalCommon.cpp @@ -36,10 +36,6 @@ # error wrong build #endif -#if (defined(STATIC_BUILD) && !defined(__MOD_DEVICES__)) || CARDINAL_VARIANT_MINI -# undef CARDINAL_INIT_OSC_THREAD -#endif - #ifdef NDEBUG # undef DEBUG #endif @@ -56,10 +52,6 @@ # include #endif -#ifdef HAVE_LIBLO -# include -#endif - #ifdef DISTRHO_OS_WASM # include #endif @@ -345,176 +337,6 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- -#ifdef HAVE_LIBLO -static void osc_error_handler(int num, const char* msg, const char* path) -{ - d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path); -} - -static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*) -{ - d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types); - return 0; -} - -static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self) -{ - d_stdout("Hello received from OSC, saying hello back to them o/"); - const lo_address source = lo_message_get_source(m); - const lo_server server = static_cast(self)->oscServer; - - // send list of features first - #ifdef CARDINAL_INIT_OSC_THREAD - lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", ":screenshot:"); - #else - lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", ""); - #endif - - // then finally hello reply - lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); - return 0; -} - -static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) -{ - d_debug("osc_load_handler()"); - DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); - DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); - - const int32_t size = argv[0]->blob.size; - DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0); - - const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data); - DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0); - - bool ok = false; - - if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) - { - CardinalPluginContext* const context = plugin->context; - std::vector data(size); - std::memcpy(data.data(), blob, size); - - #ifdef CARDINAL_INIT_OSC_THREAD - rack::contextSet(context); - #endif - - rack::system::removeRecursively(context->patch->autosavePath); - rack::system::createDirectories(context->patch->autosavePath); - try { - rack::system::unarchiveToDirectory(data, context->patch->autosavePath); - context->patch->loadAutosave(); - ok = true; - } - catch (rack::Exception& e) { - WARN("%s", e.what()); - } - - #ifdef CARDINAL_INIT_OSC_THREAD - rack::contextSet(nullptr); - #endif - } - - const lo_address source = lo_message_get_source(m); - const lo_server server = static_cast(self)->oscServer; - lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail"); - return 0; -} - -static int osc_param_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) -{ - d_debug("osc_param_handler()"); - DISTRHO_SAFE_ASSERT_RETURN(argc == 3, 0); - DISTRHO_SAFE_ASSERT_RETURN(types != nullptr, 0); - DISTRHO_SAFE_ASSERT_RETURN(types[0] == 'h', 0); - DISTRHO_SAFE_ASSERT_RETURN(types[1] == 'i', 0); - DISTRHO_SAFE_ASSERT_RETURN(types[2] == 'f', 0); - - if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) - { - CardinalPluginContext* const context = plugin->context; - - const int64_t moduleId = argv[0]->h; - const int paramId = argv[1]->i; - const float paramValue = argv[2]->f; - - #ifdef CARDINAL_INIT_OSC_THREAD - rack::contextSet(context); - #endif - - rack::engine::Module* const module = context->engine->getModule(moduleId); - DISTRHO_SAFE_ASSERT_RETURN(module != nullptr, 0); - - context->engine->setParamValue(module, paramId, paramValue); - - #ifdef CARDINAL_INIT_OSC_THREAD - rack::contextSet(nullptr); - #endif - } - - return 0; -} - -static int osc_host_param_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) -{ - d_debug("osc_host_param_handler()"); - DISTRHO_SAFE_ASSERT_RETURN(argc == 2, 0); - DISTRHO_SAFE_ASSERT_RETURN(types != nullptr, 0); - DISTRHO_SAFE_ASSERT_RETURN(types[0] == 'i', 0); - DISTRHO_SAFE_ASSERT_RETURN(types[1] == 'f', 0); - - if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) - { - CardinalPluginContext* const context = plugin->context; - - const int paramId = argv[0]->i; - DISTRHO_SAFE_ASSERT_RETURN(paramId >= 0, 0); - - const uint uparamId = static_cast(paramId); - DISTRHO_SAFE_ASSERT_UINT2_RETURN(uparamId < kModuleParameterCount, uparamId, kModuleParameterCount, 0); - - const float paramValue = argv[1]->f; - - context->parameters[uparamId] = paramValue; - } - - return 0; -} - -# ifdef CARDINAL_INIT_OSC_THREAD -static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) -{ - d_debug("osc_screenshot_handler()"); - DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); - DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); - - const int32_t size = argv[0]->blob.size; - DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0); - - const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data); - DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0); - - bool ok = false; - - if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) - { - if (char* const screenshot = String::asBase64(blob, size).getAndReleaseBuffer()) - { - ok = plugin->updateStateValue("screenshot", screenshot); - std::free(screenshot); - } - } - - const lo_address source = lo_message_get_source(m); - const lo_server server = static_cast(self)->oscServer; - lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail"); - return 0; -} -# endif -#endif - -// ----------------------------------------------------------------------------------------------------------- - #if defined(DISTRHO_OS_WASM) && !defined(CARDINAL_COMMON_UI_ONLY) static void WebBrowserDataLoaded(void* const data) { @@ -698,32 +520,14 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB loadSettings(isRealInstance); - #if defined(CARDINAL_INIT_OSC_THREAD) - INFO("Initializing OSC Remote control"); - const char* port; - if (const char* const portEnv = std::getenv("CARDINAL_REMOTE_HOST_PORT")) - port = portEnv; - else - port = CARDINAL_DEFAULT_REMOTE_PORT; - startRemoteServer(port); - #elif defined(HAVE_LIBLO) - if (isStandalone()) { - INFO("OSC Remote control is available on request"); - } else { - INFO("OSC Remote control is not available on plugin variants"); - } - #else - INFO("OSC Remote control is not enabled in this build"); - #endif + oscInitState(this); } Initializer::~Initializer() { using namespace rack; - #ifdef HAVE_LIBLO - stopRemoteServer(); - #endif + oscShutdownState(this); if (shouldSaveSettings) { @@ -784,82 +588,6 @@ void Initializer::loadSettings(const bool isRealInstance) switchDarkMode(settings::uiTheme == "dark"); } -#ifdef HAVE_LIBLO -bool Initializer::startRemoteServer(const char* const port) -{ - #ifdef CARDINAL_INIT_OSC_THREAD - if (oscServerThread != nullptr) - return true; - - if ((oscServerThread = lo_server_thread_new_with_proto(port, LO_UDP, osc_error_handler)) == nullptr) - return false; - - oscServer = lo_server_thread_get_server(oscServerThread); - - lo_server_thread_add_method(oscServerThread, "/hello", "", osc_hello_handler, this); - lo_server_thread_add_method(oscServerThread, "/host-param", "if", osc_host_param_handler, this); - lo_server_thread_add_method(oscServerThread, "/load", "b", osc_load_handler, this); - lo_server_thread_add_method(oscServerThread, "/param", "hif", osc_param_handler, this); - lo_server_thread_add_method(oscServerThread, "/screenshot", "b", osc_screenshot_handler, this); - lo_server_thread_add_method(oscServerThread, nullptr, nullptr, osc_fallback_handler, nullptr); - lo_server_thread_start(oscServerThread); - #else - if (oscServer != nullptr) - return true; - - if ((oscServer = lo_server_new_with_proto(port, LO_UDP, osc_error_handler)) == nullptr) - return false; - - lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this); - lo_server_add_method(oscServer, "/host-param", "if", osc_host_param_handler, this); - lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this); - lo_server_add_method(oscServer, "/param", "hif", osc_param_handler, this); - lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr); - #endif - - return true; -} - -void Initializer::stopRemoteServer() -{ - DISTRHO_SAFE_ASSERT(remotePluginInstance == nullptr); - - #ifdef CARDINAL_INIT_OSC_THREAD - if (oscServerThread != nullptr) - { - lo_server_thread_stop(oscServerThread); - lo_server_thread_del_method(oscServerThread, nullptr, nullptr); - lo_server_thread_free(oscServerThread); - oscServerThread = nullptr; - oscServer = nullptr; - } - #else - if (oscServer != nullptr) - { - lo_server_del_method(oscServer, nullptr, nullptr); - lo_server_free(oscServer); - oscServer = nullptr; - } - #endif -} - -void Initializer::stepRemoteServer() -{ - DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,); - DISTRHO_SAFE_ASSERT_RETURN(remotePluginInstance != nullptr,); - - #ifndef CARDINAL_INIT_OSC_THREAD - for (;;) - { - try { - if (lo_server_recv_noblock(oscServer, 0) == 0) - break; - } DISTRHO_SAFE_EXCEPTION_CONTINUE("stepRemoteServer") - } - #endif -} -#endif // HAVE_LIBLO - // -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO diff --git a/src/CardinalCommon.hpp b/src/CardinalCommon.hpp index 31b81b1..f39b427 100644 --- a/src/CardinalCommon.hpp +++ b/src/CardinalCommon.hpp @@ -7,6 +7,7 @@ #pragma once #include "DistrhoUtils.hpp" +#include "CardinalOSC.hpp" #include @@ -74,14 +75,6 @@ void openBrowser(const std::string& url); // ----------------------------------------------------------------------------------------------------------- -#if defined(HAVE_LIBLO) && defined(HEADLESS) -# define CARDINAL_INIT_OSC_THREAD -#endif - -#ifdef HAVE_LIBLO -# include -#endif - START_NAMESPACE_DISTRHO class CardinalBasePlugin; @@ -92,22 +85,12 @@ struct Initializer std::string templatePath; std::string factoryTemplatePath; bool shouldSaveSettings = false; + CARDINAL_OSC_FIELDS Initializer(const CardinalBasePlugin* plugin, const CardinalBaseUI* ui); ~Initializer(); void loadSettings(bool isRealInstance); - - #ifdef HAVE_LIBLO - lo_server oscServer = nullptr; - #ifdef CARDINAL_INIT_OSC_THREAD - lo_server_thread oscServerThread = nullptr; - #endif - CardinalBasePlugin* remotePluginInstance = nullptr; - - bool startRemoteServer(const char* port); - void stopRemoteServer(); - void stepRemoteServer(); - #endif + CARDINAL_OSC_METHODS }; #ifndef HEADLESS diff --git a/src/CardinalNative/CardinalOSC.cpp b/src/CardinalNative/CardinalOSC.cpp new file mode 120000 index 0000000..0bcc13c --- /dev/null +++ b/src/CardinalNative/CardinalOSC.cpp @@ -0,0 +1 @@ +../CardinalOSC.cpp \ No newline at end of file diff --git a/src/CardinalOSC.cpp b/src/CardinalOSC.cpp new file mode 100644 index 0000000..d247d5d --- /dev/null +++ b/src/CardinalOSC.cpp @@ -0,0 +1,309 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2026 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "CardinalOSC.hpp" + +#include "CardinalCommon.hpp" +#include "CardinalPluginContext.hpp" + +#include +#include +#include +#include +#include + +#include + +#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# error wrong build +#endif + +#if (defined(STATIC_BUILD) && !defined(__MOD_DEVICES__)) || CARDINAL_VARIANT_MINI +# undef CARDINAL_INIT_OSC_THREAD +#endif + +#ifdef HAVE_LIBLO +# include +#endif + +START_NAMESPACE_DISTRHO + +#ifdef HAVE_LIBLO +static void osc_error_handler(int num, const char* msg, const char* path) +{ + d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path); +} + +static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*) +{ + d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types); + return 0; +} + +static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self) +{ + d_stdout("Hello received from OSC, saying hello back to them o/"); + const lo_address source = lo_message_get_source(m); + const lo_server server = static_cast(self)->oscServer; + + // send list of features first + #ifdef CARDINAL_INIT_OSC_THREAD + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", ":screenshot:"); + #else + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "features", ""); + #endif + + // then finally hello reply + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); + return 0; +} + +static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) +{ + d_debug("osc_load_handler()"); + DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); + DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); + + const int32_t size = argv[0]->blob.size; + DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0); + + const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data); + DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0); + + bool ok = false; + + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) + { + CardinalPluginContext* const context = plugin->context; + std::vector data(size); + std::memcpy(data.data(), blob, size); + + #ifdef CARDINAL_INIT_OSC_THREAD + rack::contextSet(context); + #endif + + rack::system::removeRecursively(context->patch->autosavePath); + rack::system::createDirectories(context->patch->autosavePath); + try { + rack::system::unarchiveToDirectory(data, context->patch->autosavePath); + context->patch->loadAutosave(); + ok = true; + } + catch (rack::Exception& e) { + WARN("%s", e.what()); + } + + #ifdef CARDINAL_INIT_OSC_THREAD + rack::contextSet(nullptr); + #endif + } + + const lo_address source = lo_message_get_source(m); + const lo_server server = static_cast(self)->oscServer; + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail"); + return 0; +} + +static int osc_param_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) +{ + d_debug("osc_param_handler()"); + DISTRHO_SAFE_ASSERT_RETURN(argc == 3, 0); + DISTRHO_SAFE_ASSERT_RETURN(types != nullptr, 0); + DISTRHO_SAFE_ASSERT_RETURN(types[0] == 'h', 0); + DISTRHO_SAFE_ASSERT_RETURN(types[1] == 'i', 0); + DISTRHO_SAFE_ASSERT_RETURN(types[2] == 'f', 0); + + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) + { + CardinalPluginContext* const context = plugin->context; + + const int64_t moduleId = argv[0]->h; + const int paramId = argv[1]->i; + const float paramValue = argv[2]->f; + + #ifdef CARDINAL_INIT_OSC_THREAD + rack::contextSet(context); + #endif + + rack::engine::Module* const module = context->engine->getModule(moduleId); + DISTRHO_SAFE_ASSERT_RETURN(module != nullptr, 0); + + context->engine->setParamValue(module, paramId, paramValue); + + #ifdef CARDINAL_INIT_OSC_THREAD + rack::contextSet(nullptr); + #endif + } + + return 0; +} + +static int osc_host_param_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message, void* const self) +{ + d_debug("osc_host_param_handler()"); + DISTRHO_SAFE_ASSERT_RETURN(argc == 2, 0); + DISTRHO_SAFE_ASSERT_RETURN(types != nullptr, 0); + DISTRHO_SAFE_ASSERT_RETURN(types[0] == 'i', 0); + DISTRHO_SAFE_ASSERT_RETURN(types[1] == 'f', 0); + + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) + { + CardinalPluginContext* const context = plugin->context; + + const int paramId = argv[0]->i; + DISTRHO_SAFE_ASSERT_RETURN(paramId >= 0, 0); + + const uint uparamId = static_cast(paramId); + DISTRHO_SAFE_ASSERT_UINT2_RETURN(uparamId < kModuleParameterCount, uparamId, kModuleParameterCount, 0); + + const float paramValue = argv[1]->f; + + context->parameters[uparamId] = paramValue; + } + + return 0; +} + +# ifdef CARDINAL_INIT_OSC_THREAD +static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) +{ + d_debug("osc_screenshot_handler()"); + DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); + DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); + + const int32_t size = argv[0]->blob.size; + DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0); + + const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data); + DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0); + + bool ok = false; + + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) + { + if (char* const screenshot = String::asBase64(blob, size).getAndReleaseBuffer()) + { + ok = plugin->updateStateValue("screenshot", screenshot); + std::free(screenshot); + } + } + + const lo_address source = lo_message_get_source(m); + const lo_server server = static_cast(self)->oscServer; + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail"); + return 0; +} +# endif +#endif + +void oscInitState(Initializer* const self) +{ +#if defined(CARDINAL_INIT_OSC_THREAD) + INFO("Initializing OSC Remote control"); + const char* port; + if (const char* const portEnv = std::getenv("CARDINAL_REMOTE_HOST_PORT")) + port = portEnv; + else + port = CARDINAL_DEFAULT_REMOTE_PORT; + self->startRemoteServer(port); +#elif defined(HAVE_LIBLO) + if (rack::isStandalone()) { + INFO("OSC Remote control is available on request"); + } else { + INFO("OSC Remote control is not available on plugin variants"); + } +#else + INFO("OSC Remote control is not enabled in this build"); + DISTRHO_UNUSED(self); +#endif +} + +void oscShutdownState(Initializer* const self) +{ +#ifdef HAVE_LIBLO + self->stopRemoteServer(); +#else + DISTRHO_UNUSED(self); +#endif +} + +#ifdef HAVE_LIBLO +bool Initializer::startRemoteServer(const char* const port) +{ + #ifdef CARDINAL_INIT_OSC_THREAD + if (oscServerThread != nullptr) + return true; + + if ((oscServerThread = lo_server_thread_new_with_proto(port, LO_UDP, osc_error_handler)) == nullptr) + return false; + + oscServer = lo_server_thread_get_server(oscServerThread); + + lo_server_thread_add_method(oscServerThread, "/hello", "", osc_hello_handler, this); + lo_server_thread_add_method(oscServerThread, "/host-param", "if", osc_host_param_handler, this); + lo_server_thread_add_method(oscServerThread, "/load", "b", osc_load_handler, this); + lo_server_thread_add_method(oscServerThread, "/param", "hif", osc_param_handler, this); + lo_server_thread_add_method(oscServerThread, "/screenshot", "b", osc_screenshot_handler, this); + lo_server_thread_add_method(oscServerThread, nullptr, nullptr, osc_fallback_handler, nullptr); + lo_server_thread_start(oscServerThread); + #else + if (oscServer != nullptr) + return true; + + if ((oscServer = lo_server_new_with_proto(port, LO_UDP, osc_error_handler)) == nullptr) + return false; + + lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this); + lo_server_add_method(oscServer, "/host-param", "if", osc_host_param_handler, this); + lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this); + lo_server_add_method(oscServer, "/param", "hif", osc_param_handler, this); + lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr); + #endif + + return true; +} + +void Initializer::stopRemoteServer() +{ + DISTRHO_SAFE_ASSERT(remotePluginInstance == nullptr); + + #ifdef CARDINAL_INIT_OSC_THREAD + if (oscServerThread != nullptr) + { + lo_server_thread_stop(oscServerThread); + lo_server_thread_del_method(oscServerThread, nullptr, nullptr); + lo_server_thread_free(oscServerThread); + oscServerThread = nullptr; + oscServer = nullptr; + } + #else + if (oscServer != nullptr) + { + lo_server_del_method(oscServer, nullptr, nullptr); + lo_server_free(oscServer); + oscServer = nullptr; + } + #endif +} + +void Initializer::stepRemoteServer() +{ + DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(remotePluginInstance != nullptr,); + + #ifndef CARDINAL_INIT_OSC_THREAD + for (;;) + { + try { + if (lo_server_recv_noblock(oscServer, 0) == 0) + break; + } DISTRHO_SAFE_EXCEPTION_CONTINUE("stepRemoteServer") + } + #endif +} +#endif // HAVE_LIBLO + +END_NAMESPACE_DISTRHO diff --git a/src/CardinalOSC.hpp b/src/CardinalOSC.hpp new file mode 100644 index 0000000..891570b --- /dev/null +++ b/src/CardinalOSC.hpp @@ -0,0 +1,45 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2026 Filipe Coelho + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "DistrhoUtils.hpp" + +#if defined(HAVE_LIBLO) && defined(HEADLESS) +# define CARDINAL_INIT_OSC_THREAD +#endif + +#ifdef HAVE_LIBLO +# include +#endif + +START_NAMESPACE_DISTRHO + +class CardinalBasePlugin; +struct Initializer; + +#ifdef HAVE_LIBLO +# define CARDINAL_OSC_FIELDS \ + lo_server oscServer = nullptr; \ + lo_server_thread oscServerThread = nullptr; \ + CardinalBasePlugin* remotePluginInstance = nullptr; +#else +# define CARDINAL_OSC_FIELDS +#endif + +#ifdef HAVE_LIBLO +# define CARDINAL_OSC_METHODS \ + bool startRemoteServer(const char* port); \ + void stopRemoteServer(); \ + void stepRemoteServer(); +#else +# define CARDINAL_OSC_METHODS +#endif + +void oscInitState(Initializer* self); +void oscShutdownState(Initializer* self); + +END_NAMESPACE_DISTRHO diff --git a/src/CardinalRemote/CardinalOSC.cpp b/src/CardinalRemote/CardinalOSC.cpp new file mode 120000 index 0000000..0bcc13c --- /dev/null +++ b/src/CardinalRemote/CardinalOSC.cpp @@ -0,0 +1 @@ +../CardinalOSC.cpp \ No newline at end of file diff --git a/src/CardinalRemote/Makefile b/src/CardinalRemote/Makefile index 6e53f44..e36dca9 100644 --- a/src/CardinalRemote/Makefile +++ b/src/CardinalRemote/Makefile @@ -329,6 +329,7 @@ BUILD_CXX_FLAGS += -DCARDINAL_PLUGIN_PREFIX='"$(PREFIX)"' FILES = main.cpp FILES += RemoteUI.cpp FILES += CardinalCommon.cpp +FILES += CardinalOSC.cpp FILES += CardinalRemote.cpp FILES += common.cpp FILES += glfw.cpp diff --git a/src/Makefile.cardinal.mk b/src/Makefile.cardinal.mk index 772f139..bc63580 100644 --- a/src/Makefile.cardinal.mk +++ b/src/Makefile.cardinal.mk @@ -80,6 +80,7 @@ DEP_LIB_PATH = $(RACK_DEP_PATH)/lib FILES_DSP = CardinalPlugin.cpp FILES_DSP += CardinalCommon.cpp +FILES_DSP += CardinalOSC.cpp FILES_DSP += CardinalRemote.cpp FILES_DSP += common.cpp