@@ -1146,6 +1146,7 @@ public: | |||
void oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const noexcept; | |||
void oscSend_bridge_set_chunk_data(const char* const chunkFile) const noexcept; | |||
void oscSend_bridge_set_peaks() const noexcept; | |||
void oscSend_bridge_pong() const noexcept; | |||
#else | |||
public: | |||
void oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept; | |||
@@ -928,7 +928,10 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||
} | |||
if (plugin == nullptr) | |||
{ | |||
pData->plugins[id].plugin = oldPlugin; | |||
return false; | |||
} | |||
plugin->registerToOscClient(); | |||
@@ -2497,6 +2500,19 @@ void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) con | |||
std::strcat(targetPath, "/bridge_set_chunk_data"); | |||
try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); | |||
} | |||
void CarlaEngine::oscSend_bridge_pong() 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_pong()"); | |||
char targetPath[std::strlen(pData->oscData->path)+13]; | |||
std::strcpy(targetPath, pData->oscData->path); | |||
std::strcat(targetPath, "/bridge_pong"); | |||
try_lo_send(pData->oscData->target, targetPath, ""); | |||
} | |||
#else | |||
void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept | |||
{ | |||
@@ -1708,8 +1708,6 @@ private: | |||
if (std::strcmp(clientName, thisClientName) == 0) | |||
{ | |||
carla_stdout("CarlaEngineJack::findPluginIdAndIcon(\"%s\", ...) - found plugin, yes!!!", clientName); | |||
pluginId = static_cast<int>(i); | |||
icon = PATCHBAY_ICON_PLUGIN; | |||
@@ -1731,7 +1729,6 @@ private: | |||
return true; | |||
} | |||
} | |||
carla_stdout("CarlaEngineJack::findPluginIdAndIcon(\"%s\", ...) - nothing here...", clientName); | |||
return false; | |||
} | |||
@@ -147,8 +147,7 @@ void CarlaEngineOsc::close() | |||
// ----------------------------------------------------------------------- | |||
bool isDigit(const char c); | |||
bool isDigit(const char c) | |||
static bool isDigit(const char c) | |||
{ | |||
return (c >= '0' && c <= '9'); | |||
} | |||
@@ -310,10 +309,12 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons | |||
return handleMsgNoteOff(plugin, argc, argv, types); | |||
// Plugin Bridges | |||
if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && std::strlen(method) > 11 && std::strncmp(method, "bridge_", 7) == 0) | |||
if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && std::strlen(method) >= 11 && std::strncmp(method, "bridge_", 7) == 0) | |||
{ | |||
const char* const bmethod(method+7); | |||
if (std::strcmp(bmethod, "pong") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgePong, argc, argv, types); | |||
if (std::strcmp(bmethod, "plugin_info1") == 0) | |||
return CarlaPluginSetOscBridgeInfo(plugin, kPluginBridgePluginInfo1, argc, argv, types); | |||
if (std::strcmp(bmethod, "plugin_info2") == 0) | |||
@@ -41,7 +41,7 @@ CarlaEngineThread::~CarlaEngineThread() | |||
void CarlaEngineThread::run() | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fEngine != nullptr,); | |||
CARLA_ASSERT(fEngine->isRunning()); | |||
CARLA_SAFE_ASSERT(fEngine->isRunning()); | |||
carla_debug("CarlaEngineThread::run()"); | |||
bool hasUi, oscRegisted, needsSingleThread; | |||
@@ -102,7 +102,7 @@ void CarlaEngineThread::run() | |||
} | |||
#ifndef BUILD_BRIDGE | |||
// --------------------------------------------------- | |||
// ------------------------------------------------------- | |||
// Update OSC control client peaks | |||
if (oscRegisted) | |||
@@ -111,6 +111,13 @@ void CarlaEngineThread::run() | |||
} | |||
} | |||
#ifdef BUILD_BRIDGE | |||
// --------------------------------------------------------------- | |||
// Send pong | |||
fEngine->oscSend_bridge_pong(); | |||
#endif | |||
carla_msleep(25); | |||
} | |||
} | |||
@@ -31,6 +31,8 @@ | |||
#include <cmath> | |||
#include <ctime> | |||
#include <QtCore/QString> | |||
#define CARLA_BRIDGE_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ | |||
/* check argument count */ \ | |||
if (argc != argcToCompare) \ | |||
@@ -221,8 +223,8 @@ struct BridgeControl : public RingBufferControl<StackRingBuffer> { | |||
struct BridgeParamInfo { | |||
float value; | |||
CarlaString name; | |||
CarlaString unit; | |||
QString name; | |||
QString unit; | |||
BridgeParamInfo() | |||
: value(0.0f) {} | |||
@@ -244,6 +246,7 @@ public: | |||
fSaved(false), | |||
fNeedsSemDestroy(false), | |||
fTimedOut(false), | |||
fLastPongCounter(-1), | |||
fParams(nullptr) | |||
{ | |||
carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype)); | |||
@@ -383,36 +386,36 @@ public: | |||
void getLabel(char* const strBuf) const noexcept override | |||
{ | |||
std::strncpy(strBuf, (const char*)fInfo.label, STR_MAX); | |||
std::strncpy(strBuf, fInfo.label.getBuffer(), STR_MAX); | |||
} | |||
void getMaker(char* const strBuf) const noexcept override | |||
{ | |||
std::strncpy(strBuf, (const char*)fInfo.maker, STR_MAX); | |||
std::strncpy(strBuf, fInfo.maker.getBuffer(), STR_MAX); | |||
} | |||
void getCopyright(char* const strBuf) const noexcept override | |||
{ | |||
std::strncpy(strBuf, (const char*)fInfo.copyright, STR_MAX); | |||
std::strncpy(strBuf, fInfo.copyright.getBuffer(), STR_MAX); | |||
} | |||
void getRealName(char* const strBuf) const noexcept override | |||
{ | |||
std::strncpy(strBuf, (const char*)fInfo.name, STR_MAX); | |||
std::strncpy(strBuf, fInfo.name.getBuffer(), STR_MAX); | |||
} | |||
void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override | |||
{ | |||
CARLA_ASSERT(parameterId < pData->param.count); | |||
std::strncpy(strBuf, (const char*)fParams[parameterId].name, STR_MAX); | |||
std::strncpy(strBuf, fParams[parameterId].name.toUtf8().constData(), STR_MAX); | |||
} | |||
void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override | |||
{ | |||
CARLA_ASSERT(parameterId < pData->param.count); | |||
std::strncpy(strBuf, (const char*)fParams[parameterId].unit, STR_MAX); | |||
std::strncpy(strBuf, fParams[parameterId].unit.toUtf8().constData(), STR_MAX); | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -1211,15 +1214,17 @@ public: | |||
switch (infoType) | |||
{ | |||
case kPluginBridgeNull: | |||
case kPluginBridgePong: | |||
if (fLastPongCounter > 0) | |||
fLastPongCounter = 0; | |||
break; | |||
case kPluginBridgePluginInfo1: { | |||
CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iih"); | |||
const int32_t category = argv[0]->i; | |||
const int32_t hints = argv[1]->i; | |||
const int64_t uniqueId = argv[2]->h; | |||
const int32_t category = argv[0]->i; | |||
const int32_t hints = argv[1]->i; | |||
const int64_t uniqueId = argv[2]->h; | |||
CARLA_SAFE_ASSERT_BREAK(category >= 0); | |||
CARLA_SAFE_ASSERT_BREAK(hints >= 0); | |||
@@ -1301,7 +1306,7 @@ public: | |||
fParams = nullptr; | |||
} | |||
CARLA_SAFE_ASSERT_INT2(ins+outs < static_cast<int32_t>(pData->engine->getOptions().maxParameters), ins+outs, pData->engine->getOptions().maxParameters); | |||
CARLA_SAFE_ASSERT_INT2(ins+outs <= static_cast<int32_t>(pData->engine->getOptions().maxParameters), ins+outs, pData->engine->getOptions().maxParameters); | |||
const uint32_t count(static_cast<uint32_t>(carla_min<int32_t>(ins+outs, static_cast<int32_t>(pData->engine->getOptions().maxParameters), 0))); | |||
@@ -1784,13 +1789,18 @@ public: | |||
pData->osc.thread.start(); | |||
} | |||
for (int i=0; i < 200; ++i) | |||
fInitiated = false; | |||
fLastPongCounter = 0; | |||
for (; fLastPongCounter < 100; ++fLastPongCounter) | |||
{ | |||
if (fInitiated || ! pData->osc.thread.isRunning()) | |||
break; | |||
carla_msleep(50); | |||
} | |||
fLastPongCounter = -1; | |||
if (fInitError || ! fInitiated) | |||
{ | |||
pData->osc.thread.stop(6000); | |||
@@ -1835,6 +1845,8 @@ private: | |||
bool fNeedsSemDestroy; | |||
bool fTimedOut; | |||
volatile int32_t fLastPongCounter; | |||
CarlaString fBridgeBinary; | |||
BridgeAudioPool fShmAudioPool; | |||
@@ -1945,7 +1957,6 @@ CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||
if (! plugin->init(init.filename, init.name, init.label, nullptr)) | |||
{ | |||
init.engine->registerEnginePlugin(init.id, nullptr); | |||
delete plugin; | |||
return nullptr; | |||
} | |||
@@ -1954,7 +1965,6 @@ CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||
if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) | |||
{ | |||
init.engine->registerEnginePlugin(init.id, nullptr); | |||
init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!"); | |||
delete plugin; | |||
return nullptr; | |||
@@ -198,7 +198,7 @@ public: | |||
if (fWindow != nullptr) | |||
{ | |||
String uiName(pData->name); | |||
uiName += " (JUCE GUI)"; | |||
uiName += " (GUI)"; | |||
fWindow->setName(uiName); | |||
} | |||
} | |||
@@ -233,7 +233,7 @@ public: | |||
if (fWindow == nullptr) | |||
{ | |||
String uiName(pData->name); | |||
uiName += " (JUCE GUI)"; | |||
uiName += " (GUI)"; | |||
fWindow = new JucePluginWindow(); | |||
fWindow->setName(uiName); | |||
@@ -72,7 +72,7 @@ NativePlugin.cpp.o: NativePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | |||
BridgePlugin.cpp.o: BridgePlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_BACKEND_UTILS_HPP) $(CARLA_BRIDGE_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_SHM_UTILS_HPP) $(JACK_BRIDGE_HPP) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | |||
LadspaPlugin.cpp.o: LadspaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LADSPA_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
@@ -2073,6 +2073,9 @@ protected: | |||
} | |||
return ret; | |||
// unused | |||
(void)opt; | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -301,7 +301,7 @@ lv2_atom_forge_raw(LV2_Atom_Forge* forge, const void* data, uint32_t size) | |||
if (forge->sink) { | |||
out = forge->sink(forge->handle, data, size); | |||
} else { | |||
out = (LV2_Atom_Forge_Ref)forge->buf + forge->offset; | |||
out = (LV2_Atom_Forge_Ref)forge->buf + (LV2_Atom_Forge_Ref)forge->offset; | |||
uint8_t* mem = forge->buf + forge->offset; | |||
if (forge->offset + size > forge->size) { | |||
return 0; | |||
@@ -24,7 +24,7 @@ | |||
// ----------------------------------------------------------------------- | |||
enum PluginBridgeInfoType { | |||
kPluginBridgeNull = 0, | |||
kPluginBridgePong = 0, | |||
kPluginBridgePluginInfo1, // uuh => category, hints, uniqueId | |||
kPluginBridgePluginInfo2, // ssss => realName, label, maker, copyright | |||
kPluginBridgeAudioCount, // uu => ins, outs | |||
@@ -94,8 +94,8 @@ const char* PluginBridgeInfoType2str(const PluginBridgeInfoType type) noexcept | |||
{ | |||
switch (type) | |||
{ | |||
case kPluginBridgeNull: | |||
return "kPluginBridgeNull"; | |||
case kPluginBridgePong: | |||
return "kPluginBridgePong"; | |||
case kPluginBridgePluginInfo1: | |||
return "kPluginBridgePluginInfo1"; | |||
case kPluginBridgePluginInfo2: | |||