diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index fb8cc545a..7cdee10bc 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -20,10 +20,6 @@ #include "CarlaBackend.h" -#ifdef BUILD_BRIDGE -struct CarlaOscData; -#endif - namespace water { class MemoryOutputStream; class XmlDocument; @@ -979,8 +975,9 @@ public: /*! * Get a plugin's peak values. + * @note not thread-safe if pluginId == MAIN_CARLA_PLUGIN_ID */ - float* getPeaks(const uint pluginId) const noexcept; + const float* getPeaks(const uint pluginId) const noexcept; /*! * Get a plugin's input peak value. @@ -1129,11 +1126,6 @@ public: */ bool isOscControlRegistered() const noexcept; - /*! - * Idle OSC. - */ - void idleOsc() const noexcept; - /*! * Get OSC TCP server path. */ @@ -1166,7 +1158,7 @@ public: protected: /*! - * Internal data, for CarlaEngine subclasses only. + * Internal data, for CarlaEngine subclasses and friends. */ struct ProtectedData; ProtectedData* const pData; @@ -1174,6 +1166,7 @@ protected: /*! * Some internal classes read directly from pData or call protected functions. */ + friend class CarlaEngineThread; friend class CarlaPluginInstance; friend class EngineInternalGraph; friend class PendingRtEventsRunner; @@ -1206,7 +1199,7 @@ protected: * Set a plugin (stereo) peak values. * @note RT call */ - void setPluginPeaks(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept; + void setPluginPeaksRT(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept; /*! * Common save project function for main engine and plugin. @@ -1282,40 +1275,6 @@ public: # endif #endif -#ifndef BUILD_BRIDGE - // ------------------------------------------------------------------- - // OSC Controller stuff - - void oscSend_control_callback(const EngineCallbackOpcode action, const uint pluginId, - const int value1, const int value2, const int value3, - const float valuef, const char* const valueStr) const noexcept; - void oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept; - // void oscSend_control_add_plugin_end(const uint pluginId) const noexcept; - // void oscSend_control_remove_plugin(const uint pluginId) const noexcept; - void oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const int64_t uniqueId) const noexcept; - void oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept; - void oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept; - void oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept; - void oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept; - void oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept; - void oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept; - void oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept; - void oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept; - void oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept; - // void oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept; - // void oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept; - void oscSend_control_set_output_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept; - // void oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept; - // void oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept; - // void oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept; - void oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept; - void oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept; - // void oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept; - // void oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept; - void oscSend_control_set_peaks(const uint pluginId) const noexcept; - // void oscSend_control_exit() const noexcept; -#endif - CARLA_DECLARE_NON_COPY_CLASS(CarlaEngine) }; diff --git a/source/backend/CarlaHost.h b/source/backend/CarlaHost.h index efdf957b0..cf73fc6b3 100644 --- a/source/backend/CarlaHost.h +++ b/source/backend/CarlaHost.h @@ -774,7 +774,7 @@ CARLA_EXPORT float carla_get_internal_parameter_value(uint pluginId, int32_t par * Get a plugin's peak values. * @param pluginId Plugin */ -CARLA_EXPORT float* carla_get_peak_values(uint pluginId); +CARLA_EXPORT const float* carla_get_peak_values(uint pluginId); /*! * Get a plugin's input peak value. diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 98f7128b2..f05673a3b 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -725,19 +725,15 @@ public: // ------------------------------------------------------------------- // OSC stuff -#ifndef BUILD_BRIDGE - /*! - * Register this plugin to the engine's OSC client (controller or bridge). - * TODO - */ - void registerToOscClient() noexcept; -#endif - /*! * Handle an OSC message. * FIXME */ - virtual void handleOscMessage(const char* const method, const int argc, const void* const argv, const char* const types, const lo_message msg); + virtual void handleOscMessage(const char* const method, + const int argc, + const void* const argv, + const char* const types, + const lo_message msg); // ------------------------------------------------------------------- // MIDI events @@ -747,7 +743,8 @@ public: * A note with 0 velocity means note-off. * @note Non-RT call */ - void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback); + void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, + const bool sendGui, const bool sendOsc, const bool sendCallback); #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH /*! @@ -755,7 +752,7 @@ public: * This doesn't send the actual MIDI All-Notes-Off event, but 128 note-offs instead (IFF ctrlChannel is valid). * @note RT call */ - void sendMidiAllNotesOffToCallback(); + void postponeRtAllNotesOff(); #endif // ------------------------------------------------------------------- diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index 11be28082..558790f6b 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -1729,7 +1729,7 @@ float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId) // -------------------------------------------------------------------------------------------------------------------- -float* carla_get_peak_values(uint pluginId) +const float* carla_get_peak_values(uint pluginId) { CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr); diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 3b40273b2..b03443940 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1235,9 +1235,9 @@ EngineTimeInfo CarlaEngine::getTimeInfo() const noexcept // ----------------------------------------------------------------------- // Information (peaks) -float* CarlaEngine::getPeaks(const uint pluginId) const noexcept +const float* CarlaEngine::getPeaks(const uint pluginId) const noexcept { - carla_zeroFloats(pData->peaks, 4); + static const float kFallback[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; if (pluginId == MAIN_CARLA_PLUGIN_ID) { @@ -1249,11 +1249,15 @@ float* CarlaEngine::getPeaks(const uint pluginId) const noexcept pData->peaks[2] = pData->plugins[count-1].peaks[2]; pData->peaks[3] = pData->plugins[count-1].peaks[3]; } + else + { + carla_zeroFloats(pData->peaks, 4); + } return pData->peaks; } - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, pData->peaks); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, kFallback); return pData->plugins[pluginId].peaks; } @@ -1332,13 +1336,66 @@ void CarlaEngine::callback(const bool sendHost, const bool sendOsc, { switch (action) { + case ENGINE_CALLBACK_RELOAD_INFO: + { + CarlaPlugin* const plugin = pData->plugins[pluginId].plugin; + CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); + + pData->osc.sendPluginInfo(plugin); + break; + } + + case ENGINE_CALLBACK_RELOAD_PARAMETERS: + { + CarlaPlugin* const plugin = pData->plugins[pluginId].plugin; + CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); + + pData->osc.sendPluginPortCount(plugin); + + if (const uint32_t count = plugin->getParameterCount()) + { + for (uint32_t i=0; iosc.sendPluginParameterInfo(plugin, i); + } + break; + } + + case ENGINE_CALLBACK_RELOAD_PROGRAMS: + { + CarlaPlugin* const plugin = pData->plugins[pluginId].plugin; + CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); + +#if 0 + pData->engine->oscSend_control_set_midi_program_count(pData->id, count); + + for (uint32_t i=0; i < count; ++i) + pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name); + + pData->engine->oscSend_control_set_program_count(pData->id, newCount); + + for (uint32_t i=0; i < newCount; ++i) + pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]); +#endif + break; + } + case ENGINE_CALLBACK_PLUGIN_ADDED: case ENGINE_CALLBACK_RELOAD_ALL: { CarlaPlugin* const plugin = pData->plugins[pluginId].plugin; CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); - plugin->registerToOscClient(); + pData->osc.sendPluginInit(pluginId, plugin->getName()); + pData->osc.sendPluginInfo(plugin); + pData->osc.sendPluginPortCount(plugin); + + if (const uint32_t count = plugin->getParameterCount()) + { + for (uint32_t i=0; iosc.sendPluginParameterInfo(plugin, i); + } + + pData->osc.sendPluginInternalParameterValues(plugin); break; } @@ -1349,7 +1406,7 @@ void CarlaEngine::callback(const bool sendHost, const bool sendOsc, break; } - oscSend_control_callback(action, pluginId, value1, value2, value3, valuef, valueStr); + pData->osc.sendCallback(action, pluginId, value1, value2, value3, valuef, valueStr); } #endif } @@ -1772,13 +1829,6 @@ bool CarlaEngine::isOscControlRegistered() const noexcept # endif } -void CarlaEngine::idleOsc() const noexcept -{ -# ifdef HAVE_LIBLO - pData->osc.idle(); -# endif -} - const char* CarlaEngine::getOscServerPathTCP() const noexcept { # ifdef HAVE_LIBLO @@ -1888,7 +1938,7 @@ void CarlaEngine::offlineModeChanged(const bool isOfflineNow) } } -void CarlaEngine::setPluginPeaks(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept +void CarlaEngine::setPluginPeaksRT(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept { EnginePluginData& pluginData(pData->plugins[pluginId]); diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index d3eb3ccde..86e2de71c 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1377,7 +1377,7 @@ public: for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), numChanu); isetPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); + kEngine->setPluginPeaksRT(fPlugin->getId(), inPeaks, outPeaks); } else { diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 27b18d335..e4c8aeae3 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -369,7 +369,6 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept : thread(engine), #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) osc(engine), - oscData(nullptr), #endif callback(nullptr), callbackPtr(nullptr), @@ -426,9 +425,6 @@ CarlaEngine::ProtectedData::~ProtectedData() noexcept bool CarlaEngine::ProtectedData::init(const char* const clientName) { CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)"); -#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) - CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)"); -#endif CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)"); CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.out == nullptr, "Invalid engine internal data (err #5)"); CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name"); @@ -480,10 +476,7 @@ bool CarlaEngine::ProtectedData::init(const char* const clientName) #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) if (options.oscEnabled) - { osc.init(clientName, options.oscPortTCP, options.oscPortUDP); - oscData = osc.getControlData(); - } #endif #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH @@ -514,7 +507,6 @@ void CarlaEngine::ProtectedData::close() #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) osc.close(); - oscData = nullptr; #endif aboutToClose = false; diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 0d94590e3..d24e903a6 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2018 Filipe Coelho + * Copyright (C) 2011-2019 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -214,7 +214,6 @@ struct CarlaEngine::ProtectedData { #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) CarlaEngineOsc osc; - const CarlaOscData* oscData; #endif EngineCallbackFunc callback; diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index e8aeb9665..71864e75b 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -2544,7 +2544,7 @@ private: } } - setPluginPeaks(plugin->getId(), inPeaks, outPeaks); + setPluginPeaksRT(plugin->getId(), inPeaks, outPeaks); } #ifndef BUILD_BRIDGE diff --git a/source/backend/engine/CarlaEngineOsc.cpp b/source/backend/engine/CarlaEngineOsc.cpp index f5871f218..1a239499d 100644 --- a/source/backend/engine/CarlaEngineOsc.cpp +++ b/source/backend/engine/CarlaEngineOsc.cpp @@ -15,16 +15,11 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaDefines.h" +#include "CarlaEngineOsc.hpp" #ifdef HAVE_LIBLO #include "CarlaEngine.hpp" -#include "CarlaEngineOsc.hpp" -#include "CarlaPlugin.hpp" -#include "CarlaMIDI.h" - -#include CARLA_BACKEND_START_NAMESPACE @@ -32,7 +27,8 @@ CARLA_BACKEND_START_NAMESPACE CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine) noexcept : fEngine(engine), - fControlData(), + fControlDataTCP(), + fControlDataUDP(), fName(), fServerPathTCP(), fServerPathUDP(), @@ -206,413 +202,8 @@ void CarlaEngineOsc::close() noexcept fServerPathTCP.clear(); fServerPathUDP.clear(); - fControlData.clear(); -} - -// ----------------------------------------------------------------------- - -int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg) -{ - CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1); - CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', 1); -#ifdef DEBUG - if (std::strstr(path, "/bridge_pong") == nullptr) { - carla_debug("CarlaEngineOsc::handleMessage(%s, \"%s\", %i, %p, \"%s\", %p)", bool2str(isTCP), path, argc, argv, types, msg); - } -#endif - - if (isTCP) - { - CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isNotEmpty(), 1); - CARLA_SAFE_ASSERT_RETURN(fServerTCP != nullptr, 1); - } - else - { - CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isNotEmpty(), 1); - CARLA_SAFE_ASSERT_RETURN(fServerUDP != nullptr, 1); - } - - // Initial path check - if (std::strcmp(path, "/register") == 0) - return handleMsgRegister(isTCP, argc, argv, types); - - if (std::strcmp(path, "/unregister") == 0) - return handleMsgUnregister(argc, argv, types); - - const std::size_t nameSize(fName.length()); - - // Check if message is for this client - if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0) - { - carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, fName.buffer()); - return 1; - } - - // Get plugin id from path, "/carla/23/method" -> 23 - uint pluginId = 0; - std::size_t offset; - - if (std::isdigit(path[nameSize+2])) - { - if (std::isdigit(path[nameSize+3])) - { - if (std::isdigit(path[nameSize+5])) - { - carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", path+(nameSize+1)); - return 1; - } - else if (std::isdigit(path[nameSize+4])) - { - // 3 digits, /xyz/method - offset = 6; - pluginId += uint(path[nameSize+2]-'0')*100; - pluginId += uint(path[nameSize+3]-'0')*10; - pluginId += uint(path[nameSize+4]-'0'); - } - else - { - // 2 digits, /xy/method - offset = 5; - pluginId += uint(path[nameSize+2]-'0')*10; - pluginId += uint(path[nameSize+3]-'0'); - } - } - else - { - // single digit, /x/method - offset = 4; - pluginId += uint(path[nameSize+2]-'0'); - } - } - else - { - carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path); - return 1; - } - - if (pluginId > fEngine->getCurrentPluginCount()) - { - carla_stderr("CarlaEngineOsc::handleMessage() - failed to get plugin, wrong id '%i'", pluginId); - return 0; - } - - // Get plugin - CarlaPlugin* const plugin(fEngine->getPluginUnchecked(pluginId)); - - if (plugin == nullptr || plugin->getId() != pluginId) - { - carla_stderr("CarlaEngineOsc::handleMessage() - invalid plugin id '%i', probably has been removed (path: '%s')", pluginId, path); - return 0; - } - - // Get method from path, "/Carla/i/method" -> "method" - char method[32+1]; - method[32] = '\0'; - std::strncpy(method, path + (nameSize + offset), 32); - - if (method[0] == '\0') - { - carla_stderr("CarlaEngineOsc::handleMessage(%s, \"%s\", ...) - received message without method", bool2str(isTCP), path); - return 0; - } - - // Internal methods - if (std::strcmp(method, "set_option") == 0) - return 0; //handleMsgSetOption(plugin, argc, argv, types); // TODO - if (std::strcmp(method, "set_active") == 0) - return handleMsgSetActive(plugin, argc, argv, types); - if (std::strcmp(method, "set_drywet") == 0) - return handleMsgSetDryWet(plugin, argc, argv, types); - if (std::strcmp(method, "set_volume") == 0) - return handleMsgSetVolume(plugin, argc, argv, types); - if (std::strcmp(method, "set_balance_left") == 0) - return handleMsgSetBalanceLeft(plugin, argc, argv, types); - if (std::strcmp(method, "set_balance_right") == 0) - return handleMsgSetBalanceRight(plugin, argc, argv, types); - if (std::strcmp(method, "set_panning") == 0) - return handleMsgSetPanning(plugin, argc, argv, types); - if (std::strcmp(method, "set_ctrl_channel") == 0) - return 0; //handleMsgSetControlChannel(plugin, argc, argv, types); // TODO - if (std::strcmp(method, "set_parameter_value") == 0) - return handleMsgSetParameterValue(plugin, argc, argv, types); - if (std::strcmp(method, "set_parameter_midi_cc") == 0) - return handleMsgSetParameterMidiCC(plugin, argc, argv, types); - if (std::strcmp(method, "set_parameter_midi_channel") == 0) - return handleMsgSetParameterMidiChannel(plugin, argc, argv, types); - if (std::strcmp(method, "set_program") == 0) - return handleMsgSetProgram(plugin, argc, argv, types); - if (std::strcmp(method, "set_midi_program") == 0) - return handleMsgSetMidiProgram(plugin, argc, argv, types); - if (std::strcmp(method, "set_custom_data") == 0) - return 0; //handleMsgSetCustomData(plugin, argc, argv, types); // TODO - if (std::strcmp(method, "set_chunk") == 0) - return 0; //handleMsgSetChunk(plugin, argc, argv, types); // TODO - if (std::strcmp(method, "note_on") == 0) - return handleMsgNoteOn(plugin, argc, argv, types); - if (std::strcmp(method, "note_off") == 0) - return handleMsgNoteOff(plugin, argc, argv, types); - - // Send all other methods to plugins, TODO - plugin->handleOscMessage(method, argc, argv, types, msg); - return 0; -} - -// ----------------------------------------------------------------------- - -int CarlaEngineOsc::handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types) -{ - carla_debug("CarlaEngineOsc::handleMsgRegister()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); - - const char* const url = &argv[0]->s; - const lo_address addr = lo_address_new_from_url(url); - - if (fControlData.owner != nullptr) - { - carla_stderr("OSC backend already registered to %s", fControlData.owner); - - char* const path = lo_url_get_path(url); - - char targetPath[std::strlen(path)+18]; - std::strcpy(targetPath, path); - std::strcat(targetPath, "/exit-error"); - - lo_send_from(addr, isTCP ? fServerTCP : fServerUDP, LO_TT_IMMEDIATE, - targetPath, "s", "OSC already registered to another client"); - - free(path); - } - else - { - carla_stdout("OSC backend registered to %s", url); - - const char* const host = lo_address_get_hostname(addr); - const char* const port = lo_address_get_port(addr); - const lo_address target = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port); - - fControlData.owner = carla_strdup_safe(url); - fControlData.path = carla_strdup_free(lo_url_get_path(url)); - fControlData.source = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port); - fControlData.target = target; - - for (uint i=0, count=fEngine->getCurrentPluginCount(); i < count; ++i) - { - CarlaPlugin* const plugin(fEngine->getPluginUnchecked(i)); - CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr); - - fEngine->callback(false, true, ENGINE_CALLBACK_PLUGIN_ADDED, i, 0, 0, 0, 0.0f, plugin->getName()); - } - - const EngineOptions& opts(fEngine->getOptions()); - - fEngine->callback(false, true, - ENGINE_CALLBACK_ENGINE_STARTED, 0, - opts.processMode, - opts.transportMode, - static_cast(fEngine->getBufferSize()), - static_cast(fEngine->getSampleRate()), - fEngine->getCurrentDriverName()); - - // TODO - // fEngine->patchbayRefresh(); - } - - lo_address_free(addr); - return 0; -} - -int CarlaEngineOsc::handleMsgUnregister(const int argc, const lo_arg* const* const argv, const char* const types) -{ - carla_debug("CarlaEngineOsc::handleMsgUnregister()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); - - if (fControlData.owner == nullptr) - { - carla_stderr("OSC backend is not registered yet, unregister failed"); - return 0; - } - - const char* const url = &argv[0]->s; - - if (std::strcmp(fControlData.owner, url) == 0) - { - carla_stdout("OSC client %s unregistered", url); - fControlData.clear(); - return 0; - } - - carla_stderr("OSC backend unregister failed, current owner %s does not match requested %s", fControlData.owner, url); - return 0; -} - -// ----------------------------------------------------------------------- - -int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetActive()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); - - const bool active = (argv[0]->i != 0); - - plugin->setActive(active, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetDryWet()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); - - const float value = argv[0]->f; - - plugin->setDryWet(value, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetVolume()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); - - const float value = argv[0]->f; - - plugin->setVolume(value, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); - - const float value = argv[0]->f; - - plugin->setBalanceLeft(value, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); - - const float value = argv[0]->f; - - plugin->setBalanceRight(value, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetPanning()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); - - const float value = argv[0]->f; - - plugin->setPanning(value, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); - - const int32_t index = argv[0]->i; - const float value = argv[1]->f; - - CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); - - plugin->setParameterValue(static_cast(index), value, true, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); - - const int32_t index = argv[0]->i; - const int32_t cc = argv[1]->i; - - CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); - CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL, 0); - - plugin->setParameterMidiCC(static_cast(index), static_cast(cc), false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); - - const int32_t index = argv[0]->i; - const int32_t channel = argv[1]->i; - - CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); - CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); - - plugin->setParameterMidiChannel(static_cast(index), static_cast(channel), false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetProgram()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); - - const int32_t index = argv[0]->i; - - CARLA_SAFE_ASSERT_RETURN(index >= -1, 0); - - plugin->setProgram(index, true, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); - - const int32_t index = argv[0]->i; - - CARLA_SAFE_ASSERT_RETURN(index >= -1, 0); - - plugin->setMidiProgram(index, true, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgNoteOn()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii"); - - const int32_t channel = argv[0]->i; - const int32_t note = argv[1]->i; - const int32_t velo = argv[2]->i; - - CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); - CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0); - CARLA_SAFE_ASSERT_RETURN(velo >= 0 && velo < MAX_MIDI_VALUE, 0); - - plugin->sendMidiSingleNote(static_cast(channel), static_cast(note), static_cast(velo), true, false, true); - return 0; -} - -int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS) -{ - carla_debug("CarlaEngineOsc::handleMsgNoteOff()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); - - const int32_t channel = argv[0]->i; - const int32_t note = argv[1]->i; - - CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); - CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0); - - plugin->sendMidiSingleNote(static_cast(channel), static_cast(note), 0, true, false, true); - return 0; + fControlDataTCP.clear(); + fControlDataUDP.clear(); } // ----------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineOsc.hpp b/source/backend/engine/CarlaEngineOsc.hpp index 20b6a0e07..402e00059 100644 --- a/source/backend/engine/CarlaEngineOsc.hpp +++ b/source/backend/engine/CarlaEngineOsc.hpp @@ -81,20 +81,37 @@ public: bool isControlRegistered() const noexcept { - return (fControlData.target != nullptr); + return (fControlDataTCP.target != nullptr); } - const CarlaOscData* getControlData() const noexcept - { - return &fControlData; - } + // ------------------------------------------------------------------- + // TCP + + void sendCallback(const EngineCallbackOpcode action, const uint pluginId, + const int value1, const int value2, const int value3, + const float valuef, const char* const valueStr) const noexcept; + void sendPluginInit(const uint pluginId, const char* const pluginName) const noexcept; + void sendPluginInfo(const CarlaPlugin* const plugin) const noexcept; + void sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept; + void sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t parameterId) const noexcept; + void sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept; + void sendRuntimeInfo() const noexcept; + + // ------------------------------------------------------------------- + // UDP + + void sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept; + void sendPeaks(const uint pluginId, const float peaks[4]) const noexcept; // ------------------------------------------------------------------- private: CarlaEngine* const fEngine; - CarlaOscData fControlData; // for carla-control + // for carla-control + CarlaOscData fControlDataTCP; + CarlaOscData fControlDataUDP; + CarlaString fName; CarlaString fServerPathTCP; CarlaString fServerPathUDP; @@ -103,10 +120,11 @@ private: // ------------------------------------------------------------------- - int handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg); + int handleMessage(const bool isTCP, const char* const path, + const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg); int handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types); - int handleMsgUnregister(const int argc, const lo_arg* const* const argv, const char* const types); + int handleMsgUnregister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types); // Internal methods int handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS); diff --git a/source/backend/engine/CarlaEngineOscHandlers.cpp b/source/backend/engine/CarlaEngineOscHandlers.cpp new file mode 100644 index 000000000..24db2b083 --- /dev/null +++ b/source/backend/engine/CarlaEngineOscHandlers.cpp @@ -0,0 +1,446 @@ + /* + * Carla Plugin Host + * Copyright (C) 2011-2019 Filipe Coelho + * + * 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 2 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 doc/GPL.txt file. + */ + +#include "CarlaEngineOsc.hpp" + +#ifdef HAVE_LIBLO + +#include "CarlaEngine.hpp" +#include "CarlaPlugin.hpp" +#include "CarlaMIDI.h" + +#include + +CARLA_BACKEND_START_NAMESPACE + +// ----------------------------------------------------------------------- + +int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg) +{ + CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1); + CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', 1); +#ifdef DEBUG + if (std::strstr(path, "/bridge_pong") == nullptr) { + carla_debug("CarlaEngineOsc::handleMessage(%s, \"%s\", %i, %p, \"%s\", %p)", bool2str(isTCP), path, argc, argv, types, msg); + } +#endif + + if (isTCP) + { + CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isNotEmpty(), 1); + CARLA_SAFE_ASSERT_RETURN(fServerTCP != nullptr, 1); + } + else + { + CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isNotEmpty(), 1); + CARLA_SAFE_ASSERT_RETURN(fServerUDP != nullptr, 1); + } + + // Initial path check + if (std::strcmp(path, "/register") == 0) + return handleMsgRegister(isTCP, argc, argv, types); + + if (std::strcmp(path, "/unregister") == 0) + return handleMsgUnregister(isTCP, argc, argv, types); + + const std::size_t nameSize(fName.length()); + + // Check if message is for this client + if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0) + { + carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, fName.buffer()); + return 1; + } + + // Get plugin id from path, "/carla/23/method" -> 23 + uint pluginId = 0; + std::size_t offset; + + if (std::isdigit(path[nameSize+2])) + { + if (std::isdigit(path[nameSize+3])) + { + if (std::isdigit(path[nameSize+5])) + { + carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", path+(nameSize+1)); + return 1; + } + else if (std::isdigit(path[nameSize+4])) + { + // 3 digits, /xyz/method + offset = 6; + pluginId += uint(path[nameSize+2]-'0')*100; + pluginId += uint(path[nameSize+3]-'0')*10; + pluginId += uint(path[nameSize+4]-'0'); + } + else + { + // 2 digits, /xy/method + offset = 5; + pluginId += uint(path[nameSize+2]-'0')*10; + pluginId += uint(path[nameSize+3]-'0'); + } + } + else + { + // single digit, /x/method + offset = 4; + pluginId += uint(path[nameSize+2]-'0'); + } + } + else + { + carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path); + return 1; + } + + if (pluginId > fEngine->getCurrentPluginCount()) + { + carla_stderr("CarlaEngineOsc::handleMessage() - failed to get plugin, wrong id '%i'", pluginId); + return 0; + } + + // Get plugin + CarlaPlugin* const plugin(fEngine->getPluginUnchecked(pluginId)); + + if (plugin == nullptr || plugin->getId() != pluginId) + { + carla_stderr("CarlaEngineOsc::handleMessage() - invalid plugin id '%i', probably has been removed (path: '%s')", pluginId, path); + return 0; + } + + // Get method from path, "/Carla/i/method" -> "method" + char method[32+1]; + method[32] = '\0'; + std::strncpy(method, path + (nameSize + offset), 32); + + if (method[0] == '\0') + { + carla_stderr("CarlaEngineOsc::handleMessage(%s, \"%s\", ...) - received message without method", bool2str(isTCP), path); + return 0; + } + + // Internal methods + if (std::strcmp(method, "set_option") == 0) + return 0; //handleMsgSetOption(plugin, argc, argv, types); // TODO + if (std::strcmp(method, "set_active") == 0) + return handleMsgSetActive(plugin, argc, argv, types); + if (std::strcmp(method, "set_drywet") == 0) + return handleMsgSetDryWet(plugin, argc, argv, types); + if (std::strcmp(method, "set_volume") == 0) + return handleMsgSetVolume(plugin, argc, argv, types); + if (std::strcmp(method, "set_balance_left") == 0) + return handleMsgSetBalanceLeft(plugin, argc, argv, types); + if (std::strcmp(method, "set_balance_right") == 0) + return handleMsgSetBalanceRight(plugin, argc, argv, types); + if (std::strcmp(method, "set_panning") == 0) + return handleMsgSetPanning(plugin, argc, argv, types); + if (std::strcmp(method, "set_ctrl_channel") == 0) + return 0; //handleMsgSetControlChannel(plugin, argc, argv, types); // TODO + if (std::strcmp(method, "set_parameter_value") == 0) + return handleMsgSetParameterValue(plugin, argc, argv, types); + if (std::strcmp(method, "set_parameter_midi_cc") == 0) + return handleMsgSetParameterMidiCC(plugin, argc, argv, types); + if (std::strcmp(method, "set_parameter_midi_channel") == 0) + return handleMsgSetParameterMidiChannel(plugin, argc, argv, types); + if (std::strcmp(method, "set_program") == 0) + return handleMsgSetProgram(plugin, argc, argv, types); + if (std::strcmp(method, "set_midi_program") == 0) + return handleMsgSetMidiProgram(plugin, argc, argv, types); + if (std::strcmp(method, "set_custom_data") == 0) + return 0; //handleMsgSetCustomData(plugin, argc, argv, types); // TODO + if (std::strcmp(method, "set_chunk") == 0) + return 0; //handleMsgSetChunk(plugin, argc, argv, types); // TODO + if (std::strcmp(method, "note_on") == 0) + return handleMsgNoteOn(plugin, argc, argv, types); + if (std::strcmp(method, "note_off") == 0) + return handleMsgNoteOff(plugin, argc, argv, types); + + // Send all other methods to plugins, TODO + plugin->handleOscMessage(method, argc, argv, types, msg); + return 0; +} + +// ----------------------------------------------------------------------- + +int CarlaEngineOsc::handleMsgRegister(const bool isTCP, + const int argc, const lo_arg* const* const argv, const char* const types) +{ + carla_debug("CarlaEngineOsc::handleMsgRegister()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); + + const char* const url = &argv[0]->s; + const lo_address addr = lo_address_new_from_url(url); + + CarlaOscData& oscData(isTCP ? fControlDataTCP : fControlDataUDP); + + if (oscData.owner != nullptr) + { + carla_stderr("OSC backend already registered to %s", oscData.owner); + + char* const path = lo_url_get_path(url); + + char targetPath[std::strlen(path)+18]; + std::strcpy(targetPath, path); + std::strcat(targetPath, "/exit-error"); + + lo_send_from(addr, isTCP ? fServerTCP : fServerUDP, LO_TT_IMMEDIATE, + targetPath, "s", "OSC already registered to another client"); + + free(path); + } + else + { + carla_stdout("OSC backend registered to %s", url); + + const char* const host = lo_address_get_hostname(addr); + const char* const port = lo_address_get_port(addr); + const lo_address target = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port); + + oscData.owner = carla_strdup_safe(url); + oscData.path = carla_strdup_free(lo_url_get_path(url)); + oscData.source = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port); + oscData.target = target; + + for (uint i=0, count=fEngine->getCurrentPluginCount(); i < count; ++i) + { + CarlaPlugin* const plugin(fEngine->getPluginUnchecked(i)); + CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr); + + fEngine->callback(false, true, ENGINE_CALLBACK_PLUGIN_ADDED, i, 0, 0, 0, 0.0f, plugin->getName()); + } + + const EngineOptions& opts(fEngine->getOptions()); + + fEngine->callback(false, true, + ENGINE_CALLBACK_ENGINE_STARTED, 0, + opts.processMode, + opts.transportMode, + static_cast(fEngine->getBufferSize()), + static_cast(fEngine->getSampleRate()), + fEngine->getCurrentDriverName()); + + // TODO + // fEngine->patchbayRefresh(); + } + + lo_address_free(addr); + return 0; +} + +int CarlaEngineOsc::handleMsgUnregister(const bool isTCP, + const int argc, const lo_arg* const* const argv, const char* const types) +{ + carla_debug("CarlaEngineOsc::handleMsgUnregister()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); + + CarlaOscData& oscData(isTCP ? fControlDataTCP : fControlDataUDP); + + if (oscData.owner == nullptr) + { + carla_stderr("OSC backend is not registered yet, unregister failed"); + return 0; + } + + const char* const url = &argv[0]->s; + + if (std::strcmp(oscData.owner, url) == 0) + { + carla_stdout("OSC client %s unregistered", url); + oscData.clear(); + return 0; + } + + carla_stderr("OSC backend unregister failed, current owner %s does not match requested %s", oscData.owner, url); + return 0; +} + +// ----------------------------------------------------------------------- + +int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetActive()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); + + const bool active = (argv[0]->i != 0); + + plugin->setActive(active, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetDryWet()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); + + const float value = argv[0]->f; + + plugin->setDryWet(value, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetVolume()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); + + const float value = argv[0]->f; + + plugin->setVolume(value, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); + + const float value = argv[0]->f; + + plugin->setBalanceLeft(value, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); + + const float value = argv[0]->f; + + plugin->setBalanceRight(value, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetPanning()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); + + const float value = argv[0]->f; + + plugin->setPanning(value, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); + + const int32_t index = argv[0]->i; + const float value = argv[1]->f; + + CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); + + plugin->setParameterValue(static_cast(index), value, true, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); + + const int32_t index = argv[0]->i; + const int32_t cc = argv[1]->i; + + CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); + CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL, 0); + + plugin->setParameterMidiCC(static_cast(index), static_cast(cc), false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); + + const int32_t index = argv[0]->i; + const int32_t channel = argv[1]->i; + + CARLA_SAFE_ASSERT_RETURN(index >= 0, 0); + CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); + + plugin->setParameterMidiChannel(static_cast(index), static_cast(channel), false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetProgram()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); + + const int32_t index = argv[0]->i; + + CARLA_SAFE_ASSERT_RETURN(index >= -1, 0); + + plugin->setProgram(index, true, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); + + const int32_t index = argv[0]->i; + + CARLA_SAFE_ASSERT_RETURN(index >= -1, 0); + + plugin->setMidiProgram(index, true, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgNoteOn()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii"); + + const int32_t channel = argv[0]->i; + const int32_t note = argv[1]->i; + const int32_t velo = argv[2]->i; + + CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); + CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0); + CARLA_SAFE_ASSERT_RETURN(velo >= 0 && velo < MAX_MIDI_VALUE, 0); + + plugin->sendMidiSingleNote(static_cast(channel), static_cast(note), static_cast(velo), true, false, true); + return 0; +} + +int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS) +{ + carla_debug("CarlaEngineOsc::handleMsgNoteOff()"); + CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); + + const int32_t channel = argv[0]->i; + const int32_t note = argv[1]->i; + + CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0); + CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0); + + plugin->sendMidiSingleNote(static_cast(channel), static_cast(note), 0, true, false, true); + return 0; +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE + +#endif // HAVE_LIBLO diff --git a/source/backend/engine/CarlaEngineOscSend.cpp b/source/backend/engine/CarlaEngineOscSend.cpp index 5dd46d9f3..e699420dd 100644 --- a/source/backend/engine/CarlaEngineOscSend.cpp +++ b/source/backend/engine/CarlaEngineOscSend.cpp @@ -15,458 +15,278 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaDefines.h" +#include "CarlaEngineOsc.hpp" #ifdef HAVE_LIBLO #include "CarlaBackendUtils.hpp" -#include "CarlaEngineInternal.hpp" -#include "CarlaMIDI.h" +#include "CarlaEngine.hpp" +#include "CarlaPlugin.hpp" CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- -#ifndef BUILD_BRIDGE -void CarlaEngine::oscSend_control_callback(const EngineCallbackOpcode action, const uint pluginId, - const int value1, const int value2, const int value3, - const float valuef, const char* const valueStr) const noexcept +void CarlaEngineOsc::sendCallback(const EngineCallbackOpcode action, const uint pluginId, + const int value1, const int value2, const int value3, + const float valuef, const char* const valueStr) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_control_callback(%i:%s, %i, %i, %i, %i, %f, \"%s\")", + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + carla_debug("CarlaEngineOsc::sendCallback(%i:%s, %i, %i, %i, %i, %f, \"%s\")", action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valuef, valueStr); static const char* const kFakeNullString = "(null)"; - char targetPath[std::strlen(pData->oscData->path)+10]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/callback"); - try_lo_send(pData->oscData->target, targetPath, "iiiiifs", + char targetPath[std::strlen(fControlDataTCP.path)+10]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/cb"); + try_lo_send(fControlDataTCP.target, targetPath, "iiiiifs", action, pluginId, value1, value2, value3, static_cast(valuef), valueStr != nullptr ? valueStr : kFakeNullString); } -void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept +void CarlaEngineOsc::sendPluginInit(const uint pluginId, const char* const pluginName) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',); - carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); + carla_debug("CarlaEngineOsc::sendadd_plugin_start(%i, \"%s\")", pluginId, pluginName); - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_start"); - try_lo_send(pData->oscData->target, targetPath, "is", static_cast(pluginId), pluginName); + char targetPath[std::strlen(fControlDataTCP.path)+18]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/init"); + try_lo_send(fControlDataTCP.target, targetPath, "is", static_cast(pluginId), pluginName); } -#if 0 -void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+16]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_end"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} - -void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+15]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/remove_plugin"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} -#endif - -void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const int64_t uniqueId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, " P_INT64 ")", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info1"); - try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast(pluginId), static_cast(type), static_cast(category), static_cast(hints), static_cast(uniqueId)); -} - -void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); - CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info2"); - try_lo_send(pData->oscData->target, targetPath, "issss", static_cast(pluginId), realName, label, maker, copyright); -} - -void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_audio_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(ins < 50,); - CARLA_SAFE_ASSERT_RETURN(outs < 50,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(count <= 50,); - carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); -} - -void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept +void CarlaEngineOsc::sendPluginInfo(const CarlaPlugin* const plugin) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(count <= 50,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + carla_debug("CarlaEngineOsc::sendPluginInfo(%p)", plugin); + + char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1]; + carla_zeroChars(bufName, STR_MAX+1); + carla_zeroChars(bufLabel, STR_MAX+1); + carla_zeroChars(bufMaker, STR_MAX+1); + carla_zeroChars(bufCopyright, STR_MAX+1); + + plugin->getRealName(bufName); + plugin->getLabel(bufLabel); + plugin->getMaker(bufMaker); + plugin->getCopyright(bufCopyright); + + char targetPath[std::strlen(fControlDataTCP.path)+10]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/info"); + try_lo_send(fControlDataTCP.target, targetPath, "iiiihssss", + static_cast(plugin->getId()), + static_cast(plugin->getType()), + static_cast(plugin->getCategory()), + static_cast(plugin->getHints()), + static_cast(plugin->getUniqueId()), + bufName, bufLabel, bufMaker, bufCopyright); } -void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept +void CarlaEngineOsc::sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(pluginId), static_cast(index), static_cast(type), static_cast(hints), name, unit); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + carla_debug("CarlaEngineOsc::sendPluginInfo(%p)", plugin); + + uint32_t paramIns, paramOuts; + plugin->getParameterCountInfo(paramIns, paramOuts); + + if (paramIns > 49) + paramIns = 49; + if (paramOuts > 49) + paramOuts = 49; + + char targetPath[std::strlen(fControlDataTCP.path)+7]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/ports"); + try_lo_send(fControlDataTCP.target, targetPath, "iiiiiiii", + static_cast(plugin->getId()), + static_cast(plugin->getAudioInCount()), + static_cast(plugin->getAudioOutCount()), + static_cast(plugin->getMidiInCount()), + static_cast(plugin->getMidiOutCount()), + static_cast(paramIns), + static_cast(paramOuts), + static_cast(plugin->getParameterCount())); } -void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept +void CarlaEngineOsc::sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t parameterId) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT(def >= min && def <= max); - CARLA_SAFE_ASSERT(min < max); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges1"); - try_lo_send(pData->oscData->target, targetPath, "iifff", - static_cast(pluginId), - static_cast(index), - static_cast(def), - static_cast(min), - static_cast(max)); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + carla_debug("CarlaEngineOsc::sendPluginInfo(%p, %u)", plugin, parameterId); + + char bufName[STR_MAX+1], bufUnit[STR_MAX+1]; + carla_zeroChars(bufName, STR_MAX+1); + carla_zeroChars(bufUnit, STR_MAX+1); + + const ParameterData& paramData(plugin->getParameterData(parameterId)); + const ParameterRanges& paramRanges(plugin->getParameterRanges(parameterId)); + + plugin->getParameterName(parameterId, bufName); + plugin->getParameterUnit(parameterId, bufUnit); + + char targetPath[std::strlen(fControlDataTCP.path)+20]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/param"); + try_lo_send(fControlDataTCP.target, targetPath, "iiiiiissfffffff", + static_cast(plugin->getId()), static_cast(parameterId), + static_cast(paramData.type), static_cast(paramData.hints), + static_cast(paramData.midiChannel), static_cast(paramData.midiCC), + bufName, bufUnit, + static_cast(paramRanges.def), + static_cast(paramRanges.min), + static_cast(paramRanges.max), + static_cast(paramRanges.step), + static_cast(paramRanges.stepSmall), + static_cast(paramRanges.stepLarge), + static_cast(plugin->getParameterValue(parameterId))); } -void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept +void CarlaEngineOsc::sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT(step >= stepSmall && step <= stepLarge); - CARLA_SAFE_ASSERT(stepSmall <= stepLarge); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges2"); - try_lo_send(pData->oscData->target, targetPath, "iifff", - static_cast(pluginId), - static_cast(index), - static_cast(step), - static_cast(stepSmall), - static_cast(stepLarge)); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + carla_debug("CarlaEngineOsc::sendPluginInternalParameterValues(%p)", plugin); + + static_assert(PARAMETER_ACTIVE == -2 && PARAMETER_MAX == -9); + + double iparams[7]; + + for (int32_t i = 0; i < 7; ++i) + iparams[i] = plugin->getInternalParameterValue(PARAMETER_ACTIVE - i); + + char targetPath[std::strlen(fControlDataTCP.path)+18]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/iparams"); + try_lo_send(fControlDataTCP.target, targetPath, "ifffffff", + static_cast(plugin->getId()), + iparams[0], // PARAMETER_ACTIVE + iparams[1], // PARAMETER_DRYWET + iparams[2], // PARAMETER_VOLUME + iparams[3], // PARAMETER_BALANCE_LEFT + iparams[4], // PARAMETER_BALANCE_RIGHT + iparams[5], // PARAMETER_PANNING + iparams[6] // PARAMETER_CTRL_CHANNEL + ); } #if 0 -void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept +void CarlaEngineOsc::sendset_program_count(const uint pluginId, const uint32_t count) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_cc"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(cc)); -} + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + carla_debug("CarlaEngineOsc::sendset_program_count(%i, %i)", pluginId, count); -void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); - - char targetPath[std::strlen(pData->oscData->path)+28]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_channel"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(channel)); -} -#endif - -void CarlaEngine::oscSend_control_set_output_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); - carla_debug("CarlaEngine::oscSend_control_set_output_parameter_value(%i, %i:%s, %f)", pluginId, index, - (index < 0) ? InternalParameterIndex2Str(static_cast(index)) : "(none)", value); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_output_parameter_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", - static_cast(pluginId), - index, - static_cast(value)); -} - -#if 0 -void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_default_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", - static_cast(pluginId), - static_cast(index), - static_cast(value)); + char targetPath[std::strlen(fControlDataTCP.path)+19]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/set_program_count"); + try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast(pluginId), static_cast(count)); } -void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept +void CarlaEngineOsc::sendset_midi_program_count(const uint pluginId, const uint32_t count) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); -} + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + carla_debug("CarlaEngineOsc::sendset_midi_program_count(%i, %i)", pluginId, count); -void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); - carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_midi_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); + char targetPath[std::strlen(fControlDataTCP.path)+24]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/set_midi_program_count"); + try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast(pluginId), static_cast(count)); } -#endif -void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept +void CarlaEngineOsc::sendset_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); + carla_debug("CarlaEngineOsc::sendset_program_name(%i, %i, \"%s\")", pluginId, index, name); - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); + char targetPath[std::strlen(fControlDataTCP.path)+18]; + std::strcpy(targetPath, fControlDataTCP.path); std::strcat(targetPath, "/set_program_name"); - try_lo_send(pData->oscData->target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); + try_lo_send(fControlDataTCP.target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); } -void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept +void CarlaEngineOsc::sendset_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index < 50,); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); + carla_debug("CarlaEngineOsc::sendset_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); + char targetPath[std::strlen(fControlDataTCP.path)+23]; + std::strcpy(targetPath, fControlDataTCP.path); std::strcat(targetPath, "/set_midi_program_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); + try_lo_send(fControlDataTCP.target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); } +#endif -#if 0 -void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); - carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); - - char targetPath[std::strlen(pData->oscData->path)+9]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_on"); - try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast(pluginId), static_cast(channel), static_cast(note), static_cast(velo)); -} +// ----------------------------------------------------------------------- + +// FIXME use UDP -void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept +void CarlaEngineOsc::sendRuntimeInfo() const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note); - - char targetPath[std::strlen(pData->oscData->path)+10]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_off"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(channel), static_cast(note)); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + carla_debug("CarlaEngineOsc::sendRuntimeInfo()"); + + const EngineTimeInfo timeInfo(fEngine->getTimeInfo()); + + char targetPath[std::strlen(fControlDataTCP.path)+18]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/runtime"); + try_lo_send(fControlDataTCP.target, targetPath, "fiihiiif", + static_cast(fEngine->getDSPLoad()), + static_cast(fEngine->getTotalXruns()), + timeInfo.playing ? 1 : 0, + static_cast(timeInfo.frame), + static_cast(timeInfo.bbt.bar), + static_cast(timeInfo.bbt.beat), + static_cast(timeInfo.bbt.tick), + timeInfo.bbt.beatsPerMinute); } -#endif -void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept +void CarlaEngineOsc::sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - - // TODO - try and see if we can get peaks[4] ref - const EnginePluginData& epData(pData->plugins[pluginId]); - - char targetPath[std::strlen(pData->oscData->path)+11]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_peaks"); - try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast(pluginId), - static_cast(epData.peaks[0]), - static_cast(epData.peaks[1]), - static_cast(epData.peaks[2]), - static_cast(epData.peaks[3])); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + + char targetPath[std::strlen(fControlDataTCP.path)+21]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/param_fixme"); + try_lo_send(fControlDataTCP.target, targetPath, "iif", + static_cast(pluginId), + index, + static_cast(value)); } -#if 0 -void CarlaEngine::oscSend_control_exit() const noexcept +void CarlaEngineOsc::sendPeaks(const uint pluginId, const float peaks[4]) const noexcept { - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_control_exit()"); - - char targetPath[std::strlen(pData->oscData->path)+6]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/exit"); - try_lo_send(pData->oscData->target, targetPath, ""); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,); + + char targetPath[std::strlen(fControlDataTCP.path)+11]; + std::strcpy(targetPath, fControlDataTCP.path); + std::strcat(targetPath, "/peaks"); + try_lo_send(fControlDataTCP.target, targetPath, "iffff", static_cast(pluginId), + static_cast(peaks[0]), + static_cast(peaks[1]), + static_cast(peaks[2]), + static_cast(peaks[3])); } -#endif -#endif // BUILD_BRIDGE // ----------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineThread.cpp b/source/backend/engine/CarlaEngineThread.cpp index 18ebbd7ea..f71e2a092 100644 --- a/source/backend/engine/CarlaEngineThread.cpp +++ b/source/backend/engine/CarlaEngineThread.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2018 Filipe Coelho + * Copyright (C) 2011-2019 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,8 +15,8 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaEngine.hpp" #include "CarlaEngineThread.hpp" +#include "CarlaEngineInternal.hpp" #include "CarlaPlugin.hpp" CARLA_BACKEND_START_NAMESPACE @@ -48,6 +48,10 @@ void CarlaEngineThread::run() noexcept float value; +#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) + CarlaEngineOsc& engineOsc(kEngine->pData->osc); +#endif + // thread must do something... CARLA_SAFE_ASSERT_RETURN(kIsAlwaysRunning || kEngine->isRunning(),); @@ -61,7 +65,9 @@ void CarlaEngineThread::run() noexcept #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) if (kIsPlugin) - kEngine->idleOsc(); + engineOsc.idle(); + if (oscRegisted) + engineOsc.sendRuntimeInfo(); #endif for (uint i=0, count = kEngine->getCurrentPluginCount(); i < count; ++i) @@ -99,7 +105,7 @@ void CarlaEngineThread::run() noexcept #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) // Update OSC engine client if (oscRegisted) - kEngine->oscSend_control_set_output_parameter_value(i, static_cast(j), value); + engineOsc.sendParameterValue(i, j, value); #endif // Update UI if (updateUI) @@ -119,7 +125,7 @@ void CarlaEngineThread::run() noexcept // Update OSC control client peaks if (oscRegisted) - kEngine->oscSend_control_set_peaks(i); + engineOsc.sendPeaks(i, kEngine->getPeaks(i)); #endif } diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index f1a1fed92..b46471a77 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -28,6 +28,7 @@ OBJS = \ ifeq ($(HAVE_LIBLO),true) OBJS += \ $(OBJDIR)/CarlaEngineOsc.cpp.o \ + $(OBJDIR)/CarlaEngineOscHandlers.cpp.o \ $(OBJDIR)/CarlaEngineOscSend.cpp.o endif diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index ec28e1734..b32d9dcab 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -2124,95 +2124,12 @@ void CarlaPlugin::clearBuffers() noexcept pData->clearBuffers(); } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) // ------------------------------------------------------------------- // OSC stuff +#if 0 void CarlaPlugin::registerToOscClient() noexcept { - if (! pData->engine->isOscControlRegistered()) - return; - - pData->engine->oscSend_control_add_plugin_start(pData->id, pData->name); - - // Base data - { - char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1]; - carla_zeroChars(bufName, STR_MAX); - carla_zeroChars(bufLabel, STR_MAX); - carla_zeroChars(bufMaker, STR_MAX); - carla_zeroChars(bufCopyright, STR_MAX); - - getRealName(bufName); - getLabel(bufLabel); - getMaker(bufMaker); - getCopyright(bufCopyright); - - pData->engine->oscSend_control_set_plugin_info1(pData->id, getType(), getCategory(), pData->hints, getUniqueId()); - pData->engine->oscSend_control_set_plugin_info2(pData->id, bufName, bufLabel, bufMaker, bufCopyright); - } - - // Base count - uint32_t paramIns, paramOuts; - - { - getParameterCountInfo(paramIns, paramOuts); - - if (paramIns > 49) - paramIns = 49; - if (paramOuts > 49) - paramOuts = 49; - - pData->engine->oscSend_control_set_audio_count(pData->id, getAudioInCount(), getAudioOutCount()); - pData->engine->oscSend_control_set_midi_count(pData->id, getMidiInCount(), getMidiOutCount()); - pData->engine->oscSend_control_set_parameter_count(pData->id, paramIns, paramOuts); - } - - // Plugin Parameters - if (const uint32_t count = std::min(pData->param.count, 98U)) - { - char bufName[STR_MAX+1], bufUnit[STR_MAX+1]; - - for (uint32_t i=0; iparam.data[i]); - - if (paramData.type == PARAMETER_INPUT) - { - if (--paramIns == 0) - break; - } - else if (paramData.type == PARAMETER_OUTPUT) - { - if (--paramOuts == 0) - break; - } - else - { - continue; - } - - const ParameterRanges& paramRanges(pData->param.ranges[i]); - - carla_zeroChars(bufName, STR_MAX); - carla_zeroChars(bufUnit, STR_MAX); - - getParameterName(i, bufName); - getParameterUnit(i, bufUnit); - - pData->engine->oscSend_control_set_parameter_data(pData->id, i, paramData.type, paramData.hints, bufName, bufUnit); - pData->engine->oscSend_control_set_parameter_ranges1(pData->id, i, paramRanges.def, paramRanges.min, paramRanges.max); - pData->engine->oscSend_control_set_parameter_ranges2(pData->id, i, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge); -// pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast(i), getParameterValue(i)); -// -// if (paramData.midiCC >= 0) -// pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, i, paramData.midiCC); -// -// if (paramData.midiChannel != 0) -// pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, i, paramData.midiChannel); - } - } - // Programs if (const uint32_t count = std::min(pData->prog.count, 50U)) { @@ -2238,17 +2155,6 @@ void CarlaPlugin::registerToOscClient() noexcept // pData->engine->oscSend_control_set_current_midi_program(pData->id, pData->midiprog.current); } - - // Internal Parameters - { -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, pData->postProc.dryWet); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, pData->postProc.volume); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, pData->postProc.balanceLeft); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, pData->postProc.balanceRight); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, pData->postProc.panning); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, pData->ctrlChannel); -// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, pData->active ? 1.0f : 0.0f); - } } #endif @@ -2257,7 +2163,6 @@ void CarlaPlugin::handleOscMessage(const char* const, const int, const void* con { // do nothing } -//#endif // HAVE_LIBLO && ! BUILD_BRIDGE // ------------------------------------------------------------------- // MIDI events @@ -2296,7 +2201,7 @@ void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, } #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH -void CarlaPlugin::sendMidiAllNotesOffToCallback() +void CarlaPlugin::postponeRtAllNotesOff() { if (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS) return; diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 2c7e1f87e..8a3a81740 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -1316,7 +1316,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginDSSI.cpp b/source/backend/plugin/CarlaPluginDSSI.cpp index 6e6fd866b..ba5fd8db4 100644 --- a/source/backend/plugin/CarlaPluginDSSI.cpp +++ b/source/backend/plugin/CarlaPluginDSSI.cpp @@ -1221,17 +1221,6 @@ public: } } -#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_midi_program_count(pData->id, newCount); - - for (uint32_t i=0; i < newCount; ++i) - pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name); - } -#endif - if (doInit) { if (newCount > 0) @@ -1598,7 +1587,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginFluidSynth.cpp b/source/backend/plugin/CarlaPluginFluidSynth.cpp index 523b6c815..1b5303c96 100644 --- a/source/backend/plugin/CarlaPluginFluidSynth.cpp +++ b/source/backend/plugin/CarlaPluginFluidSynth.cpp @@ -1034,17 +1034,6 @@ public: return; } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_midi_program_count(pData->id, count); - - for (uint32_t i=0; i < count; ++i) - pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name); - } -#endif - if (doInit) { fluid_synth_program_reset(fSynth); @@ -1325,7 +1314,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index 427a53854..3fc82976c 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -1042,7 +1042,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginJuce.cpp b/source/backend/plugin/CarlaPluginJuce.cpp index f2a97016b..91212bcee 100644 --- a/source/backend/plugin/CarlaPluginJuce.cpp +++ b/source/backend/plugin/CarlaPluginJuce.cpp @@ -647,17 +647,6 @@ public: pData->prog.names[i] = carla_strdup(fInstance->getProgramName(i).toRawUTF8()); } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_program_count(pData->id, newCount); - - for (uint32_t i=0; i < newCount; ++i) - pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]); - } -#endif - if (doInit) { if (newCount > 0) @@ -936,7 +925,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 7ae788ac4..d9a430a4e 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -2848,17 +2848,6 @@ public: } } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_midi_program_count(pData->id, newCount); - - for (uint32_t i=0; i < newCount; ++i) - pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name); - } -#endif - if (doInit) { if (newCount > 0) @@ -3639,7 +3628,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp index 4eb26301e..fd4566339 100644 --- a/source/backend/plugin/CarlaPluginNative.cpp +++ b/source/backend/plugin/CarlaPluginNative.cpp @@ -1337,17 +1337,6 @@ public: } } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_midi_program_count(pData->id, count); - - for (i=0; i < count; ++i) - pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name); - } -#endif - if (doInit) { if (count > 0) @@ -1901,7 +1890,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginSFZero.cpp b/source/backend/plugin/CarlaPluginSFZero.cpp index 2bff18f36..eae89e3fb 100644 --- a/source/backend/plugin/CarlaPluginSFZero.cpp +++ b/source/backend/plugin/CarlaPluginSFZero.cpp @@ -497,7 +497,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp index fb1cc1375..3befd0704 100644 --- a/source/backend/plugin/CarlaPluginVST2.cpp +++ b/source/backend/plugin/CarlaPluginVST2.cpp @@ -987,17 +987,6 @@ public: } } -#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE) - // Update OSC Names - if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount()) - { - pData->engine->oscSend_control_set_program_count(pData->id, newCount); - - for (uint32_t i=0; i < newCount; ++i) - pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]); - } -#endif - if (doInit) { if (newCount > 0) @@ -1468,7 +1457,7 @@ public: if (event.channel == pData->ctrlChannel && ! allNotesOffSent) { allNotesOffSent = true; - sendMidiAllNotesOffToCallback(); + postponeRtAllNotesOff(); } #endif diff --git a/source/frontend/carla_backend.py b/source/frontend/carla_backend.py index 2fce1afcd..63c753b20 100644 --- a/source/frontend/carla_backend.py +++ b/source/frontend/carla_backend.py @@ -3462,4 +3462,23 @@ class CarlaHostPlugin(CarlaHostMeta): self.fPluginsInfo[pluginIdA] = self.fPluginsInfo[pluginIdB] self.fPluginsInfo[pluginIdB] = tmp + def _setViaCallback(self, action, pluginId, value1, value2, value3, valuef, valueStr): + if action == ENGINE_CALLBACK_PLUGIN_RENAMED: + self._set_pluginName(pluginId, valueStr) + elif action == ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED: + if value1 < 0: + self._set_internalValue(pluginId, value1, valuef) + else: + self._set_parameterValue(pluginId, value1, valuef) + elif action == ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED: + self._set_parameterDefault(pluginId, value1, valuef) + elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED: + self._set_parameterMidiCC(pluginId, value1, value2) + elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: + self._set_parameterMidiChannel(pluginId, value1, value2) + elif action == ENGINE_CALLBACK_PROGRAM_CHANGED: + self._set_currentProgram(pluginId, value1) + elif action == ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED: + self._set_currentMidiProgram(pluginId, value1) + # ------------------------------------------------------------------------------------------------------------ diff --git a/source/frontend/carla_control.py b/source/frontend/carla_control.py index 59c55eadb..aa5d37956 100755 --- a/source/frontend/carla_control.py +++ b/source/frontend/carla_control.py @@ -154,34 +154,38 @@ class CarlaControlServer(Server): def getFullURL(self): return "%scarla-control" % self.get_url() - @make_method('/carla-control/add_plugin_start', 'is') # FIXME skip name - def add_plugin_start_callback(self, path, args): + @make_method('/carla-control/cb', 'iiiiifs') + def carla_cb(self, path, args): + print(path, args) + self.fReceivedMsgs = True + action, pluginId, value1, value2, value3, valuef, valueStr = args + self.host._setViaCallback(action, pluginId, value1, value2, value3, valuef, valueStr) + engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr) + + @make_method('/carla-control/init', 'is') # FIXME set name in add method + def carla_init(self, path, args): print(path, args) self.fReceivedMsgs = True pluginId, pluginName = args self.host._add(pluginId) self.host._set_pluginInfoUpdate(pluginId, {'name': pluginName}) - #@make_method('/carla-control/add_plugin_end', 'i') # FIXME skip name - #def add_plugin_end_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, = args - #self.host.PluginAddedCallback.emit(pluginId, "") #self.fPluginsInfo[pluginId].pluginInfo['name']) - - #@make_method('/carla-control/remove_plugin', 'i') - #def remove_plugin_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, = args - #self.host.PluginRemovedCallback.emit(pluginId) - - @make_method('/carla-control/set_plugin_info1', 'iiiih') - def set_plugin_info1_callback(self, path, args): + @make_method('/carla-control/ports', 'iiiiiiii') + def carla_ports(self, path, args): print(path, args) self.fReceivedMsgs = True - pluginId, type_, category, hints, uniqueId = args # , optsAvail, optsEnabled + pluginId, audioIns, audioOuts, midiIns, midiOuts, paramIns, paramOuts, paramTotal = args + self.host._set_audioCountInfo(pluginId, {'ins': audioIns, 'outs': audioOuts}) + self.host._set_midiCountInfo(pluginId, {'ins': midiOuts, 'outs': midiOuts}) + self.host._set_parameterCountInfo(pluginId, paramTotal, {'ins': paramIns, 'outs': paramOuts}) + + @make_method('/carla-control/info', 'iiiihssss') + def carla_info(self, path, args): + print(path, args) + self.fReceivedMsgs = True + pluginId, type_, category, hints, uniqueId, realName, label, maker, copyright = args optsAvail = optsEnabled = 0x0 # FIXME + filename = name = iconName = "" # FIXME hints &= ~PLUGIN_HAS_CUSTOM_UI @@ -191,19 +195,7 @@ class CarlaControlServer(Server): 'hints': hints, 'optionsAvailable': optsAvail, 'optionsEnabled': optsEnabled, - 'uniqueId': uniqueId - } - - self.host._set_pluginInfoUpdate(pluginId, pinfo) - - @make_method('/carla-control/set_plugin_info2', 'issss') - def set_plugin_info2_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, realName, label, maker, copyright = args # , filename, name, iconName - filename = name = iconName = "" # FIXME - - pinfo = { + 'uniqueId': uniqueId, 'filename': filename, #'name': name, # FIXME 'label': label, @@ -215,47 +207,14 @@ class CarlaControlServer(Server): self.host._set_pluginInfoUpdate(pluginId, pinfo) self.host._set_pluginRealName(pluginId, realName) - @make_method('/carla-control/set_audio_count', 'iii') - def set_audio_count_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, ins, outs = args - self.host._set_audioCountInfo(pluginId, {'ins': ins, 'outs': outs}) - - @make_method('/carla-control/set_midi_count', 'iii') - def set_midi_count_callback(self, path, args): + @make_method('/carla-control/param', 'iiiiiissfffffff') + def carla_param(self, path, args): print(path, args) self.fReceivedMsgs = True - pluginId, ins, outs = args - self.host._set_midiCountInfo(pluginId, {'ins': ins, 'outs': outs}) - - @make_method('/carla-control/set_parameter_count', 'iii') # FIXME - def set_parameter_count_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, ins, outs = args # , count - count = ins + outs - self.host._set_parameterCountInfo(pluginId, count, {'ins': ins, 'outs': outs}) - - @make_method('/carla-control/set_program_count', 'ii') - def set_program_count_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, count = args - self.host._set_programCount(pluginId, count) - - @make_method('/carla-control/set_midi_program_count', 'ii') - def set_midi_program_count_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, count = args - self.host._set_midiProgramCount(pluginId, count) - - @make_method('/carla-control/set_parameter_data', 'iiiiss') - def set_parameter_data_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, paramId, type_, hints, name, unit = args + ( + pluginId, paramId, type_, hints, midiChan, midiCC, name, unit, + def_, min_, max_, step, stepSmall, stepLarge, value + ) = args hints &= ~(PARAMETER_USES_SCALEPOINTS | PARAMETER_USES_CUSTOM_TEXT) @@ -272,89 +231,49 @@ class CarlaControlServer(Server): 'hints': hints, 'index': paramId, 'rindex': -1, - 'midiCC': -1, - 'midiChannel': 0 + 'midiCC': midiCC, + 'midiChannel': midiChan, } self.host._set_parameterData(pluginId, paramId, paramData) - @make_method('/carla-control/set_parameter_ranges1', 'iifff') - def set_parameter_ranges1_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - pluginId, paramId, def_, min_, max_ = args - paramRanges = { 'def': def_, 'min': min_, - 'max': max_ + 'max': max_, + 'step': step, + 'stepSmall': stepSmall, + 'stepLarge': stepLarge, } - self.host._set_parameterRangesUpdate(pluginId, paramId, paramRanges) - @make_method('/carla-control/set_parameter_ranges2', 'iifff') - def set_parameter_ranges2_callback(self, path, args): + self.host._set_parameterValue(pluginId, paramId, value) + + @make_method('/carla-control/iparams', 'ifffffff') + def carla_iparams(self, path, args): print(path, args) self.fReceivedMsgs = True - pluginId, paramId, step, stepSmall, stepLarge = args - - paramRanges = { - 'step': step, - 'stepSmall': stepSmall, - 'stepLarge': stepLarge - } + pluginId, active, drywet, volume, balLeft, balRight, pan, ctrlChan = args + self.host._set_internalValue(pluginId, PARAMETER_ACTIVE, active) + self.host._set_internalValue(pluginId, PARAMETER_DRYWET, drywet) + self.host._set_internalValue(pluginId, PARAMETER_VOLUME, volume) + self.host._set_internalValue(pluginId, PARAMETER_BALANCE_LEFT, balLeft) + self.host._set_internalValue(pluginId, PARAMETER_BALANCE_RIGHT, balRight) + self.host._set_internalValue(pluginId, PARAMETER_PANNING, pan) + self.host._set_internalValue(pluginId, PARAMETER_CTRL_CHANNEL, ctrlChan) - self.host._set_parameterRangesUpdate(pluginId, paramId, paramRanges) - - #@make_method('/carla-control/set_parameter_midi_cc', 'iii') - #def set_parameter_midi_cc_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, paramId, cc = args - #self.host._set_parameterMidiCC(pluginId, paramId, cc) - #self.host.ParameterMidiCcChangedCallback.emit(pluginId, paramId, cc) - - #@make_method('/carla-control/set_parameter_midi_channel', 'iii') - #def set_parameter_midi_channel_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, paramId, channel = args - #self.host._set_parameterMidiChannel(pluginId, paramId, channel) - #self.host.ParameterMidiChannelChangedCallback.emit(pluginId, paramId, channel) - - @make_method('/carla-control/set_output_parameter_value', 'iif') - def set_parameter_value_callback(self, path, args): - pluginId, paramId, paramValue = args + @make_method('/carla-control/set_program_count', 'ii') + def set_program_count_callback(self, path, args): + print(path, args) + self.fReceivedMsgs = True + pluginId, count = args + self.host._set_programCount(pluginId, count) - if paramId < 0: - self.host._set_internalValue(pluginId, paramId, paramValue) - else: - self.host._set_parameterValue(pluginId, paramId, paramValue) - - self.host.ParameterValueChangedCallback.emit(pluginId, paramId, paramValue) - - #@make_method('/carla-control/set_default_value', 'iif') - #def set_default_value_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, paramId, paramValue = args - #self.host._set_parameterDefault(pluginId, paramId, paramValue) - #self.host.ParameterDefaultChangedCallback.emit(pluginId, paramId, paramValue) - - #@make_method('/carla-control/set_current_program', 'ii') - #def set_current_program_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, current = args - #self.host._set_currentProgram(pluginId, current) - #self.host.ProgramChangedCallback.emit(pluginId, current) - - #@make_method('/carla-control/set_current_midi_program', 'ii') - #def set_current_midi_program_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, current = args - #self.host._set_currentMidiProgram(pluginId, current) - #self.host.MidiProgramChangedCallback.emit(pluginId, current) + @make_method('/carla-control/set_midi_program_count', 'ii') + def set_midi_program_count_callback(self, path, args): + print(path, args) + self.fReceivedMsgs = True + pluginId, count = args + self.host._set_midiProgramCount(pluginId, count) @make_method('/carla-control/set_program_name', 'iis') def set_program_name_callback(self, path, args): @@ -371,30 +290,27 @@ class CarlaControlServer(Server): self.host._set_midiProgramData(pluginId, midiProgId, {'bank': bank, 'program': program, 'name': name}) #@make_method('/carla-control/note_on', 'iiii') - #def set_note_on_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, channel, note, velocity = args - #self.host.NoteOnCallback.emit(pluginId, channel, note, velocity) - - #@make_method('/carla-control/note_off', 'iii') - #def set_note_off_callback(self, path, args): - #print(path, args) - #self.fReceivedMsgs = True - #pluginId, channel, note = args - #self.host.NoteOffCallback.emit(pluginId, channel, note) - - @make_method('/carla-control/set_peaks', 'iffff') - def set_peaks_callback(self, path, args): + + @make_method('/carla-control/runtime', 'fiihiiif') + def carla_runtime(self, path, args): + self.fReceivedMsgs = True + load, xruns, playing, frame, bar, beat, tick, bpm = args + self.host._set_runtime_info(load, xruns) + self.host._set_transport(bool(playing), frame, bar, beat, tick, bpm) + + @make_method('/carla-control/param_fixme', 'iif') + def carla_param_fixme(self, path, args): + self.fReceivedMsgs = True + pluginId, paramId, paramValue = args + self.host._set_parameterValue(pluginId, paramId, paramValue) + + @make_method('/carla-control/peaks', 'iffff') + def carla_peaks(self, path, args): self.fReceivedMsgs = True pluginId, in1, in2, out1, out2 = args self.host._set_peaks(pluginId, in1, in2, out1, out2) - @make_method('/carla-control/exit', '') - def set_exit_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - self.host.QuitCallback.emit() + #@make_method('/carla-control/note_on', 'iiii') @make_method('/carla-control/exit-error', 's') def set_exit_error_callback(self, path, args): @@ -405,13 +321,6 @@ class CarlaControlServer(Server): self.host.QuitCallback.emit() self.host.ErrorCallback.emit(error) - @make_method('/carla-control/callback', 'iiiiifs') - def set_callback_callback(self, path, args): - print(path, args) - self.fReceivedMsgs = True - action, pluginId, value1, value2, value3, valuef, valueStr = args - engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr) - @make_method(None, None) def fallback(self, path, args): print("ControlServer::fallback(\"%s\") - unknown message, args =" % path, args) diff --git a/source/native-plugins/resources/carla-plugin b/source/native-plugins/resources/carla-plugin index 3c9a0520e..64185ae5d 100755 --- a/source/native-plugins/resources/carla-plugin +++ b/source/native-plugins/resources/carla-plugin @@ -198,24 +198,7 @@ class CarlaMiniW(ExternalUI, HostWindow): valuef = float(self.readlineblock()) valueStr = self.readlineblock().replace("\r", "\n") - if action == ENGINE_CALLBACK_PLUGIN_RENAMED: - self.host._set_pluginName(pluginId, valueStr) - elif action == ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED: - if value1 < 0: - self.host._set_internalValue(pluginId, value1, valuef) - else: - self.host._set_parameterValue(pluginId, value1, valuef) - elif action == ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED: - self.host._set_parameterDefault(pluginId, value1, valuef) - elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED: - self.host._set_parameterMidiCC(pluginId, value1, value2) - elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: - self.host._set_parameterMidiChannel(pluginId, value1, value2) - elif action == ENGINE_CALLBACK_PROGRAM_CHANGED: - self.host._set_currentProgram(pluginId, value1) - elif action == ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED: - self.host._set_currentMidiProgram(pluginId, value1) - + self.host._setViaCallback(action, pluginId, value1, value2, value3, valuef, valueStr) engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr) elif msg.startswith("ENGINE_OPTION_"):