Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-alpha2
| @@ -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) | |||
| }; | |||
| @@ -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. | |||
| @@ -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 | |||
| // ------------------------------------------------------------------- | |||
| @@ -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); | |||
| @@ -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; i<count; ++i) | |||
| pData->osc.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; i<count; ++i) | |||
| pData->osc.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]); | |||
| @@ -1377,7 +1377,7 @@ public: | |||
| for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), numChanu); i<count; ++i) | |||
| outPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples); | |||
| kEngine->setPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); | |||
| kEngine->setPluginPeaksRT(fPlugin->getId(), inPeaks, outPeaks); | |||
| } | |||
| else | |||
| { | |||
| @@ -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; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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; | |||
| @@ -2544,7 +2544,7 @@ private: | |||
| } | |||
| } | |||
| setPluginPeaks(plugin->getId(), inPeaks, outPeaks); | |||
| setPluginPeaksRT(plugin->getId(), inPeaks, outPeaks); | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| @@ -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 <cctype> | |||
| 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<int>(fEngine->getBufferSize()), | |||
| static_cast<float>(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<uint32_t>(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<uint32_t>(index), static_cast<int16_t>(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<uint32_t>(index), static_cast<uint8_t>(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<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(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<uint8_t>(channel), static_cast<uint8_t>(note), 0, true, false, true); | |||
| return 0; | |||
| fControlDataTCP.clear(); | |||
| fControlDataUDP.clear(); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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); | |||
| @@ -0,0 +1,446 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 <cctype> | |||
| 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<int>(fEngine->getBufferSize()), | |||
| static_cast<float>(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<uint32_t>(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<uint32_t>(index), static_cast<int16_t>(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<uint32_t>(index), static_cast<uint8_t>(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<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(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<uint8_t>(channel), static_cast<uint8_t>(note), 0, true, false, true); | |||
| return 0; | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #endif // HAVE_LIBLO | |||
| @@ -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<double>(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<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(type), static_cast<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(plugin->getId()), | |||
| static_cast<int32_t>(plugin->getType()), | |||
| static_cast<int32_t>(plugin->getCategory()), | |||
| static_cast<int32_t>(plugin->getHints()), | |||
| static_cast<int64_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(type), static_cast<int32_t>(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<int32_t>(plugin->getId()), | |||
| static_cast<int32_t>(plugin->getAudioInCount()), | |||
| static_cast<int32_t>(plugin->getAudioOutCount()), | |||
| static_cast<int32_t>(plugin->getMidiInCount()), | |||
| static_cast<int32_t>(plugin->getMidiOutCount()), | |||
| static_cast<int32_t>(paramIns), | |||
| static_cast<int32_t>(paramOuts), | |||
| static_cast<int32_t>(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<int32_t>(pluginId), | |||
| static_cast<int32_t>(index), | |||
| static_cast<double>(def), | |||
| static_cast<double>(min), | |||
| static_cast<double>(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<int32_t>(plugin->getId()), static_cast<int32_t>(parameterId), | |||
| static_cast<int32_t>(paramData.type), static_cast<int32_t>(paramData.hints), | |||
| static_cast<int32_t>(paramData.midiChannel), static_cast<int32_t>(paramData.midiCC), | |||
| bufName, bufUnit, | |||
| static_cast<double>(paramRanges.def), | |||
| static_cast<double>(paramRanges.min), | |||
| static_cast<double>(paramRanges.max), | |||
| static_cast<double>(paramRanges.step), | |||
| static_cast<double>(paramRanges.stepSmall), | |||
| static_cast<double>(paramRanges.stepLarge), | |||
| static_cast<double>(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<int32_t>(pluginId), | |||
| static_cast<int32_t>(index), | |||
| static_cast<double>(step), | |||
| static_cast<double>(stepSmall), | |||
| static_cast<double>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(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<InternalParameterIndex>(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<int32_t>(pluginId), | |||
| index, | |||
| static_cast<double>(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<int32_t>(pluginId), | |||
| static_cast<int32_t>(index), | |||
| static_cast<double>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), name); | |||
| try_lo_send(fControlDataTCP.target, targetPath, "iis", static_cast<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name); | |||
| try_lo_send(fControlDataTCP.target, targetPath, "iiiis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(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<double>(fEngine->getDSPLoad()), | |||
| static_cast<int32_t>(fEngine->getTotalXruns()), | |||
| timeInfo.playing ? 1 : 0, | |||
| static_cast<int64_t>(timeInfo.frame), | |||
| static_cast<int32_t>(timeInfo.bbt.bar), | |||
| static_cast<int32_t>(timeInfo.bbt.beat), | |||
| static_cast<int32_t>(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<int32_t>(pluginId), | |||
| static_cast<double>(epData.peaks[0]), | |||
| static_cast<double>(epData.peaks[1]), | |||
| static_cast<double>(epData.peaks[2]), | |||
| static_cast<double>(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<int32_t>(pluginId), | |||
| index, | |||
| static_cast<double>(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<int32_t>(pluginId), | |||
| static_cast<double>(peaks[0]), | |||
| static_cast<double>(peaks[1]), | |||
| static_cast<double>(peaks[2]), | |||
| static_cast<double>(peaks[3])); | |||
| } | |||
| #endif | |||
| #endif // BUILD_BRIDGE | |||
| // ----------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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<int32_t>(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 | |||
| } | |||
| @@ -28,6 +28,7 @@ OBJS = \ | |||
| ifeq ($(HAVE_LIBLO),true) | |||
| OBJS += \ | |||
| $(OBJDIR)/CarlaEngineOsc.cpp.o \ | |||
| $(OBJDIR)/CarlaEngineOscHandlers.cpp.o \ | |||
| $(OBJDIR)/CarlaEngineOscSend.cpp.o | |||
| endif | |||
| @@ -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<uint32_t>(pData->param.count, 98U)) | |||
| { | |||
| char bufName[STR_MAX+1], bufUnit[STR_MAX+1]; | |||
| for (uint32_t i=0; i<count; ++i) | |||
| { | |||
| const ParameterData& paramData(pData->param.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<int32_t>(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<uint32_t>(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; | |||
| @@ -1316,7 +1316,7 @@ public: | |||
| if (event.channel == pData->ctrlChannel && ! allNotesOffSent) | |||
| { | |||
| allNotesOffSent = true; | |||
| sendMidiAllNotesOffToCallback(); | |||
| postponeRtAllNotesOff(); | |||
| } | |||
| #endif | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -1042,7 +1042,7 @@ public: | |||
| if (event.channel == pData->ctrlChannel && ! allNotesOffSent) | |||
| { | |||
| allNotesOffSent = true; | |||
| sendMidiAllNotesOffToCallback(); | |||
| postponeRtAllNotesOff(); | |||
| } | |||
| #endif | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -497,7 +497,7 @@ public: | |||
| if (event.channel == pData->ctrlChannel && ! allNotesOffSent) | |||
| { | |||
| allNotesOffSent = true; | |||
| sendMidiAllNotesOffToCallback(); | |||
| postponeRtAllNotesOff(); | |||
| } | |||
| #endif | |||
| @@ -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 | |||
| @@ -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) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| @@ -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) | |||
| @@ -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_"): | |||