Initial code for remote push over OSC

Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
falkTX 2021-10-23 15:48:09 +01:00
parent a00020e597
commit e83d514eb6
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
3 changed files with 196 additions and 1 deletions

View file

@ -33,6 +33,11 @@
# undef DEBUG
#endif
#ifdef HAVE_LIBLO
# include <lo/lo.h>
# include "extra/Thread.hpp"
#endif
#include <list>
#include "DistrhoPluginUtils.hpp"
@ -41,6 +46,8 @@
#include "extra/Base64.hpp"
#include "extra/SharedResourcePointer.hpp"
#define REMOTE_HOST_PORT "2228"
namespace rack {
namespace plugin {
void initStaticPlugins();
@ -57,7 +64,16 @@ START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------------------------------------------
struct Initializer {
struct Initializer
#ifdef HAVE_LIBLO
: public Thread
#endif
{
#ifdef HAVE_LIBLO
lo_server oscServer = nullptr;
CardinalBasePlugin* oscPlugin = nullptr;
#endif
Initializer(const CardinalBasePlugin* const plugin)
{
using namespace rack;
@ -136,12 +152,33 @@ struct Initializer {
INFO("Initializing plugins");
plugin::initStaticPlugins();
#ifdef HAVE_LIBLO
oscServer = lo_server_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler);
DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,);
lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this);
lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this);
lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr);
startThread();
#endif
}
~Initializer()
{
using namespace rack;
#ifdef HAVE_LIBLO
if (oscServer != nullptr)
{
stopThread(5000);
lo_server_del_method(oscServer, nullptr, nullptr);
lo_server_free(oscServer);
oscServer = nullptr;
}
#endif
INFO("Destroying plugins");
plugin::destroyStaticPlugins();
@ -154,6 +191,77 @@ struct Initializer {
INFO("Destroying logger");
logger::destroy();
}
#ifdef HAVE_LIBLO
void run() override
{
while (! shouldThreadExit())
{
d_msleep(200);
while (lo_server_recv_noblock(oscServer, 0) != 0) {}
}
}
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("osc_hello_handler()");
const lo_address source = lo_message_get_source(m);
lo_send_from(source, static_cast<Initializer*>(self)->oscServer, 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_stdout("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<Initializer*>(self)->oscPlugin)
{
CardinalPluginContext* const context = plugin->context;
std::vector<uint8_t> data(size);
std::memcpy(data.data(), blob, size);
const MutexLocker cml(context->mutex);
rack::contextSet(context);
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());
}
rack::contextSet(nullptr);
}
const lo_address source = lo_message_get_source(m);
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail");
return 0;
}
#endif
};
// -----------------------------------------------------------------------------------------------------------
@ -247,6 +355,10 @@ public:
context->patch->loadTemplate();
context->engine->startFallbackThread();
#ifdef HAVE_LIBLO
fInitializer->oscPlugin = this;
#endif
#if defined(__MOD_DEVICES__) && !defined(HEADLESS)
context->window = new rack::window::Window;
rack::window::WindowInit(context->window, this);
@ -260,6 +372,10 @@ public:
~CardinalPlugin() override
{
#ifdef HAVE_LIBLO
fInitializer->oscPlugin = nullptr;
#endif
{
const MutexLocker cml(context->mutex);
rack::contextSet(context);