Initial code for remote push over OSC
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
a00020e597
commit
e83d514eb6
3 changed files with 196 additions and 1 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue