Browse Source

Rework some core OSC remote control code, behaving like the plugin

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.1-alpha2
falkTX 6 years ago
parent
commit
d005d44bd1
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
28 changed files with 885 additions and 1256 deletions
  1. +5
    -46
      source/backend/CarlaEngine.hpp
  2. +1
    -1
      source/backend/CarlaHost.h
  3. +8
    -11
      source/backend/CarlaPlugin.hpp
  4. +1
    -1
      source/backend/CarlaStandalone.cpp
  5. +63
    -13
      source/backend/engine/CarlaEngine.cpp
  6. +1
    -1
      source/backend/engine/CarlaEngineGraph.cpp
  7. +0
    -8
      source/backend/engine/CarlaEngineInternal.cpp
  8. +1
    -2
      source/backend/engine/CarlaEngineInternal.hpp
  9. +1
    -1
      source/backend/engine/CarlaEngineJack.cpp
  10. +5
    -414
      source/backend/engine/CarlaEngineOsc.cpp
  11. +26
    -8
      source/backend/engine/CarlaEngineOsc.hpp
  12. +446
    -0
      source/backend/engine/CarlaEngineOscHandlers.cpp
  13. +207
    -387
      source/backend/engine/CarlaEngineOscSend.cpp
  14. +11
    -5
      source/backend/engine/CarlaEngineThread.cpp
  15. +1
    -0
      source/backend/engine/Makefile
  16. +2
    -97
      source/backend/plugin/CarlaPlugin.cpp
  17. +1
    -1
      source/backend/plugin/CarlaPluginBridge.cpp
  18. +1
    -12
      source/backend/plugin/CarlaPluginDSSI.cpp
  19. +1
    -12
      source/backend/plugin/CarlaPluginFluidSynth.cpp
  20. +1
    -1
      source/backend/plugin/CarlaPluginJack.cpp
  21. +1
    -12
      source/backend/plugin/CarlaPluginJuce.cpp
  22. +1
    -12
      source/backend/plugin/CarlaPluginLV2.cpp
  23. +1
    -12
      source/backend/plugin/CarlaPluginNative.cpp
  24. +1
    -1
      source/backend/plugin/CarlaPluginSFZero.cpp
  25. +1
    -12
      source/backend/plugin/CarlaPluginVST2.cpp
  26. +19
    -0
      source/frontend/carla_backend.py
  27. +77
    -168
      source/frontend/carla_control.py
  28. +1
    -18
      source/native-plugins/resources/carla-plugin

+ 5
- 46
source/backend/CarlaEngine.hpp View File

@@ -20,10 +20,6 @@

#include "CarlaBackend.h"

#ifdef BUILD_BRIDGE
struct CarlaOscData;
#endif

namespace water {
class MemoryOutputStream;
class XmlDocument;
@@ -979,8 +975,9 @@ public:

/*!
* Get a plugin's peak values.
* @note not thread-safe if pluginId == MAIN_CARLA_PLUGIN_ID
*/
float* getPeaks(const uint pluginId) const noexcept;
const float* getPeaks(const uint pluginId) const noexcept;

/*!
* Get a plugin's input peak value.
@@ -1129,11 +1126,6 @@ public:
*/
bool isOscControlRegistered() const noexcept;

/*!
* Idle OSC.
*/
void idleOsc() const noexcept;

/*!
* Get OSC TCP server path.
*/
@@ -1166,7 +1158,7 @@ public:

protected:
/*!
* Internal data, for CarlaEngine subclasses only.
* Internal data, for CarlaEngine subclasses and friends.
*/
struct ProtectedData;
ProtectedData* const pData;
@@ -1174,6 +1166,7 @@ protected:
/*!
* Some internal classes read directly from pData or call protected functions.
*/
friend class CarlaEngineThread;
friend class CarlaPluginInstance;
friend class EngineInternalGraph;
friend class PendingRtEventsRunner;
@@ -1206,7 +1199,7 @@ protected:
* Set a plugin (stereo) peak values.
* @note RT call
*/
void setPluginPeaks(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept;
void setPluginPeaksRT(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept;

/*!
* Common save project function for main engine and plugin.
@@ -1282,40 +1275,6 @@ public:
# endif
#endif

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------
// OSC Controller stuff

void oscSend_control_callback(const EngineCallbackOpcode action, const uint pluginId,
const int value1, const int value2, const int value3,
const float valuef, const char* const valueStr) const noexcept;
void oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept;
// void oscSend_control_add_plugin_end(const uint pluginId) const noexcept;
// void oscSend_control_remove_plugin(const uint pluginId) const noexcept;
void oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const int64_t uniqueId) const noexcept;
void oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept;
void oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept;
void oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept;
void oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept;
void oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept;
void oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept;
void oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept;
void oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept;
void oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept;
// void oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept;
// void oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept;
void oscSend_control_set_output_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept;
// void oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept;
// void oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept;
// void oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept;
void oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept;
void oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept;
// void oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept;
// void oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept;
void oscSend_control_set_peaks(const uint pluginId) const noexcept;
// void oscSend_control_exit() const noexcept;
#endif

CARLA_DECLARE_NON_COPY_CLASS(CarlaEngine)
};



+ 1
- 1
source/backend/CarlaHost.h View File

@@ -774,7 +774,7 @@ CARLA_EXPORT float carla_get_internal_parameter_value(uint pluginId, int32_t par
* Get a plugin's peak values.
* @param pluginId Plugin
*/
CARLA_EXPORT float* carla_get_peak_values(uint pluginId);
CARLA_EXPORT const float* carla_get_peak_values(uint pluginId);

/*!
* Get a plugin's input peak value.


+ 8
- 11
source/backend/CarlaPlugin.hpp View File

@@ -725,19 +725,15 @@ public:
// -------------------------------------------------------------------
// OSC stuff

#ifndef BUILD_BRIDGE
/*!
* Register this plugin to the engine's OSC client (controller or bridge).
* TODO
*/
void registerToOscClient() noexcept;
#endif

/*!
* Handle an OSC message.
* FIXME
*/
virtual void handleOscMessage(const char* const method, const int argc, const void* const argv, const char* const types, const lo_message msg);
virtual void handleOscMessage(const char* const method,
const int argc,
const void* const argv,
const char* const types,
const lo_message msg);

// -------------------------------------------------------------------
// MIDI events
@@ -747,7 +743,8 @@ public:
* A note with 0 velocity means note-off.
* @note Non-RT call
*/
void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback);
void sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo,
const bool sendGui, const bool sendOsc, const bool sendCallback);

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
/*!
@@ -755,7 +752,7 @@ public:
* This doesn't send the actual MIDI All-Notes-Off event, but 128 note-offs instead (IFF ctrlChannel is valid).
* @note RT call
*/
void sendMidiAllNotesOffToCallback();
void postponeRtAllNotesOff();
#endif

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


+ 1
- 1
source/backend/CarlaStandalone.cpp View File

@@ -1729,7 +1729,7 @@ float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId)

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

float* carla_get_peak_values(uint pluginId)
const float* carla_get_peak_values(uint pluginId)
{
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);



+ 63
- 13
source/backend/engine/CarlaEngine.cpp View File

@@ -1235,9 +1235,9 @@ EngineTimeInfo CarlaEngine::getTimeInfo() const noexcept
// -----------------------------------------------------------------------
// Information (peaks)

float* CarlaEngine::getPeaks(const uint pluginId) const noexcept
const float* CarlaEngine::getPeaks(const uint pluginId) const noexcept
{
carla_zeroFloats(pData->peaks, 4);
static const float kFallback[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

if (pluginId == MAIN_CARLA_PLUGIN_ID)
{
@@ -1249,11 +1249,15 @@ float* CarlaEngine::getPeaks(const uint pluginId) const noexcept
pData->peaks[2] = pData->plugins[count-1].peaks[2];
pData->peaks[3] = pData->plugins[count-1].peaks[3];
}
else
{
carla_zeroFloats(pData->peaks, 4);
}

return pData->peaks;
}

CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, pData->peaks);
CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, kFallback);

return pData->plugins[pluginId].peaks;
}
@@ -1332,13 +1336,66 @@ void CarlaEngine::callback(const bool sendHost, const bool sendOsc,
{
switch (action)
{
case ENGINE_CALLBACK_RELOAD_INFO:
{
CarlaPlugin* const plugin = pData->plugins[pluginId].plugin;
CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);

pData->osc.sendPluginInfo(plugin);
break;
}

case ENGINE_CALLBACK_RELOAD_PARAMETERS:
{
CarlaPlugin* const plugin = pData->plugins[pluginId].plugin;
CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);

pData->osc.sendPluginPortCount(plugin);

if (const uint32_t count = plugin->getParameterCount())
{
for (uint32_t i=0; i<count; ++i)
pData->osc.sendPluginParameterInfo(plugin, i);
}
break;
}

case ENGINE_CALLBACK_RELOAD_PROGRAMS:
{
CarlaPlugin* const plugin = pData->plugins[pluginId].plugin;
CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);

#if 0
pData->engine->oscSend_control_set_midi_program_count(pData->id, count);

for (uint32_t i=0; i < count; ++i)
pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);

pData->engine->oscSend_control_set_program_count(pData->id, newCount);

for (uint32_t i=0; i < newCount; ++i)
pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
#endif
break;
}

case ENGINE_CALLBACK_PLUGIN_ADDED:
case ENGINE_CALLBACK_RELOAD_ALL:
{
CarlaPlugin* const plugin = pData->plugins[pluginId].plugin;
CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);

plugin->registerToOscClient();
pData->osc.sendPluginInit(pluginId, plugin->getName());
pData->osc.sendPluginInfo(plugin);
pData->osc.sendPluginPortCount(plugin);

if (const uint32_t count = plugin->getParameterCount())
{
for (uint32_t i=0; i<count; ++i)
pData->osc.sendPluginParameterInfo(plugin, i);
}

pData->osc.sendPluginInternalParameterValues(plugin);
break;
}

@@ -1349,7 +1406,7 @@ void CarlaEngine::callback(const bool sendHost, const bool sendOsc,
break;
}

oscSend_control_callback(action, pluginId, value1, value2, value3, valuef, valueStr);
pData->osc.sendCallback(action, pluginId, value1, value2, value3, valuef, valueStr);
}
#endif
}
@@ -1772,13 +1829,6 @@ bool CarlaEngine::isOscControlRegistered() const noexcept
# endif
}

void CarlaEngine::idleOsc() const noexcept
{
# ifdef HAVE_LIBLO
pData->osc.idle();
# endif
}

const char* CarlaEngine::getOscServerPathTCP() const noexcept
{
# ifdef HAVE_LIBLO
@@ -1888,7 +1938,7 @@ void CarlaEngine::offlineModeChanged(const bool isOfflineNow)
}
}

void CarlaEngine::setPluginPeaks(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept
void CarlaEngine::setPluginPeaksRT(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept
{
EnginePluginData& pluginData(pData->plugins[pluginId]);



+ 1
- 1
source/backend/engine/CarlaEngineGraph.cpp View File

@@ -1377,7 +1377,7 @@ public:
for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), numChanu); i<count; ++i)
outPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples);

kEngine->setPluginPeaks(fPlugin->getId(), inPeaks, outPeaks);
kEngine->setPluginPeaksRT(fPlugin->getId(), inPeaks, outPeaks);
}
else
{


+ 0
- 8
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -369,7 +369,6 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept
: thread(engine),
#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
osc(engine),
oscData(nullptr),
#endif
callback(nullptr),
callbackPtr(nullptr),
@@ -426,9 +425,6 @@ CarlaEngine::ProtectedData::~ProtectedData() noexcept
bool CarlaEngine::ProtectedData::init(const char* const clientName)
{
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)");
#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)");
#endif
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)");
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.out == nullptr, "Invalid engine internal data (err #5)");
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name");
@@ -480,10 +476,7 @@ bool CarlaEngine::ProtectedData::init(const char* const clientName)

#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
if (options.oscEnabled)
{
osc.init(clientName, options.oscPortTCP, options.oscPortUDP);
oscData = osc.getControlData();
}
#endif

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
@@ -514,7 +507,6 @@ void CarlaEngine::ProtectedData::close()

#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
osc.close();
oscData = nullptr;
#endif

aboutToClose = false;


+ 1
- 2
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -214,7 +214,6 @@ struct CarlaEngine::ProtectedData {

#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
CarlaEngineOsc osc;
const CarlaOscData* oscData;
#endif

EngineCallbackFunc callback;


+ 1
- 1
source/backend/engine/CarlaEngineJack.cpp View File

@@ -2544,7 +2544,7 @@ private:
}
}

setPluginPeaks(plugin->getId(), inPeaks, outPeaks);
setPluginPeaksRT(plugin->getId(), inPeaks, outPeaks);
}

#ifndef BUILD_BRIDGE


+ 5
- 414
source/backend/engine/CarlaEngineOsc.cpp View File

@@ -15,16 +15,11 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaDefines.h"
#include "CarlaEngineOsc.hpp"

#ifdef HAVE_LIBLO

#include "CarlaEngine.hpp"
#include "CarlaEngineOsc.hpp"
#include "CarlaPlugin.hpp"
#include "CarlaMIDI.h"

#include <cctype>

CARLA_BACKEND_START_NAMESPACE

@@ -32,7 +27,8 @@ CARLA_BACKEND_START_NAMESPACE

CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine) noexcept
: fEngine(engine),
fControlData(),
fControlDataTCP(),
fControlDataUDP(),
fName(),
fServerPathTCP(),
fServerPathUDP(),
@@ -206,413 +202,8 @@ void CarlaEngineOsc::close() noexcept
fServerPathTCP.clear();
fServerPathUDP.clear();

fControlData.clear();
}

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

int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
{
CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', 1);
#ifdef DEBUG
if (std::strstr(path, "/bridge_pong") == nullptr) {
carla_debug("CarlaEngineOsc::handleMessage(%s, \"%s\", %i, %p, \"%s\", %p)", bool2str(isTCP), path, argc, argv, types, msg);
}
#endif

if (isTCP)
{
CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServerTCP != nullptr, 1);
}
else
{
CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServerUDP != nullptr, 1);
}

// Initial path check
if (std::strcmp(path, "/register") == 0)
return handleMsgRegister(isTCP, argc, argv, types);

if (std::strcmp(path, "/unregister") == 0)
return handleMsgUnregister(argc, argv, types);

const std::size_t nameSize(fName.length());

// Check if message is for this client
if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0)
{
carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, fName.buffer());
return 1;
}

// Get plugin id from path, "/carla/23/method" -> 23
uint pluginId = 0;
std::size_t offset;

if (std::isdigit(path[nameSize+2]))
{
if (std::isdigit(path[nameSize+3]))
{
if (std::isdigit(path[nameSize+5]))
{
carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", path+(nameSize+1));
return 1;
}
else if (std::isdigit(path[nameSize+4]))
{
// 3 digits, /xyz/method
offset = 6;
pluginId += uint(path[nameSize+2]-'0')*100;
pluginId += uint(path[nameSize+3]-'0')*10;
pluginId += uint(path[nameSize+4]-'0');
}
else
{
// 2 digits, /xy/method
offset = 5;
pluginId += uint(path[nameSize+2]-'0')*10;
pluginId += uint(path[nameSize+3]-'0');
}
}
else
{
// single digit, /x/method
offset = 4;
pluginId += uint(path[nameSize+2]-'0');
}
}
else
{
carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path);
return 1;
}

if (pluginId > fEngine->getCurrentPluginCount())
{
carla_stderr("CarlaEngineOsc::handleMessage() - failed to get plugin, wrong id '%i'", pluginId);
return 0;
}

// Get plugin
CarlaPlugin* const plugin(fEngine->getPluginUnchecked(pluginId));

if (plugin == nullptr || plugin->getId() != pluginId)
{
carla_stderr("CarlaEngineOsc::handleMessage() - invalid plugin id '%i', probably has been removed (path: '%s')", pluginId, path);
return 0;
}

// Get method from path, "/Carla/i/method" -> "method"
char method[32+1];
method[32] = '\0';
std::strncpy(method, path + (nameSize + offset), 32);

if (method[0] == '\0')
{
carla_stderr("CarlaEngineOsc::handleMessage(%s, \"%s\", ...) - received message without method", bool2str(isTCP), path);
return 0;
}

// Internal methods
if (std::strcmp(method, "set_option") == 0)
return 0; //handleMsgSetOption(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_active") == 0)
return handleMsgSetActive(plugin, argc, argv, types);
if (std::strcmp(method, "set_drywet") == 0)
return handleMsgSetDryWet(plugin, argc, argv, types);
if (std::strcmp(method, "set_volume") == 0)
return handleMsgSetVolume(plugin, argc, argv, types);
if (std::strcmp(method, "set_balance_left") == 0)
return handleMsgSetBalanceLeft(plugin, argc, argv, types);
if (std::strcmp(method, "set_balance_right") == 0)
return handleMsgSetBalanceRight(plugin, argc, argv, types);
if (std::strcmp(method, "set_panning") == 0)
return handleMsgSetPanning(plugin, argc, argv, types);
if (std::strcmp(method, "set_ctrl_channel") == 0)
return 0; //handleMsgSetControlChannel(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_parameter_value") == 0)
return handleMsgSetParameterValue(plugin, argc, argv, types);
if (std::strcmp(method, "set_parameter_midi_cc") == 0)
return handleMsgSetParameterMidiCC(plugin, argc, argv, types);
if (std::strcmp(method, "set_parameter_midi_channel") == 0)
return handleMsgSetParameterMidiChannel(plugin, argc, argv, types);
if (std::strcmp(method, "set_program") == 0)
return handleMsgSetProgram(plugin, argc, argv, types);
if (std::strcmp(method, "set_midi_program") == 0)
return handleMsgSetMidiProgram(plugin, argc, argv, types);
if (std::strcmp(method, "set_custom_data") == 0)
return 0; //handleMsgSetCustomData(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_chunk") == 0)
return 0; //handleMsgSetChunk(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "note_on") == 0)
return handleMsgNoteOn(plugin, argc, argv, types);
if (std::strcmp(method, "note_off") == 0)
return handleMsgNoteOff(plugin, argc, argv, types);

// Send all other methods to plugins, TODO
plugin->handleOscMessage(method, argc, argv, types, msg);
return 0;
}

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

int CarlaEngineOsc::handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types)
{
carla_debug("CarlaEngineOsc::handleMsgRegister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");

const char* const url = &argv[0]->s;
const lo_address addr = lo_address_new_from_url(url);

if (fControlData.owner != nullptr)
{
carla_stderr("OSC backend already registered to %s", fControlData.owner);

char* const path = lo_url_get_path(url);

char targetPath[std::strlen(path)+18];
std::strcpy(targetPath, path);
std::strcat(targetPath, "/exit-error");

lo_send_from(addr, isTCP ? fServerTCP : fServerUDP, LO_TT_IMMEDIATE,
targetPath, "s", "OSC already registered to another client");

free(path);
}
else
{
carla_stdout("OSC backend registered to %s", url);

const char* const host = lo_address_get_hostname(addr);
const char* const port = lo_address_get_port(addr);
const lo_address target = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port);

fControlData.owner = carla_strdup_safe(url);
fControlData.path = carla_strdup_free(lo_url_get_path(url));
fControlData.source = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port);
fControlData.target = target;

for (uint i=0, count=fEngine->getCurrentPluginCount(); i < count; ++i)
{
CarlaPlugin* const plugin(fEngine->getPluginUnchecked(i));
CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr);

fEngine->callback(false, true, ENGINE_CALLBACK_PLUGIN_ADDED, i, 0, 0, 0, 0.0f, plugin->getName());
}

const EngineOptions& opts(fEngine->getOptions());

fEngine->callback(false, true,
ENGINE_CALLBACK_ENGINE_STARTED, 0,
opts.processMode,
opts.transportMode,
static_cast<int>(fEngine->getBufferSize()),
static_cast<float>(fEngine->getSampleRate()),
fEngine->getCurrentDriverName());

// TODO
// fEngine->patchbayRefresh();
}

lo_address_free(addr);
return 0;
}

int CarlaEngineOsc::handleMsgUnregister(const int argc, const lo_arg* const* const argv, const char* const types)
{
carla_debug("CarlaEngineOsc::handleMsgUnregister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");

if (fControlData.owner == nullptr)
{
carla_stderr("OSC backend is not registered yet, unregister failed");
return 0;
}

const char* const url = &argv[0]->s;

if (std::strcmp(fControlData.owner, url) == 0)
{
carla_stdout("OSC client %s unregistered", url);
fControlData.clear();
return 0;
}

carla_stderr("OSC backend unregister failed, current owner %s does not match requested %s", fControlData.owner, url);
return 0;
}

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

int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetActive()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const bool active = (argv[0]->i != 0);

plugin->setActive(active, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetDryWet()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setDryWet(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetVolume()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setVolume(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setBalanceLeft(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setBalanceRight(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetPanning()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setPanning(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if");

const int32_t index = argv[0]->i;
const float value = argv[1]->f;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);

plugin->setParameterValue(static_cast<uint32_t>(index), value, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t index = argv[0]->i;
const int32_t cc = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL, 0);

plugin->setParameterMidiCC(static_cast<uint32_t>(index), static_cast<int16_t>(cc), false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t index = argv[0]->i;
const int32_t channel = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);

plugin->setParameterMidiChannel(static_cast<uint32_t>(index), static_cast<uint8_t>(channel), false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetProgram()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const int32_t index = argv[0]->i;

CARLA_SAFE_ASSERT_RETURN(index >= -1, 0);

plugin->setProgram(index, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const int32_t index = argv[0]->i;

CARLA_SAFE_ASSERT_RETURN(index >= -1, 0);

plugin->setMidiProgram(index, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgNoteOn()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii");

const int32_t channel = argv[0]->i;
const int32_t note = argv[1]->i;
const int32_t velo = argv[2]->i;

CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);
CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0);
CARLA_SAFE_ASSERT_RETURN(velo >= 0 && velo < MAX_MIDI_VALUE, 0);

plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(velo), true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgNoteOff()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t channel = argv[0]->i;
const int32_t note = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);
CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0);

plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), 0, true, false, true);
return 0;
fControlDataTCP.clear();
fControlDataUDP.clear();
}

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


+ 26
- 8
source/backend/engine/CarlaEngineOsc.hpp View File

@@ -81,20 +81,37 @@ public:

bool isControlRegistered() const noexcept
{
return (fControlData.target != nullptr);
return (fControlDataTCP.target != nullptr);
}

const CarlaOscData* getControlData() const noexcept
{
return &fControlData;
}
// -------------------------------------------------------------------
// TCP

void sendCallback(const EngineCallbackOpcode action, const uint pluginId,
const int value1, const int value2, const int value3,
const float valuef, const char* const valueStr) const noexcept;
void sendPluginInit(const uint pluginId, const char* const pluginName) const noexcept;
void sendPluginInfo(const CarlaPlugin* const plugin) const noexcept;
void sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept;
void sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t parameterId) const noexcept;
void sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept;
void sendRuntimeInfo() const noexcept;

// -------------------------------------------------------------------
// UDP

void sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept;
void sendPeaks(const uint pluginId, const float peaks[4]) const noexcept;

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

private:
CarlaEngine* const fEngine;

CarlaOscData fControlData; // for carla-control
// for carla-control
CarlaOscData fControlDataTCP;
CarlaOscData fControlDataUDP;

CarlaString fName;
CarlaString fServerPathTCP;
CarlaString fServerPathUDP;
@@ -103,10 +120,11 @@ private:

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

int handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);
int handleMessage(const bool isTCP, const char* const path,
const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);

int handleMsgRegister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types);
int handleMsgUnregister(const int argc, const lo_arg* const* const argv, const char* const types);
int handleMsgUnregister(const bool isTCP, const int argc, const lo_arg* const* const argv, const char* const types);

// Internal methods
int handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS);


+ 446
- 0
source/backend/engine/CarlaEngineOscHandlers.cpp View File

@@ -0,0 +1,446 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaEngineOsc.hpp"

#ifdef HAVE_LIBLO

#include "CarlaEngine.hpp"
#include "CarlaPlugin.hpp"
#include "CarlaMIDI.h"

#include <cctype>

CARLA_BACKEND_START_NAMESPACE

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

int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
{
CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', 1);
#ifdef DEBUG
if (std::strstr(path, "/bridge_pong") == nullptr) {
carla_debug("CarlaEngineOsc::handleMessage(%s, \"%s\", %i, %p, \"%s\", %p)", bool2str(isTCP), path, argc, argv, types, msg);
}
#endif

if (isTCP)
{
CARLA_SAFE_ASSERT_RETURN(fServerPathTCP.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServerTCP != nullptr, 1);
}
else
{
CARLA_SAFE_ASSERT_RETURN(fServerPathUDP.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServerUDP != nullptr, 1);
}

// Initial path check
if (std::strcmp(path, "/register") == 0)
return handleMsgRegister(isTCP, argc, argv, types);

if (std::strcmp(path, "/unregister") == 0)
return handleMsgUnregister(isTCP, argc, argv, types);

const std::size_t nameSize(fName.length());

// Check if message is for this client
if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0)
{
carla_stderr("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, fName.buffer());
return 1;
}

// Get plugin id from path, "/carla/23/method" -> 23
uint pluginId = 0;
std::size_t offset;

if (std::isdigit(path[nameSize+2]))
{
if (std::isdigit(path[nameSize+3]))
{
if (std::isdigit(path[nameSize+5]))
{
carla_stderr2("CarlaEngineOsc::handleMessage() - invalid plugin id, over 999? (value: \"%s\")", path+(nameSize+1));
return 1;
}
else if (std::isdigit(path[nameSize+4]))
{
// 3 digits, /xyz/method
offset = 6;
pluginId += uint(path[nameSize+2]-'0')*100;
pluginId += uint(path[nameSize+3]-'0')*10;
pluginId += uint(path[nameSize+4]-'0');
}
else
{
// 2 digits, /xy/method
offset = 5;
pluginId += uint(path[nameSize+2]-'0')*10;
pluginId += uint(path[nameSize+3]-'0');
}
}
else
{
// single digit, /x/method
offset = 4;
pluginId += uint(path[nameSize+2]-'0');
}
}
else
{
carla_stderr("CarlaEngineOsc::handleMessage() - invalid message '%s'", path);
return 1;
}

if (pluginId > fEngine->getCurrentPluginCount())
{
carla_stderr("CarlaEngineOsc::handleMessage() - failed to get plugin, wrong id '%i'", pluginId);
return 0;
}

// Get plugin
CarlaPlugin* const plugin(fEngine->getPluginUnchecked(pluginId));

if (plugin == nullptr || plugin->getId() != pluginId)
{
carla_stderr("CarlaEngineOsc::handleMessage() - invalid plugin id '%i', probably has been removed (path: '%s')", pluginId, path);
return 0;
}

// Get method from path, "/Carla/i/method" -> "method"
char method[32+1];
method[32] = '\0';
std::strncpy(method, path + (nameSize + offset), 32);

if (method[0] == '\0')
{
carla_stderr("CarlaEngineOsc::handleMessage(%s, \"%s\", ...) - received message without method", bool2str(isTCP), path);
return 0;
}

// Internal methods
if (std::strcmp(method, "set_option") == 0)
return 0; //handleMsgSetOption(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_active") == 0)
return handleMsgSetActive(plugin, argc, argv, types);
if (std::strcmp(method, "set_drywet") == 0)
return handleMsgSetDryWet(plugin, argc, argv, types);
if (std::strcmp(method, "set_volume") == 0)
return handleMsgSetVolume(plugin, argc, argv, types);
if (std::strcmp(method, "set_balance_left") == 0)
return handleMsgSetBalanceLeft(plugin, argc, argv, types);
if (std::strcmp(method, "set_balance_right") == 0)
return handleMsgSetBalanceRight(plugin, argc, argv, types);
if (std::strcmp(method, "set_panning") == 0)
return handleMsgSetPanning(plugin, argc, argv, types);
if (std::strcmp(method, "set_ctrl_channel") == 0)
return 0; //handleMsgSetControlChannel(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_parameter_value") == 0)
return handleMsgSetParameterValue(plugin, argc, argv, types);
if (std::strcmp(method, "set_parameter_midi_cc") == 0)
return handleMsgSetParameterMidiCC(plugin, argc, argv, types);
if (std::strcmp(method, "set_parameter_midi_channel") == 0)
return handleMsgSetParameterMidiChannel(plugin, argc, argv, types);
if (std::strcmp(method, "set_program") == 0)
return handleMsgSetProgram(plugin, argc, argv, types);
if (std::strcmp(method, "set_midi_program") == 0)
return handleMsgSetMidiProgram(plugin, argc, argv, types);
if (std::strcmp(method, "set_custom_data") == 0)
return 0; //handleMsgSetCustomData(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "set_chunk") == 0)
return 0; //handleMsgSetChunk(plugin, argc, argv, types); // TODO
if (std::strcmp(method, "note_on") == 0)
return handleMsgNoteOn(plugin, argc, argv, types);
if (std::strcmp(method, "note_off") == 0)
return handleMsgNoteOff(plugin, argc, argv, types);

// Send all other methods to plugins, TODO
plugin->handleOscMessage(method, argc, argv, types, msg);
return 0;
}

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

int CarlaEngineOsc::handleMsgRegister(const bool isTCP,
const int argc, const lo_arg* const* const argv, const char* const types)
{
carla_debug("CarlaEngineOsc::handleMsgRegister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");

const char* const url = &argv[0]->s;
const lo_address addr = lo_address_new_from_url(url);

CarlaOscData& oscData(isTCP ? fControlDataTCP : fControlDataUDP);

if (oscData.owner != nullptr)
{
carla_stderr("OSC backend already registered to %s", oscData.owner);

char* const path = lo_url_get_path(url);

char targetPath[std::strlen(path)+18];
std::strcpy(targetPath, path);
std::strcat(targetPath, "/exit-error");

lo_send_from(addr, isTCP ? fServerTCP : fServerUDP, LO_TT_IMMEDIATE,
targetPath, "s", "OSC already registered to another client");

free(path);
}
else
{
carla_stdout("OSC backend registered to %s", url);

const char* const host = lo_address_get_hostname(addr);
const char* const port = lo_address_get_port(addr);
const lo_address target = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port);

oscData.owner = carla_strdup_safe(url);
oscData.path = carla_strdup_free(lo_url_get_path(url));
oscData.source = lo_address_new_with_proto(isTCP ? LO_TCP : LO_UDP, host, port);
oscData.target = target;

for (uint i=0, count=fEngine->getCurrentPluginCount(); i < count; ++i)
{
CarlaPlugin* const plugin(fEngine->getPluginUnchecked(i));
CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr);

fEngine->callback(false, true, ENGINE_CALLBACK_PLUGIN_ADDED, i, 0, 0, 0, 0.0f, plugin->getName());
}

const EngineOptions& opts(fEngine->getOptions());

fEngine->callback(false, true,
ENGINE_CALLBACK_ENGINE_STARTED, 0,
opts.processMode,
opts.transportMode,
static_cast<int>(fEngine->getBufferSize()),
static_cast<float>(fEngine->getSampleRate()),
fEngine->getCurrentDriverName());

// TODO
// fEngine->patchbayRefresh();
}

lo_address_free(addr);
return 0;
}

int CarlaEngineOsc::handleMsgUnregister(const bool isTCP,
const int argc, const lo_arg* const* const argv, const char* const types)
{
carla_debug("CarlaEngineOsc::handleMsgUnregister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");

CarlaOscData& oscData(isTCP ? fControlDataTCP : fControlDataUDP);

if (oscData.owner == nullptr)
{
carla_stderr("OSC backend is not registered yet, unregister failed");
return 0;
}

const char* const url = &argv[0]->s;

if (std::strcmp(oscData.owner, url) == 0)
{
carla_stdout("OSC client %s unregistered", url);
oscData.clear();
return 0;
}

carla_stderr("OSC backend unregister failed, current owner %s does not match requested %s", oscData.owner, url);
return 0;
}

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

int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetActive()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const bool active = (argv[0]->i != 0);

plugin->setActive(active, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetDryWet()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setDryWet(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetVolume()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setVolume(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetBalanceLeft()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setBalanceLeft(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetBalanceRight()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setBalanceRight(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetPanning(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetPanning()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");

const float value = argv[0]->f;

plugin->setPanning(value, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterValue()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if");

const int32_t index = argv[0]->i;
const float value = argv[1]->f;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);

plugin->setParameterValue(static_cast<uint32_t>(index), value, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiCC()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t index = argv[0]->i;
const int32_t cc = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL, 0);

plugin->setParameterMidiCC(static_cast<uint32_t>(index), static_cast<int16_t>(cc), false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t index = argv[0]->i;
const int32_t channel = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);

plugin->setParameterMidiChannel(static_cast<uint32_t>(index), static_cast<uint8_t>(channel), false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetProgram()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const int32_t index = argv[0]->i;

CARLA_SAFE_ASSERT_RETURN(index >= -1, 0);

plugin->setProgram(index, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgSetMidiProgram()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");

const int32_t index = argv[0]->i;

CARLA_SAFE_ASSERT_RETURN(index >= -1, 0);

plugin->setMidiProgram(index, true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgNoteOn()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii");

const int32_t channel = argv[0]->i;
const int32_t note = argv[1]->i;
const int32_t velo = argv[2]->i;

CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);
CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0);
CARLA_SAFE_ASSERT_RETURN(velo >= 0 && velo < MAX_MIDI_VALUE, 0);

plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(velo), true, false, true);
return 0;
}

int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS)
{
carla_debug("CarlaEngineOsc::handleMsgNoteOff()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");

const int32_t channel = argv[0]->i;
const int32_t note = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);
CARLA_SAFE_ASSERT_RETURN(note >= 0 && note < MAX_MIDI_NOTE, 0);

plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), 0, true, false, true);
return 0;
}

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

CARLA_BACKEND_END_NAMESPACE

#endif // HAVE_LIBLO

+ 207
- 387
source/backend/engine/CarlaEngineOscSend.cpp View File

@@ -15,458 +15,278 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaDefines.h"
#include "CarlaEngineOsc.hpp"

#ifdef HAVE_LIBLO

#include "CarlaBackendUtils.hpp"
#include "CarlaEngineInternal.hpp"
#include "CarlaMIDI.h"
#include "CarlaEngine.hpp"
#include "CarlaPlugin.hpp"

CARLA_BACKEND_START_NAMESPACE

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

#ifndef BUILD_BRIDGE
void CarlaEngine::oscSend_control_callback(const EngineCallbackOpcode action, const uint pluginId,
const int value1, const int value2, const int value3,
const float valuef, const char* const valueStr) const noexcept
void CarlaEngineOsc::sendCallback(const EngineCallbackOpcode action, const uint pluginId,
const int value1, const int value2, const int value3,
const float valuef, const char* const valueStr) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
carla_debug("CarlaEngine::oscSend_control_callback(%i:%s, %i, %i, %i, %i, %f, \"%s\")",
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
carla_debug("CarlaEngineOsc::sendCallback(%i:%s, %i, %i, %i, %i, %f, \"%s\")",
action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valuef, valueStr);

static const char* const kFakeNullString = "(null)";

char targetPath[std::strlen(pData->oscData->path)+10];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/callback");
try_lo_send(pData->oscData->target, targetPath, "iiiiifs",
char targetPath[std::strlen(fControlDataTCP.path)+10];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/cb");
try_lo_send(fControlDataTCP.target, targetPath, "iiiiifs",
action, pluginId, value1, value2, value3, static_cast<double>(valuef),
valueStr != nullptr ? valueStr : kFakeNullString);
}

void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept
void CarlaEngineOsc::sendPluginInit(const uint pluginId, const char* const pluginName) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',);
carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName);
carla_debug("CarlaEngineOsc::sendadd_plugin_start(%i, \"%s\")", pluginId, pluginName);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/add_plugin_start");
try_lo_send(pData->oscData->target, targetPath, "is", static_cast<int32_t>(pluginId), pluginName);
char targetPath[std::strlen(fControlDataTCP.path)+18];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/init");
try_lo_send(fControlDataTCP.target, targetPath, "is", static_cast<int32_t>(pluginId), pluginName);
}

#if 0
void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId);

char targetPath[std::strlen(pData->oscData->path)+16];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/add_plugin_end");
try_lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(pluginId));
}

void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId);

char targetPath[std::strlen(pData->oscData->path)+15];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/remove_plugin");
try_lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(pluginId));
}
#endif

void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const int64_t uniqueId) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,);
carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, " P_INT64 ")", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_plugin_info1");
try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast<int32_t>(pluginId), static_cast<int32_t>(type), static_cast<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(uniqueId));
}

void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(maker != nullptr,);
CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,);
carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_plugin_info2");
try_lo_send(pData->oscData->target, targetPath, "issss", static_cast<int32_t>(pluginId), realName, label, maker, copyright);
}

void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_audio_count");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
}

void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_midi_count");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
}

void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(ins < 50,);
CARLA_SAFE_ASSERT_RETURN(outs < 50,);
carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_count");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
}

void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(count <= 50,);
carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count);

char targetPath[std::strlen(pData->oscData->path)+19];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_program_count");
try_lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
}

void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept
void CarlaEngineOsc::sendPluginInfo(const CarlaPlugin* const plugin) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(count <= 50,);
carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count);

char targetPath[std::strlen(pData->oscData->path)+24];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_midi_program_count");
try_lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
carla_debug("CarlaEngineOsc::sendPluginInfo(%p)", plugin);

char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1];
carla_zeroChars(bufName, STR_MAX+1);
carla_zeroChars(bufLabel, STR_MAX+1);
carla_zeroChars(bufMaker, STR_MAX+1);
carla_zeroChars(bufCopyright, STR_MAX+1);

plugin->getRealName(bufName);
plugin->getLabel(bufLabel);
plugin->getMaker(bufMaker);
plugin->getCopyright(bufCopyright);

char targetPath[std::strlen(fControlDataTCP.path)+10];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/info");
try_lo_send(fControlDataTCP.target, targetPath, "iiiihssss",
static_cast<int32_t>(plugin->getId()),
static_cast<int32_t>(plugin->getType()),
static_cast<int32_t>(plugin->getCategory()),
static_cast<int32_t>(plugin->getHints()),
static_cast<int64_t>(plugin->getUniqueId()),
bufName, bufLabel, bufMaker, bufCopyright);
}

void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept
void CarlaEngineOsc::sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(unit != nullptr,);
carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit);

char targetPath[std::strlen(pData->oscData->path)+20];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_data");
try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(type), static_cast<int32_t>(hints), name, unit);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
carla_debug("CarlaEngineOsc::sendPluginInfo(%p)", plugin);

uint32_t paramIns, paramOuts;
plugin->getParameterCountInfo(paramIns, paramOuts);

if (paramIns > 49)
paramIns = 49;
if (paramOuts > 49)
paramOuts = 49;

char targetPath[std::strlen(fControlDataTCP.path)+7];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/ports");
try_lo_send(fControlDataTCP.target, targetPath, "iiiiiiii",
static_cast<int32_t>(plugin->getId()),
static_cast<int32_t>(plugin->getAudioInCount()),
static_cast<int32_t>(plugin->getAudioOutCount()),
static_cast<int32_t>(plugin->getMidiInCount()),
static_cast<int32_t>(plugin->getMidiOutCount()),
static_cast<int32_t>(paramIns),
static_cast<int32_t>(paramOuts),
static_cast<int32_t>(plugin->getParameterCount()));
}

void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept
void CarlaEngineOsc::sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t parameterId) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT(def >= min && def <= max);
CARLA_SAFE_ASSERT(min < max);
carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def);

char targetPath[std::strlen(pData->oscData->path)+24];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_ranges1");
try_lo_send(pData->oscData->target, targetPath, "iifff",
static_cast<int32_t>(pluginId),
static_cast<int32_t>(index),
static_cast<double>(def),
static_cast<double>(min),
static_cast<double>(max));
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
carla_debug("CarlaEngineOsc::sendPluginInfo(%p, %u)", plugin, parameterId);

char bufName[STR_MAX+1], bufUnit[STR_MAX+1];
carla_zeroChars(bufName, STR_MAX+1);
carla_zeroChars(bufUnit, STR_MAX+1);

const ParameterData& paramData(plugin->getParameterData(parameterId));
const ParameterRanges& paramRanges(plugin->getParameterRanges(parameterId));

plugin->getParameterName(parameterId, bufName);
plugin->getParameterUnit(parameterId, bufUnit);

char targetPath[std::strlen(fControlDataTCP.path)+20];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/param");
try_lo_send(fControlDataTCP.target, targetPath, "iiiiiissfffffff",
static_cast<int32_t>(plugin->getId()), static_cast<int32_t>(parameterId),
static_cast<int32_t>(paramData.type), static_cast<int32_t>(paramData.hints),
static_cast<int32_t>(paramData.midiChannel), static_cast<int32_t>(paramData.midiCC),
bufName, bufUnit,
static_cast<double>(paramRanges.def),
static_cast<double>(paramRanges.min),
static_cast<double>(paramRanges.max),
static_cast<double>(paramRanges.step),
static_cast<double>(paramRanges.stepSmall),
static_cast<double>(paramRanges.stepLarge),
static_cast<double>(plugin->getParameterValue(parameterId)));
}

void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept
void CarlaEngineOsc::sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT(step >= stepSmall && step <= stepLarge);
CARLA_SAFE_ASSERT(stepSmall <= stepLarge);
carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge);

char targetPath[std::strlen(pData->oscData->path)+24];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_ranges2");
try_lo_send(pData->oscData->target, targetPath, "iifff",
static_cast<int32_t>(pluginId),
static_cast<int32_t>(index),
static_cast<double>(step),
static_cast<double>(stepSmall),
static_cast<double>(stepLarge));
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
carla_debug("CarlaEngineOsc::sendPluginInternalParameterValues(%p)", plugin);

static_assert(PARAMETER_ACTIVE == -2 && PARAMETER_MAX == -9);

double iparams[7];

for (int32_t i = 0; i < 7; ++i)
iparams[i] = plugin->getInternalParameterValue(PARAMETER_ACTIVE - i);

char targetPath[std::strlen(fControlDataTCP.path)+18];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/iparams");
try_lo_send(fControlDataTCP.target, targetPath, "ifffffff",
static_cast<int32_t>(plugin->getId()),
iparams[0], // PARAMETER_ACTIVE
iparams[1], // PARAMETER_DRYWET
iparams[2], // PARAMETER_VOLUME
iparams[3], // PARAMETER_BALANCE_LEFT
iparams[4], // PARAMETER_BALANCE_RIGHT
iparams[5], // PARAMETER_PANNING
iparams[6] // PARAMETER_CTRL_CHANNEL
);
}

#if 0
void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept
void CarlaEngineOsc::sendset_program_count(const uint pluginId, const uint32_t count) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,);
carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc);

char targetPath[std::strlen(pData->oscData->path)+23];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_midi_cc");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(cc));
}
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
carla_debug("CarlaEngineOsc::sendset_program_count(%i, %i)", pluginId, count);

void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel);

char targetPath[std::strlen(pData->oscData->path)+28];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_parameter_midi_channel");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(channel));
}
#endif

void CarlaEngine::oscSend_control_set_output_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,);
carla_debug("CarlaEngine::oscSend_control_set_output_parameter_value(%i, %i:%s, %f)", pluginId, index,
(index < 0) ? InternalParameterIndex2Str(static_cast<InternalParameterIndex>(index)) : "(none)", value);

char targetPath[std::strlen(pData->oscData->path)+21];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_output_parameter_value");
try_lo_send(pData->oscData->target, targetPath, "iif",
static_cast<int32_t>(pluginId),
index,
static_cast<double>(value));
}

#if 0
void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value);

char targetPath[std::strlen(pData->oscData->path)+19];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_default_value");
try_lo_send(pData->oscData->target, targetPath, "iif",
static_cast<int32_t>(pluginId),
static_cast<int32_t>(index),
static_cast<double>(value));
char targetPath[std::strlen(fControlDataTCP.path)+19];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/set_program_count");
try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
}

void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept
void CarlaEngineOsc::sendset_midi_program_count(const uint pluginId, const uint32_t count) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index);

char targetPath[std::strlen(pData->oscData->path)+21];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_current_program");
try_lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), index);
}
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
carla_debug("CarlaEngineOsc::sendset_midi_program_count(%i, %i)", pluginId, count);

void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index);

char targetPath[std::strlen(pData->oscData->path)+26];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_current_midi_program");
try_lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), index);
char targetPath[std::strlen(fControlDataTCP.path)+24];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/set_midi_program_count");
try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
}
#endif

void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept
void CarlaEngineOsc::sendset_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name);
carla_debug("CarlaEngineOsc::sendset_program_name(%i, %i, \"%s\")", pluginId, index, name);

char targetPath[std::strlen(pData->oscData->path)+18];
std::strcpy(targetPath, pData->oscData->path);
char targetPath[std::strlen(fControlDataTCP.path)+18];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/set_program_name");
try_lo_send(pData->oscData->target, targetPath, "iis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), name);
try_lo_send(fControlDataTCP.target, targetPath, "iis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), name);
}

void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept
void CarlaEngineOsc::sendset_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId <= pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(index < 50,);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name);
carla_debug("CarlaEngineOsc::sendset_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name);

char targetPath[std::strlen(pData->oscData->path)+23];
std::strcpy(targetPath, pData->oscData->path);
char targetPath[std::strlen(fControlDataTCP.path)+23];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/set_midi_program_data");
try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name);
try_lo_send(fControlDataTCP.target, targetPath, "iiiis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name);
}
#endif

#if 0
void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,);
carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo);

char targetPath[std::strlen(pData->oscData->path)+9];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/note_on");
try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note), static_cast<int32_t>(velo));
}
// -----------------------------------------------------------------------

// FIXME use UDP

void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept
void CarlaEngineOsc::sendRuntimeInfo() const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note);

char targetPath[std::strlen(pData->oscData->path)+10];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/note_off");
try_lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note));
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
carla_debug("CarlaEngineOsc::sendRuntimeInfo()");

const EngineTimeInfo timeInfo(fEngine->getTimeInfo());

char targetPath[std::strlen(fControlDataTCP.path)+18];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/runtime");
try_lo_send(fControlDataTCP.target, targetPath, "fiihiiif",
static_cast<double>(fEngine->getDSPLoad()),
static_cast<int32_t>(fEngine->getTotalXruns()),
timeInfo.playing ? 1 : 0,
static_cast<int64_t>(timeInfo.frame),
static_cast<int32_t>(timeInfo.bbt.bar),
static_cast<int32_t>(timeInfo.bbt.beat),
static_cast<int32_t>(timeInfo.bbt.tick),
timeInfo.bbt.beatsPerMinute);
}
#endif

void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept
void CarlaEngineOsc::sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);

// TODO - try and see if we can get peaks[4] ref
const EnginePluginData& epData(pData->plugins[pluginId]);

char targetPath[std::strlen(pData->oscData->path)+11];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/set_peaks");
try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast<int32_t>(pluginId),
static_cast<double>(epData.peaks[0]),
static_cast<double>(epData.peaks[1]),
static_cast<double>(epData.peaks[2]),
static_cast<double>(epData.peaks[3]));
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);

char targetPath[std::strlen(fControlDataTCP.path)+21];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/param_fixme");
try_lo_send(fControlDataTCP.target, targetPath, "iif",
static_cast<int32_t>(pluginId),
index,
static_cast<double>(value));
}

#if 0
void CarlaEngine::oscSend_control_exit() const noexcept
void CarlaEngineOsc::sendPeaks(const uint pluginId, const float peaks[4]) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,);
carla_debug("CarlaEngine::oscSend_control_exit()");

char targetPath[std::strlen(pData->oscData->path)+6];
std::strcpy(targetPath, pData->oscData->path);
std::strcat(targetPath, "/exit");
try_lo_send(pData->oscData->target, targetPath, "");
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);

char targetPath[std::strlen(fControlDataTCP.path)+11];
std::strcpy(targetPath, fControlDataTCP.path);
std::strcat(targetPath, "/peaks");
try_lo_send(fControlDataTCP.target, targetPath, "iffff", static_cast<int32_t>(pluginId),
static_cast<double>(peaks[0]),
static_cast<double>(peaks[1]),
static_cast<double>(peaks[2]),
static_cast<double>(peaks[3]));
}
#endif
#endif // BUILD_BRIDGE

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



+ 11
- 5
source/backend/engine/CarlaEngineThread.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,8 +15,8 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaEngine.hpp"
#include "CarlaEngineThread.hpp"
#include "CarlaEngineInternal.hpp"
#include "CarlaPlugin.hpp"

CARLA_BACKEND_START_NAMESPACE
@@ -48,6 +48,10 @@ void CarlaEngineThread::run() noexcept

float value;

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
CarlaEngineOsc& engineOsc(kEngine->pData->osc);
#endif

// thread must do something...
CARLA_SAFE_ASSERT_RETURN(kIsAlwaysRunning || kEngine->isRunning(),);

@@ -61,7 +65,9 @@ void CarlaEngineThread::run() noexcept

#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
if (kIsPlugin)
kEngine->idleOsc();
engineOsc.idle();
if (oscRegisted)
engineOsc.sendRuntimeInfo();
#endif

for (uint i=0, count = kEngine->getCurrentPluginCount(); i < count; ++i)
@@ -99,7 +105,7 @@ void CarlaEngineThread::run() noexcept
#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC engine client
if (oscRegisted)
kEngine->oscSend_control_set_output_parameter_value(i, static_cast<int32_t>(j), value);
engineOsc.sendParameterValue(i, j, value);
#endif
// Update UI
if (updateUI)
@@ -119,7 +125,7 @@ void CarlaEngineThread::run() noexcept
// Update OSC control client peaks

if (oscRegisted)
kEngine->oscSend_control_set_peaks(i);
engineOsc.sendPeaks(i, kEngine->getPeaks(i));
#endif
}



+ 1
- 0
source/backend/engine/Makefile View File

@@ -28,6 +28,7 @@ OBJS = \
ifeq ($(HAVE_LIBLO),true)
OBJS += \
$(OBJDIR)/CarlaEngineOsc.cpp.o \
$(OBJDIR)/CarlaEngineOscHandlers.cpp.o \
$(OBJDIR)/CarlaEngineOscSend.cpp.o
endif



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

@@ -2124,95 +2124,12 @@ void CarlaPlugin::clearBuffers() noexcept
pData->clearBuffers();
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// -------------------------------------------------------------------
// OSC stuff

#if 0
void CarlaPlugin::registerToOscClient() noexcept
{
if (! pData->engine->isOscControlRegistered())
return;

pData->engine->oscSend_control_add_plugin_start(pData->id, pData->name);

// Base data
{
char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1];
carla_zeroChars(bufName, STR_MAX);
carla_zeroChars(bufLabel, STR_MAX);
carla_zeroChars(bufMaker, STR_MAX);
carla_zeroChars(bufCopyright, STR_MAX);

getRealName(bufName);
getLabel(bufLabel);
getMaker(bufMaker);
getCopyright(bufCopyright);

pData->engine->oscSend_control_set_plugin_info1(pData->id, getType(), getCategory(), pData->hints, getUniqueId());
pData->engine->oscSend_control_set_plugin_info2(pData->id, bufName, bufLabel, bufMaker, bufCopyright);
}

// Base count
uint32_t paramIns, paramOuts;

{
getParameterCountInfo(paramIns, paramOuts);

if (paramIns > 49)
paramIns = 49;
if (paramOuts > 49)
paramOuts = 49;

pData->engine->oscSend_control_set_audio_count(pData->id, getAudioInCount(), getAudioOutCount());
pData->engine->oscSend_control_set_midi_count(pData->id, getMidiInCount(), getMidiOutCount());
pData->engine->oscSend_control_set_parameter_count(pData->id, paramIns, paramOuts);
}

// Plugin Parameters
if (const uint32_t count = std::min<uint32_t>(pData->param.count, 98U))
{
char bufName[STR_MAX+1], bufUnit[STR_MAX+1];

for (uint32_t i=0; i<count; ++i)
{
const ParameterData& paramData(pData->param.data[i]);

if (paramData.type == PARAMETER_INPUT)
{
if (--paramIns == 0)
break;
}
else if (paramData.type == PARAMETER_OUTPUT)
{
if (--paramOuts == 0)
break;
}
else
{
continue;
}

const ParameterRanges& paramRanges(pData->param.ranges[i]);

carla_zeroChars(bufName, STR_MAX);
carla_zeroChars(bufUnit, STR_MAX);

getParameterName(i, bufName);
getParameterUnit(i, bufUnit);

pData->engine->oscSend_control_set_parameter_data(pData->id, i, paramData.type, paramData.hints, bufName, bufUnit);
pData->engine->oscSend_control_set_parameter_ranges1(pData->id, i, paramRanges.def, paramRanges.min, paramRanges.max);
pData->engine->oscSend_control_set_parameter_ranges2(pData->id, i, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
// pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(i), getParameterValue(i));
//
// if (paramData.midiCC >= 0)
// pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, i, paramData.midiCC);
//
// if (paramData.midiChannel != 0)
// pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, i, paramData.midiChannel);
}
}

// Programs
if (const uint32_t count = std::min<uint32_t>(pData->prog.count, 50U))
{
@@ -2238,17 +2155,6 @@ void CarlaPlugin::registerToOscClient() noexcept

// pData->engine->oscSend_control_set_current_midi_program(pData->id, pData->midiprog.current);
}

// Internal Parameters
{
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, pData->postProc.dryWet);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, pData->postProc.volume);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, pData->postProc.balanceLeft);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, pData->postProc.balanceRight);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, pData->postProc.panning);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, pData->ctrlChannel);
// pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, pData->active ? 1.0f : 0.0f);
}
}
#endif

@@ -2257,7 +2163,6 @@ void CarlaPlugin::handleOscMessage(const char* const, const int, const void* con
{
// do nothing
}
//#endif // HAVE_LIBLO && ! BUILD_BRIDGE

// -------------------------------------------------------------------
// MIDI events
@@ -2296,7 +2201,7 @@ void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note,
}

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
void CarlaPlugin::sendMidiAllNotesOffToCallback()
void CarlaPlugin::postponeRtAllNotesOff()
{
if (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)
return;


+ 1
- 1
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -1316,7 +1316,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -1221,17 +1221,6 @@ public:
}
}

#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_midi_program_count(pData->id, newCount);

for (uint32_t i=0; i < newCount; ++i)
pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);
}
#endif

if (doInit)
{
if (newCount > 0)
@@ -1598,7 +1587,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginFluidSynth.cpp View File

@@ -1034,17 +1034,6 @@ public:
return;
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_midi_program_count(pData->id, count);

for (uint32_t i=0; i < count; ++i)
pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);
}
#endif

if (doInit)
{
fluid_synth_program_reset(fSynth);
@@ -1325,7 +1314,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 1
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -1042,7 +1042,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginJuce.cpp View File

@@ -647,17 +647,6 @@ public:
pData->prog.names[i] = carla_strdup(fInstance->getProgramName(i).toRawUTF8());
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_program_count(pData->id, newCount);

for (uint32_t i=0; i < newCount; ++i)
pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
}
#endif

if (doInit)
{
if (newCount > 0)
@@ -936,7 +925,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -2848,17 +2848,6 @@ public:
}
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_midi_program_count(pData->id, newCount);

for (uint32_t i=0; i < newCount; ++i)
pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);
}
#endif

if (doInit)
{
if (newCount > 0)
@@ -3639,7 +3628,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -1337,17 +1337,6 @@ public:
}
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_midi_program_count(pData->id, count);

for (i=0; i < count; ++i)
pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);
}
#endif

if (doInit)
{
if (count > 0)
@@ -1901,7 +1890,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 1
source/backend/plugin/CarlaPluginSFZero.cpp View File

@@ -497,7 +497,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 1
- 12
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -987,17 +987,6 @@ public:
}
}

#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
pData->engine->oscSend_control_set_program_count(pData->id, newCount);

for (uint32_t i=0; i < newCount; ++i)
pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
}
#endif

if (doInit)
{
if (newCount > 0)
@@ -1468,7 +1457,7 @@ public:
if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
{
allNotesOffSent = true;
sendMidiAllNotesOffToCallback();
postponeRtAllNotesOff();
}
#endif



+ 19
- 0
source/frontend/carla_backend.py View File

@@ -3462,4 +3462,23 @@ class CarlaHostPlugin(CarlaHostMeta):
self.fPluginsInfo[pluginIdA] = self.fPluginsInfo[pluginIdB]
self.fPluginsInfo[pluginIdB] = tmp

def _setViaCallback(self, action, pluginId, value1, value2, value3, valuef, valueStr):
if action == ENGINE_CALLBACK_PLUGIN_RENAMED:
self._set_pluginName(pluginId, valueStr)
elif action == ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
if value1 < 0:
self._set_internalValue(pluginId, value1, valuef)
else:
self._set_parameterValue(pluginId, value1, valuef)
elif action == ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED:
self._set_parameterDefault(pluginId, value1, valuef)
elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED:
self._set_parameterMidiCC(pluginId, value1, value2)
elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
self._set_parameterMidiChannel(pluginId, value1, value2)
elif action == ENGINE_CALLBACK_PROGRAM_CHANGED:
self._set_currentProgram(pluginId, value1)
elif action == ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED:
self._set_currentMidiProgram(pluginId, value1)

# ------------------------------------------------------------------------------------------------------------

+ 77
- 168
source/frontend/carla_control.py View File

@@ -154,34 +154,38 @@ class CarlaControlServer(Server):
def getFullURL(self):
return "%scarla-control" % self.get_url()

@make_method('/carla-control/add_plugin_start', 'is') # FIXME skip name
def add_plugin_start_callback(self, path, args):
@make_method('/carla-control/cb', 'iiiiifs')
def carla_cb(self, path, args):
print(path, args)
self.fReceivedMsgs = True
action, pluginId, value1, value2, value3, valuef, valueStr = args
self.host._setViaCallback(action, pluginId, value1, value2, value3, valuef, valueStr)
engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr)

@make_method('/carla-control/init', 'is') # FIXME set name in add method
def carla_init(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, pluginName = args
self.host._add(pluginId)
self.host._set_pluginInfoUpdate(pluginId, {'name': pluginName})

#@make_method('/carla-control/add_plugin_end', 'i') # FIXME skip name
#def add_plugin_end_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, = args
#self.host.PluginAddedCallback.emit(pluginId, "") #self.fPluginsInfo[pluginId].pluginInfo['name'])

#@make_method('/carla-control/remove_plugin', 'i')
#def remove_plugin_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, = args
#self.host.PluginRemovedCallback.emit(pluginId)

@make_method('/carla-control/set_plugin_info1', 'iiiih')
def set_plugin_info1_callback(self, path, args):
@make_method('/carla-control/ports', 'iiiiiiii')
def carla_ports(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, type_, category, hints, uniqueId = args # , optsAvail, optsEnabled
pluginId, audioIns, audioOuts, midiIns, midiOuts, paramIns, paramOuts, paramTotal = args
self.host._set_audioCountInfo(pluginId, {'ins': audioIns, 'outs': audioOuts})
self.host._set_midiCountInfo(pluginId, {'ins': midiOuts, 'outs': midiOuts})
self.host._set_parameterCountInfo(pluginId, paramTotal, {'ins': paramIns, 'outs': paramOuts})

@make_method('/carla-control/info', 'iiiihssss')
def carla_info(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, type_, category, hints, uniqueId, realName, label, maker, copyright = args
optsAvail = optsEnabled = 0x0 # FIXME
filename = name = iconName = "" # FIXME

hints &= ~PLUGIN_HAS_CUSTOM_UI

@@ -191,19 +195,7 @@ class CarlaControlServer(Server):
'hints': hints,
'optionsAvailable': optsAvail,
'optionsEnabled': optsEnabled,
'uniqueId': uniqueId
}

self.host._set_pluginInfoUpdate(pluginId, pinfo)

@make_method('/carla-control/set_plugin_info2', 'issss')
def set_plugin_info2_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, realName, label, maker, copyright = args # , filename, name, iconName
filename = name = iconName = "" # FIXME

pinfo = {
'uniqueId': uniqueId,
'filename': filename,
#'name': name, # FIXME
'label': label,
@@ -215,47 +207,14 @@ class CarlaControlServer(Server):
self.host._set_pluginInfoUpdate(pluginId, pinfo)
self.host._set_pluginRealName(pluginId, realName)

@make_method('/carla-control/set_audio_count', 'iii')
def set_audio_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, ins, outs = args
self.host._set_audioCountInfo(pluginId, {'ins': ins, 'outs': outs})

@make_method('/carla-control/set_midi_count', 'iii')
def set_midi_count_callback(self, path, args):
@make_method('/carla-control/param', 'iiiiiissfffffff')
def carla_param(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, ins, outs = args
self.host._set_midiCountInfo(pluginId, {'ins': ins, 'outs': outs})

@make_method('/carla-control/set_parameter_count', 'iii') # FIXME
def set_parameter_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, ins, outs = args # , count
count = ins + outs
self.host._set_parameterCountInfo(pluginId, count, {'ins': ins, 'outs': outs})

@make_method('/carla-control/set_program_count', 'ii')
def set_program_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, count = args
self.host._set_programCount(pluginId, count)

@make_method('/carla-control/set_midi_program_count', 'ii')
def set_midi_program_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, count = args
self.host._set_midiProgramCount(pluginId, count)

@make_method('/carla-control/set_parameter_data', 'iiiiss')
def set_parameter_data_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, paramId, type_, hints, name, unit = args
(
pluginId, paramId, type_, hints, midiChan, midiCC, name, unit,
def_, min_, max_, step, stepSmall, stepLarge, value
) = args

hints &= ~(PARAMETER_USES_SCALEPOINTS | PARAMETER_USES_CUSTOM_TEXT)

@@ -272,89 +231,49 @@ class CarlaControlServer(Server):
'hints': hints,
'index': paramId,
'rindex': -1,
'midiCC': -1,
'midiChannel': 0
'midiCC': midiCC,
'midiChannel': midiChan,
}
self.host._set_parameterData(pluginId, paramId, paramData)

@make_method('/carla-control/set_parameter_ranges1', 'iifff')
def set_parameter_ranges1_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, paramId, def_, min_, max_ = args

paramRanges = {
'def': def_,
'min': min_,
'max': max_
'max': max_,
'step': step,
'stepSmall': stepSmall,
'stepLarge': stepLarge,
}

self.host._set_parameterRangesUpdate(pluginId, paramId, paramRanges)

@make_method('/carla-control/set_parameter_ranges2', 'iifff')
def set_parameter_ranges2_callback(self, path, args):
self.host._set_parameterValue(pluginId, paramId, value)

@make_method('/carla-control/iparams', 'ifffffff')
def carla_iparams(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, paramId, step, stepSmall, stepLarge = args

paramRanges = {
'step': step,
'stepSmall': stepSmall,
'stepLarge': stepLarge
}
pluginId, active, drywet, volume, balLeft, balRight, pan, ctrlChan = args
self.host._set_internalValue(pluginId, PARAMETER_ACTIVE, active)
self.host._set_internalValue(pluginId, PARAMETER_DRYWET, drywet)
self.host._set_internalValue(pluginId, PARAMETER_VOLUME, volume)
self.host._set_internalValue(pluginId, PARAMETER_BALANCE_LEFT, balLeft)
self.host._set_internalValue(pluginId, PARAMETER_BALANCE_RIGHT, balRight)
self.host._set_internalValue(pluginId, PARAMETER_PANNING, pan)
self.host._set_internalValue(pluginId, PARAMETER_CTRL_CHANNEL, ctrlChan)

self.host._set_parameterRangesUpdate(pluginId, paramId, paramRanges)

#@make_method('/carla-control/set_parameter_midi_cc', 'iii')
#def set_parameter_midi_cc_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, paramId, cc = args
#self.host._set_parameterMidiCC(pluginId, paramId, cc)
#self.host.ParameterMidiCcChangedCallback.emit(pluginId, paramId, cc)

#@make_method('/carla-control/set_parameter_midi_channel', 'iii')
#def set_parameter_midi_channel_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, paramId, channel = args
#self.host._set_parameterMidiChannel(pluginId, paramId, channel)
#self.host.ParameterMidiChannelChangedCallback.emit(pluginId, paramId, channel)

@make_method('/carla-control/set_output_parameter_value', 'iif')
def set_parameter_value_callback(self, path, args):
pluginId, paramId, paramValue = args
@make_method('/carla-control/set_program_count', 'ii')
def set_program_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, count = args
self.host._set_programCount(pluginId, count)

if paramId < 0:
self.host._set_internalValue(pluginId, paramId, paramValue)
else:
self.host._set_parameterValue(pluginId, paramId, paramValue)

self.host.ParameterValueChangedCallback.emit(pluginId, paramId, paramValue)

#@make_method('/carla-control/set_default_value', 'iif')
#def set_default_value_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, paramId, paramValue = args
#self.host._set_parameterDefault(pluginId, paramId, paramValue)
#self.host.ParameterDefaultChangedCallback.emit(pluginId, paramId, paramValue)

#@make_method('/carla-control/set_current_program', 'ii')
#def set_current_program_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, current = args
#self.host._set_currentProgram(pluginId, current)
#self.host.ProgramChangedCallback.emit(pluginId, current)

#@make_method('/carla-control/set_current_midi_program', 'ii')
#def set_current_midi_program_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, current = args
#self.host._set_currentMidiProgram(pluginId, current)
#self.host.MidiProgramChangedCallback.emit(pluginId, current)
@make_method('/carla-control/set_midi_program_count', 'ii')
def set_midi_program_count_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
pluginId, count = args
self.host._set_midiProgramCount(pluginId, count)

@make_method('/carla-control/set_program_name', 'iis')
def set_program_name_callback(self, path, args):
@@ -371,30 +290,27 @@ class CarlaControlServer(Server):
self.host._set_midiProgramData(pluginId, midiProgId, {'bank': bank, 'program': program, 'name': name})

#@make_method('/carla-control/note_on', 'iiii')
#def set_note_on_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, channel, note, velocity = args
#self.host.NoteOnCallback.emit(pluginId, channel, note, velocity)

#@make_method('/carla-control/note_off', 'iii')
#def set_note_off_callback(self, path, args):
#print(path, args)
#self.fReceivedMsgs = True
#pluginId, channel, note = args
#self.host.NoteOffCallback.emit(pluginId, channel, note)

@make_method('/carla-control/set_peaks', 'iffff')
def set_peaks_callback(self, path, args):

@make_method('/carla-control/runtime', 'fiihiiif')
def carla_runtime(self, path, args):
self.fReceivedMsgs = True
load, xruns, playing, frame, bar, beat, tick, bpm = args
self.host._set_runtime_info(load, xruns)
self.host._set_transport(bool(playing), frame, bar, beat, tick, bpm)

@make_method('/carla-control/param_fixme', 'iif')
def carla_param_fixme(self, path, args):
self.fReceivedMsgs = True
pluginId, paramId, paramValue = args
self.host._set_parameterValue(pluginId, paramId, paramValue)

@make_method('/carla-control/peaks', 'iffff')
def carla_peaks(self, path, args):
self.fReceivedMsgs = True
pluginId, in1, in2, out1, out2 = args
self.host._set_peaks(pluginId, in1, in2, out1, out2)

@make_method('/carla-control/exit', '')
def set_exit_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
self.host.QuitCallback.emit()
#@make_method('/carla-control/note_on', 'iiii')

@make_method('/carla-control/exit-error', 's')
def set_exit_error_callback(self, path, args):
@@ -405,13 +321,6 @@ class CarlaControlServer(Server):
self.host.QuitCallback.emit()
self.host.ErrorCallback.emit(error)

@make_method('/carla-control/callback', 'iiiiifs')
def set_callback_callback(self, path, args):
print(path, args)
self.fReceivedMsgs = True
action, pluginId, value1, value2, value3, valuef, valueStr = args
engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr)

@make_method(None, None)
def fallback(self, path, args):
print("ControlServer::fallback(\"%s\") - unknown message, args =" % path, args)


+ 1
- 18
source/native-plugins/resources/carla-plugin View File

@@ -198,24 +198,7 @@ class CarlaMiniW(ExternalUI, HostWindow):
valuef = float(self.readlineblock())
valueStr = self.readlineblock().replace("\r", "\n")

if action == ENGINE_CALLBACK_PLUGIN_RENAMED:
self.host._set_pluginName(pluginId, valueStr)
elif action == ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
if value1 < 0:
self.host._set_internalValue(pluginId, value1, valuef)
else:
self.host._set_parameterValue(pluginId, value1, valuef)
elif action == ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED:
self.host._set_parameterDefault(pluginId, value1, valuef)
elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED:
self.host._set_parameterMidiCC(pluginId, value1, value2)
elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
self.host._set_parameterMidiChannel(pluginId, value1, value2)
elif action == ENGINE_CALLBACK_PROGRAM_CHANGED:
self.host._set_currentProgram(pluginId, value1)
elif action == ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED:
self.host._set_currentMidiProgram(pluginId, value1)

self.host._setViaCallback(action, pluginId, value1, value2, value3, valuef, valueStr)
engineCallback(self.host, action, pluginId, value1, value2, value3, valuef, valueStr)

elif msg.startswith("ENGINE_OPTION_"):


Loading…
Cancel
Save