Signed-off-by: falkTX <falktx@falktx.com>tags/23.02
| @@ -1550,7 +1550,7 @@ static void initStatic__BogaudioModules() | |||||
| { | { | ||||
| // Make sure to use dark theme as default | // Make sure to use dark theme as default | ||||
| Skins& skins(Skins::skins()); | Skins& skins(Skins::skins()); | ||||
| skins._default = "dark"; | |||||
| skins._default = settings::darkMode ? "dark" : "light"; | |||||
| #define modelADSR modelBogaudioADSR | #define modelADSR modelBogaudioADSR | ||||
| #define modelLFO modelBogaudioLFO | #define modelLFO modelBogaudioLFO | ||||
| #define modelNoise modelBogaudioNoise | #define modelNoise modelBogaudioNoise | ||||
| @@ -40,6 +40,7 @@ | |||||
| #include <system.hpp> | #include <system.hpp> | ||||
| #include <app/Browser.hpp> | #include <app/Browser.hpp> | ||||
| #include <app/Scene.hpp> | #include <app/Scene.hpp> | ||||
| #include <engine/Engine.hpp> | |||||
| #include <window/Window.hpp> | #include <window/Window.hpp> | ||||
| #ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | #ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | ||||
| @@ -236,7 +237,7 @@ static int osc_fallback_handler(const char* const path, const char* const types, | |||||
| static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self) | static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self) | ||||
| { | { | ||||
| d_stdout("osc_hello_handler()"); | |||||
| d_debug("osc_hello_handler()"); | |||||
| const lo_address source = lo_message_get_source(m); | const lo_address source = lo_message_get_source(m); | ||||
| const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread); | const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread); | ||||
| lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); | lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); | ||||
| @@ -245,7 +246,7 @@ static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_m | |||||
| static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) | 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()"); | |||||
| d_debug("osc_load_handler()"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); | DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); | DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); | ||||
| @@ -283,9 +284,35 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a | |||||
| return 0; | 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<Initializer*>(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; | |||||
| rack::engine::Module* const module = context->engine->getModule(moduleId); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(module != nullptr, 0); | |||||
| context->engine->setParamValue(module, paramId, paramValue); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) | static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self) | ||||
| { | { | ||||
| d_stdout("osc_screenshot_handler()"); | |||||
| d_debug("osc_screenshot_handler()"); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); | DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); | DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0); | ||||
| @@ -298,7 +325,13 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, | |||||
| bool ok = false; | bool ok = false; | ||||
| if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->remotePluginInstance) | if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->remotePluginInstance) | ||||
| ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer()); | |||||
| { | |||||
| 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_address source = lo_message_get_source(m); | ||||
| const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread); | const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread); | ||||
| @@ -441,13 +474,20 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB | |||||
| #ifdef CARDINAL_INIT_OSC_THREAD | #ifdef CARDINAL_INIT_OSC_THREAD | ||||
| INFO("Initializing OSC Remote control"); | INFO("Initializing OSC Remote control"); | ||||
| oscServerThread = lo_server_thread_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler); | |||||
| const char* port; | |||||
| if (const char* const portEnv = std::getenv("CARDINAL_REMOTE_HOST_PORT")) | |||||
| port = portEnv; | |||||
| else | |||||
| port = CARDINAL_DEFAULT_REMOTE_HOST_PORT; | |||||
| oscServerThread = lo_server_thread_new_with_proto(port, LO_UDP, osc_error_handler); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(oscServerThread != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(oscServerThread != nullptr,); | ||||
| lo_server_thread_add_method(oscServerThread, "/hello", "", osc_hello_handler, this); | lo_server_thread_add_method(oscServerThread, "/hello", "", osc_hello_handler, this); | ||||
| lo_server_thread_add_method(oscServerThread, "/load", "b", osc_load_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, "/screenshot", "b", osc_screenshot_handler, this); | ||||
| lo_server_thread_add_method(oscServerThread, nullptr, nullptr, osc_fallback_handler, nullptr); | lo_server_thread_add_method(oscServerThread, nullptr, nullptr, osc_fallback_handler, nullptr); | ||||
| lo_server_thread_start(oscServerThread); | |||||
| #else | #else | ||||
| INFO("OSC Remote control is not enabled in this build"); | INFO("OSC Remote control is not enabled in this build"); | ||||
| #endif | #endif | ||||
| @@ -460,6 +500,7 @@ Initializer::~Initializer() | |||||
| #ifdef CARDINAL_INIT_OSC_THREAD | #ifdef CARDINAL_INIT_OSC_THREAD | ||||
| if (oscServerThread != nullptr) | if (oscServerThread != nullptr) | ||||
| { | { | ||||
| lo_server_thread_stop(oscServerThread); | |||||
| lo_server_thread_del_method(oscServerThread, nullptr, nullptr); | lo_server_thread_del_method(oscServerThread, nullptr, nullptr); | ||||
| lo_server_thread_free(oscServerThread); | lo_server_thread_free(oscServerThread); | ||||
| oscServerThread = nullptr; | oscServerThread = nullptr; | ||||
| @@ -53,7 +53,7 @@ | |||||
| #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Generator" | #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Generator" | ||||
| // #ifdef __MOD_DEVICES__ | // #ifdef __MOD_DEVICES__ | ||||
| // # define DISTRHO_PLUGIN_USES_MODGUI 1 | |||||
| # define DISTRHO_PLUGIN_USES_MODGUI 1 | |||||
| // #endif | // #endif | ||||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | ||||
| @@ -794,6 +794,22 @@ protected: | |||||
| void setState(const char* const key, const char* const value) override | void setState(const char* const key, const char* const value) override | ||||
| { | { | ||||
| #if CARDINAL_VARIANT_MINI | |||||
| if (std::strcmp(key, "param") == 0) | |||||
| { | |||||
| int64_t moduleId = 0; | |||||
| int paramId = 0; | |||||
| float paramValue = 0.f; | |||||
| std::sscanf(value, "%lu:%d:%f", &moduleId, ¶mId, ¶mValue); | |||||
| rack::engine::Module* const module = context->engine->getModule(moduleId); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(module != nullptr,); | |||||
| context->engine->setParamValue(module, paramId, paramValue); | |||||
| return; | |||||
| } | |||||
| #endif | |||||
| #ifndef HEADLESS | #ifndef HEADLESS | ||||
| if (std::strcmp(key, "moduleInfos") == 0) | if (std::strcmp(key, "moduleInfos") == 0) | ||||
| { | { | ||||
| @@ -35,6 +35,11 @@ | |||||
| # include <lo/lo.h> | # include <lo/lo.h> | ||||
| #endif | #endif | ||||
| #ifdef HAVE_LIBLO | |||||
| // # define REMOTE_HOST "localhost" | |||||
| # define REMOTE_HOST "192.168.51.1" | |||||
| #endif | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| namespace remoteUtils { | namespace remoteUtils { | ||||
| @@ -98,7 +103,10 @@ bool connectToRemote() | |||||
| lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); | lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); | ||||
| } | } | ||||
| if (const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT)) | |||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | |||||
| DISTRHO_SAFE_ASSERT(addr != nullptr); | |||||
| if (addr != nullptr) | |||||
| { | { | ||||
| lo_send(addr, "/hello", ""); | lo_send(addr, "/hello", ""); | ||||
| lo_address_free(addr); | lo_address_free(addr); | ||||
| @@ -127,7 +135,23 @@ void idleRemote(RemoteDetails* const remote) | |||||
| #endif | #endif | ||||
| } | } | ||||
| void deployToRemote(RemoteDetails* const remote) | |||||
| void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int paramId, float value) | |||||
| { | |||||
| #if CARDINAL_VARIANT_MINI | |||||
| char paramBuf[512] = {}; | |||||
| std::snprintf(paramBuf, sizeof(paramBuf), "%lu:%d:%f", moduleId, paramId, value); | |||||
| static_cast<CardinalBaseUI*>(remote->handle)->setState("param", paramBuf); | |||||
| #elif defined(HAVE_LIBLO) | |||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); | |||||
| lo_send(addr, "/param", "hif", moduleId, paramId, value); | |||||
| lo_address_free(addr); | |||||
| #endif | |||||
| } | |||||
| void sendFullPatchToRemote(RemoteDetails* const remote) | |||||
| { | { | ||||
| CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP); | CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(context != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(context != nullptr,); | ||||
| @@ -146,7 +170,7 @@ void deployToRemote(RemoteDetails* const remote) | |||||
| std::free(patch); | std::free(patch); | ||||
| } | } | ||||
| #elif defined(HAVE_LIBLO) | #elif defined(HAVE_LIBLO) | ||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); | |||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); | ||||
| if (const lo_blob blob = lo_blob_new(data.size(), data.data())) | if (const lo_blob blob = lo_blob_new(data.size(), data.data())) | ||||
| @@ -162,7 +186,7 @@ void deployToRemote(RemoteDetails* const remote) | |||||
| void sendScreenshotToRemote(RemoteDetails*, const char* const screenshot) | void sendScreenshotToRemote(RemoteDetails*, const char* const screenshot) | ||||
| { | { | ||||
| #ifdef HAVE_LIBLO | #ifdef HAVE_LIBLO | ||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); | |||||
| const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); | ||||
| std::vector<uint8_t> data(d_getChunkFromBase64String(screenshot)); | std::vector<uint8_t> data(d_getChunkFromBase64String(screenshot)); | ||||
| @@ -17,11 +17,7 @@ | |||||
| #pragma once | #pragma once | ||||
| #ifdef HAVE_LIBLO | |||||
| // # define REMOTE_HOST "localhost" | |||||
| # define REMOTE_HOST "192.168.51.1" | |||||
| # define REMOTE_HOST_PORT "2228" | |||||
| #endif | |||||
| #define CARDINAL_DEFAULT_REMOTE_HOST_PORT "2228" | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| @@ -37,7 +33,8 @@ RemoteDetails* getRemote(); | |||||
| bool connectToRemote(); | bool connectToRemote(); | ||||
| void disconnectFromRemote(RemoteDetails* remote); | void disconnectFromRemote(RemoteDetails* remote); | ||||
| void idleRemote(RemoteDetails* remote); | void idleRemote(RemoteDetails* remote); | ||||
| void deployToRemote(RemoteDetails* remote); | |||||
| void sendParamChangeToRemote(RemoteDetails* remote, int64_t moduleId, int paramId, float value); | |||||
| void sendFullPatchToRemote(RemoteDetails* remote); | |||||
| void sendScreenshotToRemote(RemoteDetails* remote, const char* screenshot); | void sendScreenshotToRemote(RemoteDetails* remote, const char* screenshot); | ||||
| } | } | ||||
| @@ -64,6 +64,7 @@ | |||||
| namespace rack { | namespace rack { | ||||
| namespace engine { | namespace engine { | ||||
| void Engine_setAboutToClose(Engine*); | void Engine_setAboutToClose(Engine*); | ||||
| void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*); | |||||
| } | } | ||||
| namespace window { | namespace window { | ||||
| void WindowSetPluginUI(Window* window, DISTRHO_NAMESPACE::UI* ui); | void WindowSetPluginUI(Window* window, DISTRHO_NAMESPACE::UI* ui); | ||||
| @@ -344,8 +345,7 @@ public: | |||||
| rack::contextSet(context); | rack::contextSet(context); | ||||
| #if CARDINAL_VARIANT_MINI | #if CARDINAL_VARIANT_MINI | ||||
| DISTRHO_SAFE_ASSERT_RETURN(remoteUtils::connectToRemote(),); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(remoteDetails != nullptr,); | |||||
| remoteUtils::connectToRemote(); | |||||
| // create unique temporary path for this instance | // create unique temporary path for this instance | ||||
| try { | try { | ||||
| @@ -387,6 +387,8 @@ public: | |||||
| context->window = new rack::window::Window; | context->window = new rack::window::Window; | ||||
| context->scene->rackScroll->reset(); | context->scene->rackScroll->reset(); | ||||
| Engine_setRemoteDetails(context->engine, remoteDetails); | |||||
| #endif | #endif | ||||
| Window& window(getWindow()); | Window& window(getWindow()); | ||||
| @@ -49,6 +49,7 @@ | |||||
| # undef DEBUG | # undef DEBUG | ||||
| #endif | #endif | ||||
| #include "../CardinalRemote.hpp" | |||||
| #include "DistrhoUtils.hpp" | #include "DistrhoUtils.hpp" | ||||
| @@ -97,6 +98,9 @@ struct Engine::Internal { | |||||
| int smoothParamId = 0; | int smoothParamId = 0; | ||||
| float smoothValue = 0.f; | float smoothValue = 0.f; | ||||
| // Remote control | |||||
| remoteUtils::RemoteDetails* remoteDetails = nullptr; | |||||
| /** Mutex that guards the Engine state, such as settings, Modules, and Cables. | /** Mutex that guards the Engine state, such as settings, Modules, and Cables. | ||||
| Writers lock when mutating the engine's state or stepping the block. | Writers lock when mutating the engine's state or stepping the block. | ||||
| Readers lock when using the engine's state. | Readers lock when using the engine's state. | ||||
| @@ -210,12 +214,13 @@ static void Engine_stepFrame(Engine* that) { | |||||
| Param* smoothParam = &smoothModule->params[smoothParamId]; | Param* smoothParam = &smoothModule->params[smoothParamId]; | ||||
| float value = smoothParam->value; | float value = smoothParam->value; | ||||
| float newValue; | float newValue; | ||||
| if (internal->blockFrames != 1) { | |||||
| if (internal->remoteDetails != nullptr) { | |||||
| newValue = value; | |||||
| sendParamChangeToRemote(internal->remoteDetails, smoothModule->id, smoothParamId, value); | |||||
| } else { | |||||
| // Use decay rate of roughly 1 graphics frame | // Use decay rate of roughly 1 graphics frame | ||||
| const float smoothLambda = 60.f; | const float smoothLambda = 60.f; | ||||
| newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime; | newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime; | ||||
| } else { | |||||
| newValue = value; | |||||
| } | } | ||||
| if (d_isEqual(value, newValue)) { | if (d_isEqual(value, newValue)) { | ||||
| // Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats) | // Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats) | ||||
| @@ -1013,6 +1018,9 @@ void Engine::setParamValue(Module* module, int paramId, float value) { | |||||
| internal->smoothModule = NULL; | internal->smoothModule = NULL; | ||||
| internal->smoothParamId = 0; | internal->smoothParamId = 0; | ||||
| } | } | ||||
| if (internal->remoteDetails != nullptr) { | |||||
| sendParamChangeToRemote(internal->remoteDetails, module->id, paramId, value); | |||||
| } | |||||
| module->params[paramId].value = value; | module->params[paramId].value = value; | ||||
| } | } | ||||
| @@ -1263,5 +1271,10 @@ void Engine_setAboutToClose(Engine* const engine) { | |||||
| } | } | ||||
| void Engine_setRemoteDetails(Engine* const engine, remoteUtils::RemoteDetails* const remoteDetails) { | |||||
| engine->internal->remoteDetails = remoteDetails; | |||||
| } | |||||
| } // namespace engine | } // namespace engine | ||||
| } // namespace rack | } // namespace rack | ||||
| @@ -66,7 +66,9 @@ namespace rack { | |||||
| namespace asset { | namespace asset { | ||||
| std::string patchesPath(); | std::string patchesPath(); | ||||
| } | } | ||||
| namespace engine { | |||||
| void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*); | |||||
| } | |||||
| namespace plugin { | namespace plugin { | ||||
| void updateStaticPluginsDarkMode(); | void updateStaticPluginsDarkMode(); | ||||
| } | } | ||||
| @@ -168,26 +170,29 @@ struct FileButton : MenuButton { | |||||
| patchUtils::revertDialog(); | patchUtils::revertDialog(); | ||||
| }, APP->patch->path.empty())); | }, APP->patch->path.empty())); | ||||
| // #if defined(HAVE_LIBLO) && ! CARDINAL_VARIANT_MINI | |||||
| #if defined(HAVE_LIBLO) && ! CARDINAL_VARIANT_MINI | |||||
| menu->addChild(new ui::MenuSeparator); | menu->addChild(new ui::MenuSeparator); | ||||
| remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote(); | remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote(); | ||||
| if (remoteDetails != nullptr && remoteDetails->connected) { | if (remoteDetails != nullptr && remoteDetails->connected) { | ||||
| menu->addChild(createMenuItem("Deploy to MOD", "F7", [remoteDetails]() { | menu->addChild(createMenuItem("Deploy to MOD", "F7", [remoteDetails]() { | ||||
| remoteUtils::deployToRemote(remoteDetails); | |||||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||||
| })); | })); | ||||
| menu->addChild(createCheckMenuItem("Auto deploy to MOD", "", | menu->addChild(createCheckMenuItem("Auto deploy to MOD", "", | ||||
| [remoteDetails]() {return remoteDetails->autoDeploy;}, | [remoteDetails]() {return remoteDetails->autoDeploy;}, | ||||
| [remoteDetails]() {remoteDetails->autoDeploy = !remoteDetails->autoDeploy;} | |||||
| [remoteDetails]() { | |||||
| remoteDetails->autoDeploy = !remoteDetails->autoDeploy; | |||||
| Engine_setRemoteDetails(APP->engine, remoteDetails->autoDeploy ? remoteDetails : nullptr); | |||||
| } | |||||
| )); | )); | ||||
| } else { | } else { | ||||
| menu->addChild(createMenuItem("Connect to MOD", "", []() { | menu->addChild(createMenuItem("Connect to MOD", "", []() { | ||||
| remoteUtils::connectToRemote(); | |||||
| DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote()); | |||||
| })); | })); | ||||
| } | } | ||||
| // #endif | |||||
| #endif | |||||
| #ifndef DISTRHO_OS_WASM | #ifndef DISTRHO_OS_WASM | ||||
| menu->addChild(new ui::MenuSeparator); | menu->addChild(new ui::MenuSeparator); | ||||
| @@ -212,11 +212,15 @@ void Scene::step() { | |||||
| if (remoteDetails->autoDeploy) { | if (remoteDetails->autoDeploy) { | ||||
| const int actionIndex = APP->history->actionIndex; | const int actionIndex = APP->history->actionIndex; | ||||
| const double time = system::getTime(); | const double time = system::getTime(); | ||||
| if (internal->historyActionIndex != actionIndex && time - internal->lastSceneChangeTime >= 1.0) { | |||||
| if (internal->historyActionIndex != actionIndex && actionIndex > 0 && time - internal->lastSceneChangeTime >= 1.0) { | |||||
| const std::string& name(APP->history->actions[actionIndex - 1]->name); | |||||
| if (/*std::abs(internal->historyActionIndex = actionIndex) > 1 ||*/ name != "move knob") { | |||||
| printf("action '%s'\n", APP->history->actions[actionIndex - 1]->name.c_str()); | |||||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||||
| window::generateScreenshot(); | |||||
| } | |||||
| internal->historyActionIndex = actionIndex; | internal->historyActionIndex = actionIndex; | ||||
| internal->lastSceneChangeTime = time; | internal->lastSceneChangeTime = time; | ||||
| remoteUtils::deployToRemote(remoteDetails); | |||||
| window::generateScreenshot(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -319,7 +323,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { | |||||
| } | } | ||||
| if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) { | if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) { | ||||
| if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | ||||
| remoteUtils::deployToRemote(remoteDetails); | |||||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||||
| window::generateScreenshot(); | window::generateScreenshot(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| @@ -585,9 +585,10 @@ static void Window__downscaleBitmap(uint8_t* pixels, int& width, int& height) { | |||||
| static void Window__writeImagePNG(void* context, void* data, int size) { | static void Window__writeImagePNG(void* context, void* data, int size) { | ||||
| USE_NAMESPACE_DISTRHO | USE_NAMESPACE_DISTRHO | ||||
| CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context); | CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context); | ||||
| if (const char* const screenshot = String::asBase64(data, size).buffer()) { | |||||
| if (char* const screenshot = String::asBase64(data, size).getAndReleaseBuffer()) { | |||||
| ui->setState("screenshot", screenshot); | ui->setState("screenshot", screenshot); | ||||
| remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); | remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); | ||||
| std::free(screenshot); | |||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||