diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 0bc2ed047..c729ba9a4 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -23,7 +23,7 @@ // ----------------------------------------------------------------------- // Avoid including extra libs here -typedef void* lo_address; +typedef void* lo_message; typedef struct _NativePluginDescriptor NativePluginDescriptor; struct LADSPA_RDF_Descriptor; @@ -712,15 +712,15 @@ public: /*! * Register this plugin to the engine's OSC client (controller or bridge). + * TODO */ void registerToOscClient() noexcept; /*! - * Update the plugin's internal OSC data according to @a source and @a url. - * This is used for OSC-GUI bridges. - * TODO remove + * Handle an OSC message. + * FIXME */ - virtual void updateOscData(const lo_address& source, const char* const url); + virtual void handleOscMessage(const char* const method, const int argc, const void* const argv, const char* const types, const lo_message msg); #ifndef BUILD_BRIDGE // ------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineOsc.cpp b/source/backend/engine/CarlaEngineOsc.cpp index 7eb1c1a40..398d7b137 100644 --- a/source/backend/engine/CarlaEngineOsc.cpp +++ b/source/backend/engine/CarlaEngineOsc.cpp @@ -209,7 +209,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons } #endif - const size_t nameSize(fName.length()); + 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) @@ -220,7 +220,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons // Get plugin id from path, "/carla/23/method" -> 23 uint pluginId = 0; - size_t offset; + std::size_t offset; if (std::isdigit(path[nameSize+2])) { @@ -286,26 +286,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons return 0; } - // Common OSC methods (all bridges) - if (std::strcmp(method, "update") == 0) - { - const lo_address source(lo_message_get_source(msg)); - return handleMsgUpdate(plugin, argc, argv, types, source); - } - if (std::strcmp(method, "exiting") == 0) - return handleMsgExiting(plugin); - #ifndef BUILD_BRIDGE - // Common OSC methods (DSSI and bridge UIs) - if (std::strcmp(method, "configure") == 0) - return handleMsgConfigure(plugin, argc, argv, types); - if (std::strcmp(method, "control") == 0) - return handleMsgControl(plugin, argc, argv, types); - if (std::strcmp(method, "program") == 0) - return handleMsgProgram(plugin, argc, argv, types); - if (std::strcmp(method, "midi") == 0) - return handleMsgMidi(plugin, argc, argv, types); - // Internal methods if (std::strcmp(method, "set_active") == 0) return handleMsgSetActive(plugin, argc, argv, types); @@ -333,90 +314,10 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons return handleMsgNoteOn(plugin, argc, argv, types); if (std::strcmp(method, "note_off") == 0) return handleMsgNoteOff(plugin, argc, argv, types); - - // Plugin Bridges - if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && std::strlen(method) >= 11 && std::strncmp(method, "bridge_", 7) == 0) - { - const char* const bmethod(method+7); - - if (std::strcmp(bmethod, "pong") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscPong, argc, argv, types); - if (std::strcmp(bmethod, "plugin_info1") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscPluginInfo1, argc, argv, types); - if (std::strcmp(bmethod, "plugin_info2") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscPluginInfo2, argc, argv, types); - if (std::strcmp(bmethod, "audio_count") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscAudioCount, argc, argv, types); - if (std::strcmp(bmethod, "midi_count") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscMidiCount, argc, argv, types); - if (std::strcmp(bmethod, "parameter_count") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterCount, argc, argv, types); - if (std::strcmp(bmethod, "program_count") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscProgramCount, argc, argv, types); - if (std::strcmp(bmethod, "midi_program_count") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscMidiProgramCount, argc, argv, types); - if (std::strcmp(bmethod, "parameter_data1") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterData1, argc, argv, types); - if (std::strcmp(bmethod, "parameter_data2") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterData2, argc, argv, types); - if (std::strcmp(bmethod, "parameter_ranges1") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterRanges1, argc, argv, types); - if (std::strcmp(bmethod, "parameter_ranges2") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterRanges2, argc, argv, types); - if (std::strcmp(bmethod, "parameter_value") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscParameterValue, argc, argv, types); - if (std::strcmp(bmethod, "default_value") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscDefaultValue, argc, argv, types); - if (std::strcmp(bmethod, "current_program") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscCurrentProgram, argc, argv, types); - if (std::strcmp(bmethod, "current_midi_program") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscCurrentMidiProgram, argc, argv, types); - if (std::strcmp(bmethod, "program_name") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscProgramName, argc, argv, types); - if (std::strcmp(bmethod, "midi_program_data") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscMidiProgramData, argc, argv, types); - if (std::strcmp(bmethod, "configure") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscConfigure, argc, argv, types); - if (std::strcmp(bmethod, "set_custom_data") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscSetCustomData, argc, argv, types); - if (std::strcmp(bmethod, "set_chunk_data_file") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscSetChunkDataFile, argc, argv, types); - if (std::strcmp(bmethod, "latency") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscLatency, argc, argv, types); - if (std::strcmp(bmethod, "ready") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscReady, argc, argv, types); - if (std::strcmp(bmethod, "error") == 0) - return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgeOscError, argc, argv, types); - } -#endif - - carla_stderr("CarlaEngineOsc::handleMessage() - unsupported OSC method '%s'", method); - return 1; -} - -// ----------------------------------------------------------------------- - -int CarlaEngineOsc::handleMsgUpdate(CARLA_ENGINE_OSC_HANDLE_ARGS2, const lo_address source) -{ - carla_debug("CarlaEngineOsc::handleMsgUpdate()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s"); - -#ifndef BUILD_BRIDGE - const char* const url = (const char*)&argv[0]->s; - - plugin->updateOscData(source, url); #endif - return 0; -} - -int CarlaEngineOsc::handleMsgExiting(CARLA_ENGINE_OSC_HANDLE_ARGS1) -{ - carla_debug("CarlaEngineOsc::handleMsgExiting()"); - // TODO - check for non-UIs (dssi-vst) and set to -1 instead - fEngine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, plugin->getId(), 0, 0, 0.0f, nullptr); - - plugin->showCustomUI(false); + // Send all other methods to plugins, TODO + plugin->handleOscMessage(method, argc, argv, types, msg); return 0; } @@ -481,114 +382,7 @@ int CarlaEngineOsc::handleMsgUnregister() // ----------------------------------------------------------------------- -int CarlaEngineOsc::handleMsgConfigure(CARLA_ENGINE_OSC_HANDLE_ARGS2) -{ - carla_debug("CarlaEngineOsc::handleMsgConfigure()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ss"); - - const char* const key = (const char*)&argv[0]->s; - const char* const value = (const char*)&argv[1]->s; - - plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, key, value, false); - return 0; -} - -int CarlaEngineOsc::handleMsgControl(CARLA_ENGINE_OSC_HANDLE_ARGS2) -{ - carla_debug("CarlaEngineOsc::handleMsgControl()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); - - const int32_t rindex = argv[0]->i; - const float value = argv[1]->f; - - plugin->setParameterValueByRealIndex(rindex, value, false, true, true); - return 0; -} - -int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) -{ - carla_debug("CarlaEngineOsc::handleMsgProgram()"); - - if (argc == 2) - { - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); - - const int32_t bank = argv[0]->i; - const int32_t program = argv[1]->i; - - CARLA_SAFE_ASSERT_RETURN(bank >= 0, 0); - CARLA_SAFE_ASSERT_RETURN(program >= 0, 0); - - plugin->setMidiProgramById(static_cast(bank), static_cast(program), false, true, true); - return 0; - } - else - { - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); - - const int32_t program = argv[0]->i; - - CARLA_SAFE_ASSERT_RETURN(program >= 0, 0); - CARLA_SAFE_ASSERT_RETURN(program < static_cast(plugin->getProgramCount()), 0); - - plugin->setProgram(program, false, true, true); - return 0; - } -} - -int CarlaEngineOsc::handleMsgMidi(CARLA_ENGINE_OSC_HANDLE_ARGS2) -{ - carla_debug("CarlaEngineOsc::handleMsgMidi()"); - CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "m"); - -#ifdef BUILD_BRIDGE - CARLA_ASSERT(false); // this should never happen - return 0; - - // unused - (void)plugin; - (void)argv; -#else - if (plugin->getMidiInCount() == 0) - { - carla_stderr("CarlaEngineOsc::handleMsgMidi() - received midi when plugin has no midi inputs"); - return 0; - } - - const uint8_t* const data = argv[0]->m; - uint8_t status = data[1]; - uint8_t channel = status & 0x0F; - - // Fix bad note-off - if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0) - status = MIDI_STATUS_NOTE_OFF; - - if (MIDI_IS_STATUS_NOTE_OFF(status)) - { - const uint8_t note = data[2]; - - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 0); - - plugin->sendMidiSingleNote(channel, note, 0, false, true, true); - } - else if (MIDI_IS_STATUS_NOTE_ON(status)) - { - const uint8_t note = data[2]; - const uint8_t velo = data[3]; - - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 0); - CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE, 0); - - plugin->sendMidiSingleNote(channel, note, velo, false, true, true); - } - - return 0; -#endif -} - -// ----------------------------------------------------------------------- - -int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetActive()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); @@ -599,7 +393,7 @@ int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetDryWet()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); @@ -610,7 +404,7 @@ int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetVolume()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); @@ -621,7 +415,7 @@ int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); @@ -632,7 +426,7 @@ int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); @@ -643,7 +437,7 @@ int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetPanning()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); @@ -654,7 +448,7 @@ int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); @@ -668,7 +462,7 @@ int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); @@ -683,7 +477,7 @@ int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); @@ -698,7 +492,7 @@ int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARG return 0; } -int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetProgram()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); @@ -711,7 +505,7 @@ int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); @@ -724,7 +518,7 @@ int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgNoteOn()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii"); @@ -741,7 +535,7 @@ int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2) return 0; } -int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS2) +int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS) { carla_debug("CarlaEngineOsc::handleMsgNoteOff()"); CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); diff --git a/source/backend/engine/CarlaEngineOsc.hpp b/source/backend/engine/CarlaEngineOsc.hpp index 8cfd181e3..5d398396f 100644 --- a/source/backend/engine/CarlaEngineOsc.hpp +++ b/source/backend/engine/CarlaEngineOsc.hpp @@ -22,8 +22,7 @@ #include "CarlaOscUtils.hpp" #include "CarlaString.hpp" -#define CARLA_ENGINE_OSC_HANDLE_ARGS1 CarlaPlugin* const plugin -#define CARLA_ENGINE_OSC_HANDLE_ARGS2 CarlaPlugin* const plugin, const int argc, const lo_arg* const* const argv, const char* const types +#define CARLA_ENGINE_OSC_HANDLE_ARGS CarlaPlugin* const plugin, const int argc, const lo_arg* const* const argv, const char* const types #define CARLA_ENGINE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ /* check argument count */ \ @@ -108,34 +107,24 @@ 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); - // Common OSC methods (all bridges) - int handleMsgUpdate(CARLA_ENGINE_OSC_HANDLE_ARGS2, const lo_address source); - int handleMsgExiting(CARLA_ENGINE_OSC_HANDLE_ARGS1); - #ifndef BUILD_BRIDGE int handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types, const lo_address source); int handleMsgUnregister(); - // Common OSC methods (DSSI and bridge UIs) - int handleMsgConfigure(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgControl(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgMidi(CARLA_ENGINE_OSC_HANDLE_ARGS2); - // Internal methods - int handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2); - int handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS2); + int handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS); + int handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS); #endif // ----------------------------------------------------------------------- diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index ddc016a49..f758ed346 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -1576,10 +1576,9 @@ void CarlaPlugin::registerToOscClient() noexcept #endif } -void CarlaPlugin::updateOscData(const lo_address&, const char* const) +void CarlaPlugin::handleOscMessage(const char* const, const int, const void* const, const char* const, const lo_message) { - // should not happen - CARLA_SAFE_ASSERT(false); + // do nothing } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/CarlaPluginDSSI.cpp b/source/backend/plugin/CarlaPluginDSSI.cpp index 1f089bb23..8f7edd49d 100644 --- a/source/backend/plugin/CarlaPluginDSSI.cpp +++ b/source/backend/plugin/CarlaPluginDSSI.cpp @@ -30,9 +30,30 @@ using juce::ScopedPointer; using juce::String; using juce::StringArray; -CARLA_BACKEND_START_NAMESPACE +#define CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ + /* check argument count */ \ + if (argc != argcToCompare) \ + { \ + carla_stderr("CarlaPluginDSSI::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \ + return; \ + } \ + if (argc > 0) \ + { \ + /* check for nullness */ \ + if (types == nullptr || typesToCompare == nullptr) \ + { \ + carla_stderr("CarlaPluginDSSI::%s() - argument types are null", __FUNCTION__); \ + return; \ + } \ + /* check argument types */ \ + if (std::strcmp(types, typesToCompare) != 0) \ + { \ + carla_stderr("CarlaPluginDSSI::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \ + return; \ + } \ + } -class CarlaPluginDSSI; +CARLA_BACKEND_START_NAMESPACE // ------------------------------------------------------------------- // Fallback data @@ -2091,93 +2112,136 @@ public: } // ------------------------------------------------------------------- - // Post-poned UI Stuff + // OSC stuff - void uiParameterChange(const uint32_t index, const float value) noexcept override + void handleOscMessage(const char* const method, const int argc, const void* const argvx, const char* const types, const lo_message msg) override { - CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,); + const lo_address source(lo_message_get_source(msg)); + CARLA_SAFE_ASSERT_RETURN(source != nullptr,); - if (fOscData.target == nullptr) - return; + // protocol for DSSI UIs *must* be UDP + CARLA_SAFE_ASSERT_RETURN(lo_address_get_protocol(source) == LO_UDP,); - osc_send_control(fOscData, pData->param.data[index].rindex, value); + if (fOscData.source == nullptr) + { + // if no UI is registered yet only "update" message is valid + CARLA_SAFE_ASSERT_RETURN(std::strcmp(method, "update") == 0,) + } + else + { + // make sure message source is the DSSI UI + const char* const msghost = lo_address_get_hostname(source); + const char* const msgport = lo_address_get_port(source); + + const char* const ourhost = lo_address_get_hostname(fOscData.source); + const char* const ourport = lo_address_get_port(fOscData.source); + + CARLA_SAFE_ASSERT_RETURN(std::strcmp(msghost, ourhost) == 0,); + CARLA_SAFE_ASSERT_RETURN(std::strcmp(msgport, ourport) == 0,); + } + + const lo_arg* const* const argv(static_cast(argvx)); + + if (std::strcmp(method, "configure") == 0) + return handleOscMessageConfigure(argc, argv, types); + if (std::strcmp(method, "control") == 0) + return handleOscMessageControl(argc, argv, types); + if (std::strcmp(method, "program") == 0) + return handleOscMessageProgram(argc, argv, types); + if (std::strcmp(method, "midi") == 0) + return handleOscMessageMIDI(argc, argv, types); + if (std::strcmp(method, "update") == 0) + return handleOscMessageUpdate(argc, argv, types, lo_message_get_source(msg)); + if (std::strcmp(method, "exiting") == 0) + return handleOscMessageExiting(); + + carla_stdout("CarlaPluginDSSI::handleOscMessage() - unknown method '%s'", method); } - void uiMidiProgramChange(const uint32_t index) noexcept override + void handleOscMessageConfigure(const int argc, const lo_arg* const* const argv, const char* const types) { - CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,); + carla_debug("CarlaPluginDSSI::handleMsgConfigure()"); + CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(2, "ss"); - if (fOscData.target == nullptr) - return; + const char* const key = (const char*)&argv[0]->s; + const char* const value = (const char*)&argv[1]->s; - osc_send_program(fOscData, pData->midiprog.data[index].bank, pData->midiprog.data[index].program); + setCustomData(CUSTOM_DATA_TYPE_STRING, key, value, false); } - void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override + void handleOscMessageControl(const int argc, const lo_arg* const* const argv, const char* const types) { - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,); + carla_debug("CarlaPluginDSSI::handleMsgControl()"); + CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(2, "if"); - if (fOscData.target == nullptr) - return; + const int32_t rindex = argv[0]->i; + const float value = argv[1]->f; -#if 0 - uint8_t midiData[4]; - midiData[0] = 0; - midiData[1] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT)); - midiData[2] = note; - midiData[3] = velo; + setParameterValueByRealIndex(rindex, value, false, true, true); + } - osc_send_midi(fOscData, midiData); -#endif + void handleOscMessageProgram(const int argc, const lo_arg* const* const argv, const char* const types) + { + carla_debug("CarlaPluginDSSI::handleMsgProgram()"); + CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(2, "ii"); + + const int32_t bank = argv[0]->i; + const int32_t program = argv[1]->i; + + CARLA_SAFE_ASSERT_RETURN(bank >= 0,); + CARLA_SAFE_ASSERT_RETURN(program >= 0,); + + setMidiProgramById(static_cast(bank), static_cast(program), false, true, true); } - void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override + void handleOscMessageMIDI(const int argc, const lo_arg* const* const argv, const char* const types) { - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + carla_debug("CarlaPluginDSSI::handleMsgMidi()"); + CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(1, "m"); - if (fOscData.target == nullptr) + if (getMidiInCount() == 0) + { + carla_stderr("CarlaPluginDSSI::handleMsgMidi() - received midi when plugin has no midi inputs"); return; + } -#if 0 - uint8_t midiData[4]; - midiData[0] = 0; - midiData[1] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT)); - midiData[2] = note; - midiData[3] = 0; +#ifndef BUILD_BRIDGE + const uint8_t* const data = argv[0]->m; + uint8_t status = data[1]; + uint8_t channel = status & 0x0F; - osc_send_midi(fOscData, midiData); -#endif - } + // Fix bad note-off + if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0) + status = MIDI_STATUS_NOTE_OFF; - // ------------------------------------------------------------------- + if (MIDI_IS_STATUS_NOTE_OFF(status)) + { + const uint8_t note = data[2]; - void* getNativeHandle() const noexcept override - { - return fHandle; - } + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - const void* getNativeDescriptor() const noexcept override - { - return fDssiDescriptor; - } + sendMidiSingleNote(channel, note, 0, false, true, true); + } + else if (MIDI_IS_STATUS_NOTE_ON(status)) + { + const uint8_t note = data[2]; + const uint8_t velo = data[3]; - uintptr_t getUiBridgeProcessId() const noexcept override - { - return fThreadUI.getProcessPID(); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); + + sendMidiSingleNote(channel, note, velo, false, true, true); + } +#endif } - const void* getExtraStuff() const noexcept override + void handleOscMessageUpdate(const int argc, const lo_arg* const* const argv, const char* const types, const lo_address source) { - return fUiFilename; - } + carla_debug("CarlaPluginDSSI::handleMsgUpdate()"); + CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(1, "s"); - // ------------------------------------------------------------------- + const char* const url = (const char*)&argv[0]->s; - void updateOscData(const lo_address& source, const char* const url) override - { // FIXME - remove debug prints later carla_stdout("CarlaPluginDSSI::updateOscData(%p, \"%s\")", source, url); @@ -2237,6 +2301,101 @@ public: carla_stdout("CarlaPluginDSSI::updateOscData() - done"); } + void handleOscMessageExiting() + { + carla_debug("CarlaPluginDSSI::handleMsgExiting()"); + + // hide UI + showCustomUI(false); + + // tell frontend + pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr); + } + + // ------------------------------------------------------------------- + // Post-poned UI Stuff + + void uiParameterChange(const uint32_t index, const float value) noexcept override + { + CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,); + + if (fOscData.target == nullptr) + return; + + osc_send_control(fOscData, pData->param.data[index].rindex, value); + } + + void uiMidiProgramChange(const uint32_t index) noexcept override + { + CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,); + + if (fOscData.target == nullptr) + return; + + osc_send_program(fOscData, pData->midiprog.data[index].bank, pData->midiprog.data[index].program); + } + + void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override + { + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,); + + if (fOscData.target == nullptr) + return; + +#if 0 + uint8_t midiData[4]; + midiData[0] = 0; + midiData[1] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT)); + midiData[2] = note; + midiData[3] = velo; + + osc_send_midi(fOscData, midiData); +#endif + } + + void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override + { + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + + if (fOscData.target == nullptr) + return; + +#if 0 + uint8_t midiData[4]; + midiData[0] = 0; + midiData[1] = uint8_t(MIDI_STATUS_NOTE_ON | (channel & MIDI_CHANNEL_BIT)); + midiData[2] = note; + midiData[3] = 0; + + osc_send_midi(fOscData, midiData); +#endif + } + + // ------------------------------------------------------------------- + + void* getNativeHandle() const noexcept override + { + return fHandle; + } + + const void* getNativeDescriptor() const noexcept override + { + return fDssiDescriptor; + } + + uintptr_t getUiBridgeProcessId() const noexcept override + { + return fThreadUI.getProcessPID(); + } + + const void* getExtraStuff() const noexcept override + { + return fUiFilename; + } + // ------------------------------------------------------------------- bool init(const char* const filename, const char* const name, const char* const label)