Browse Source

Allow the plugin to receive OSC messages, remove some from engine

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 Carla
tags/1.9.6
falkTX 10 years ago
parent
commit
b602ad6db4
5 changed files with 255 additions and 314 deletions
  1. +5
    -5
      source/backend/CarlaPlugin.hpp
  2. +17
    -223
      source/backend/engine/CarlaEngineOsc.cpp
  3. +14
    -25
      source/backend/engine/CarlaEngineOsc.hpp
  4. +2
    -3
      source/backend/plugin/CarlaPlugin.cpp
  5. +217
    -58
      source/backend/plugin/CarlaPluginDSSI.cpp

+ 5
- 5
source/backend/CarlaPlugin.hpp View File

@@ -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
// ------------------------------------------------------------------- // -------------------------------------------------------------------


+ 17
- 223
source/backend/engine/CarlaEngineOsc.cpp View File

@@ -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");


+ 14
- 25
source/backend/engine/CarlaEngineOsc.hpp View File

@@ -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


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 2
- 3
source/backend/plugin/CarlaPlugin.cpp View File

@@ -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
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------


+ 217
- 58
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -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)


Loading…
Cancel
Save