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 | // Avoid including extra libs here | ||||
typedef void* lo_address; | |||||
typedef void* lo_message; | |||||
typedef struct _NativePluginDescriptor NativePluginDescriptor; | typedef struct _NativePluginDescriptor NativePluginDescriptor; | ||||
struct LADSPA_RDF_Descriptor; | struct LADSPA_RDF_Descriptor; | ||||
@@ -712,15 +712,15 @@ public: | |||||
/*! | /*! | ||||
* Register this plugin to the engine's OSC client (controller or bridge). | * Register this plugin to the engine's OSC client (controller or bridge). | ||||
* TODO | |||||
*/ | */ | ||||
void registerToOscClient() noexcept; | 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 | #ifndef BUILD_BRIDGE | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -209,7 +209,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons | |||||
} | } | ||||
#endif | #endif | ||||
const size_t nameSize(fName.length()); | |||||
const std::size_t nameSize(fName.length()); | |||||
// Check if message is for this client | // Check if message is for this client | ||||
if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0) | 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 | // Get plugin id from path, "/carla/23/method" -> 23 | ||||
uint pluginId = 0; | uint pluginId = 0; | ||||
size_t offset; | |||||
std::size_t offset; | |||||
if (std::isdigit(path[nameSize+2])) | if (std::isdigit(path[nameSize+2])) | ||||
{ | { | ||||
@@ -286,26 +286,7 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons | |||||
return 0; | 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 | #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 | // Internal methods | ||||
if (std::strcmp(method, "set_active") == 0) | if (std::strcmp(method, "set_active") == 0) | ||||
return handleMsgSetActive(plugin, argc, argv, types); | 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); | return handleMsgNoteOn(plugin, argc, argv, types); | ||||
if (std::strcmp(method, "note_off") == 0) | if (std::strcmp(method, "note_off") == 0) | ||||
return handleMsgNoteOff(plugin, argc, argv, types); | 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 | #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; | 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_debug("CarlaEngineOsc::handleMsgSetActive()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | ||||
@@ -599,7 +393,7 @@ int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetDryWet()"); | carla_debug("CarlaEngineOsc::handleMsgSetDryWet()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | ||||
@@ -610,7 +404,7 @@ int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetVolume()"); | carla_debug("CarlaEngineOsc::handleMsgSetVolume()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | ||||
@@ -621,7 +415,7 @@ int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()"); | carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | ||||
@@ -632,7 +426,7 @@ int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()"); | carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | ||||
@@ -643,7 +437,7 @@ int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetPanning()"); | carla_debug("CarlaEngineOsc::handleMsgSetPanning()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f"); | ||||
@@ -654,7 +448,7 @@ int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()"); | carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if"); | ||||
@@ -668,7 +462,7 @@ int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()"); | carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | ||||
@@ -683,7 +477,7 @@ int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()"); | carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | ||||
@@ -698,7 +492,7 @@ int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARG | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetProgram()"); | carla_debug("CarlaEngineOsc::handleMsgSetProgram()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | ||||
@@ -711,7 +505,7 @@ int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()"); | carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i"); | ||||
@@ -724,7 +518,7 @@ int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgNoteOn()"); | carla_debug("CarlaEngineOsc::handleMsgNoteOn()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii"); | ||||
@@ -741,7 +535,7 @@ int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
return 0; | return 0; | ||||
} | } | ||||
int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||||
int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS) | |||||
{ | { | ||||
carla_debug("CarlaEngineOsc::handleMsgNoteOff()"); | carla_debug("CarlaEngineOsc::handleMsgNoteOff()"); | ||||
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii"); | ||||
@@ -22,8 +22,7 @@ | |||||
#include "CarlaOscUtils.hpp" | #include "CarlaOscUtils.hpp" | ||||
#include "CarlaString.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) \ | #define CARLA_ENGINE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ | ||||
/* check argument count */ \ | /* 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); | 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 | #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 handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types, const lo_address source); | ||||
int handleMsgUnregister(); | 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 | // 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 | #endif | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -1576,10 +1576,9 @@ void CarlaPlugin::registerToOscClient() noexcept | |||||
#endif | #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::String; | ||||
using juce::StringArray; | 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 | // 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; | 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 | // FIXME - remove debug prints later | ||||
carla_stdout("CarlaPluginDSSI::updateOscData(%p, \"%s\")", source, url); | carla_stdout("CarlaPluginDSSI::updateOscData(%p, \"%s\")", source, url); | ||||
@@ -2237,6 +2301,101 @@ public: | |||||
carla_stdout("CarlaPluginDSSI::updateOscData() - done"); | 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) | bool init(const char* const filename, const char* const name, const char* const label) | ||||