With this we can check if the osc messages come from the proper source (say a DSSI UI), so there won't be conflicts if external tools send random osc messages to Carlatags/1.9.6
| @@ -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 | |||
| // ------------------------------------------------------------------- | |||
| @@ -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<uint32_t>(bank), static_cast<uint32_t>(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<int32_t>(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"); | |||
| @@ -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 | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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 | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -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<const lo_arg* const* const>(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<uint32_t>(bank), static_cast<uint32_t>(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) | |||