From e2320b1fa98a2149c9e19c63eeca8c64d8878467 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 17 Sep 2017 21:12:03 +0200 Subject: [PATCH] More libjack work, a few more apps are working now --- source/backend/plugin/CarlaPluginJack.cpp | 214 ++++++++++++++------- source/interposer/libjack.cpp | 218 +++++++++++++++++----- source/utils/CarlaBridgeDefines.hpp | 3 +- source/utils/CarlaRingBuffer.hpp | 4 +- source/utils/Lv2AtomRingBuffer.hpp | 2 +- 5 files changed, 324 insertions(+), 117 deletions(-) diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index 61a8deaf0..b9b4acd1d 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -20,6 +20,9 @@ #endif #include "CarlaPluginInternal.hpp" +#include "CarlaEngine.hpp" + +#ifdef CARLA_OS_LINUX #include "CarlaBackendUtils.hpp" #include "CarlaBridgeUtils.hpp" @@ -139,7 +142,7 @@ protected: } for (; fProcess->isRunning() && ! shouldThreadExit();) - carla_sleep(1); + carla_msleep(50); // we only get here if bridge crashed or thread asked to exit if (fProcess->isRunning() && shouldThreadExit()) @@ -168,6 +171,10 @@ protected: "Please remove this plugin, and not rely on it from this point."); kEngine->callback(CarlaBackend::ENGINE_CALLBACK_ERROR, kPlugin->getId(), 0, 0, 0.0f, errorString); } + else + { + carla_stderr("CarlaPluginJackThread::run() - bridge closed itself"); + } } fProcess = nullptr; @@ -195,6 +202,7 @@ public: fInitError(false), fTimedOut(false), fTimedError(false), + fProcCanceled(false), fProcWaitTime(0), fLastPongTime(-1), fBridgeThread(engine, this), @@ -231,12 +239,12 @@ public: if (fBridgeThread.isThreadRunning()) { - fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientQuit); - fShmNonRtClientControl.commitWrite(); - fShmRtClientControl.writeOpcode(kPluginBridgeRtClientQuit); fShmRtClientControl.commitWrite(); + fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientQuit); + fShmNonRtClientControl.commitWrite(); + if (! fTimedOut) waitForClient("stopping", 3000); } @@ -374,6 +382,7 @@ public: fTimedOut = true; fTimedError = true; fInitiated = false; + carla_stderr2("Plugin bridge has been stopped or crashed"); pData->engine->callback(ENGINE_CALLBACK_PLUGIN_UNAVAILABLE, pData->id, 0, 0, 0.0f, "Plugin bridge has been stopped or crashed"); } @@ -551,6 +560,11 @@ public: void activate() noexcept override { + if (! fBridgeThread.isThreadRunning()) + { + CARLA_SAFE_ASSERT_RETURN(restartBridgeThread(),); + } + CARLA_SAFE_ASSERT_RETURN(! fTimedError,); { @@ -569,6 +583,9 @@ public: void deactivate() noexcept override { + if (! fBridgeThread.isThreadRunning()) + return; + CARLA_SAFE_ASSERT_RETURN(! fTimedError,); { @@ -590,7 +607,7 @@ public: // -------------------------------------------------------------------------------------------------------- // Check if active - if (fTimedOut || fTimedError || ! pData->active) + if (fProcCanceled || fTimedOut || fTimedError || ! pData->active) { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) @@ -945,6 +962,13 @@ public: return false; } + if (fShmRtClientControl.data->procFlags) + { + carla_stdout("PROC Flags active, disabling plugin"); + fInitiated = false; + fProcCanceled = true; + } + for (uint32_t i=0; i < fInfo.aOuts; ++i) FloatVectorOperations::copy(audioOut[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), iframes); @@ -1329,7 +1353,20 @@ public: break; case kPluginBridgeNonRtServerSaved: + break; + case kPluginBridgeNonRtServerUiClosed: + carla_stdout("bridge closed cleanly?"); + pData->active = false; + +#ifdef HAVE_LIBLO + if (pData->engine->isOscControlRegistered()) + pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, 0.0f); +#endif + + pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_ACTIVE, 0, 0.0f, nullptr); + + fBridgeThread.stopThread(1000); break; case kPluginBridgeNonRtServerError: { @@ -1428,24 +1465,6 @@ public: // --------------------------------------------------------------- - // initial values - fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientNull); - fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeRtClientData))); - fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtClientData))); - fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtServerData))); - - fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetBufferSize); - fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize()); - - fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetSampleRate); - fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate()); - - fShmNonRtClientControl.commitWrite(); - - // testing dummy message - fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull); - fShmRtClientControl.commitWrite(); - // init bridge thread { char shmIdsStr[6*4+1]; @@ -1457,51 +1476,10 @@ public: std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6); fBridgeThread.setData(shmIdsStr); - fBridgeThread.startThread(); } - fInitiated = false; - fLastPongTime = Time::currentTimeMillis(); - CARLA_SAFE_ASSERT(fLastPongTime > 0); - - static bool sFirstInit = true; - - int64_t timeoutEnd = 5000; - - if (sFirstInit) - timeoutEnd *= 2; - sFirstInit = false; - - const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; - - for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();) - { - pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); - - if (needsEngineIdle) - pData->engine->idle(); - - idle(); - - if (fInitiated) - break; - if (pData->engine->isAboutToClose()) - break; - - carla_msleep(20); - } - - fLastPongTime = -1; - - if (fInitError || ! fInitiated) - { - fBridgeThread.stopThread(6000); - - if (! fInitError) - pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)"); - + if (! restartBridgeThread()) return false; - } // --------------------------------------------------------------- // register client @@ -1525,6 +1503,7 @@ private: bool fInitError; bool fTimedOut; bool fTimedError; + bool fProcCanceled; uint fProcWaitTime; int64_t fLastPongTime; @@ -1589,11 +1568,111 @@ private: carla_stderr("waitForClient(%s) timed out", action); } + bool restartBridgeThread() + { + fInitiated = false; + fInitError = false; + fTimedError = false; + + // cleanup of previous data + delete[] fInfo.aInNames; + fInfo.aInNames = nullptr; + + delete[] fInfo.aOutNames; + fInfo.aOutNames = nullptr; + + // reset memory + fProcCanceled = false; + fShmRtClientControl.data->procFlags = 0; + carla_zeroStruct(fShmRtClientControl.data->timeInfo); + carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize); + + fShmRtClientControl.clearData(); + fShmNonRtClientControl.clearData(); + fShmNonRtServerControl.clearData(); + + // initial values + fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientNull); + fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeRtClientData))); + fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtClientData))); + fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtServerData))); + + fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetBufferSize); + fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize()); + + fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetSampleRate); + fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate()); + + fShmNonRtClientControl.commitWrite(); + + if (fShmAudioPool.dataSize != 0) + { + fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool); + fShmRtClientControl.writeULong(static_cast(fShmAudioPool.dataSize)); + fShmRtClientControl.commitWrite(); + } + else + { + // testing dummy message + fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull); + fShmRtClientControl.commitWrite(); + } + + fBridgeThread.startThread(); + + fLastPongTime = Time::currentTimeMillis(); + CARLA_SAFE_ASSERT(fLastPongTime > 0); + + static bool sFirstInit = true; + + int64_t timeoutEnd = 5000; + + if (sFirstInit) + timeoutEnd *= 2; + sFirstInit = false; + + const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; + + for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();) + { + pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); + + if (needsEngineIdle) + pData->engine->idle(); + + idle(); + + if (fInitiated) + break; + if (pData->engine->isAboutToClose()) + break; + + carla_msleep(20); + } + + fLastPongTime = -1; + + if (fInitError || ! fInitiated) + { + fBridgeThread.stopThread(6000); + + if (! fInitError) + pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n" + "(or the plugin crashed on initialization?)"); + + return false; + } + + return true; + } + CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginJack) }; CARLA_BACKEND_END_NAMESPACE +#endif // CARLA_OS_LINUX + // ------------------------------------------------------------------------------------------------------------------- CARLA_BACKEND_START_NAMESPACE @@ -1602,6 +1681,7 @@ CarlaPlugin* CarlaPlugin::newJackApp(const Initializer& init) { carla_debug("CarlaPlugin::newJackApp({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label); +#ifdef CARLA_OS_LINUX CarlaPluginJack* const plugin(new CarlaPluginJack(init.engine, init.id)); if (! plugin->init(init.filename, init.name)) @@ -1611,6 +1691,10 @@ CarlaPlugin* CarlaPlugin::newJackApp(const Initializer& init) } return plugin; +#else + init.engine->setLastError("JACK Application support not available"); + return nullptr; +#endif } CARLA_BACKEND_END_NAMESPACE diff --git a/source/interposer/libjack.cpp b/source/interposer/libjack.cpp index 7ed77f399..1728779ca 100644 --- a/source/interposer/libjack.cpp +++ b/source/interposer/libjack.cpp @@ -67,23 +67,26 @@ struct JackPortState { void* buffer; uint index; uint flags; + bool isSystem; JackPortState() : name(nullptr), fullname(nullptr), buffer(nullptr), index(0), - flags(0) {} + flags(0), + isSystem(false) {} - JackPortState(const char* const n, const uint i, const uint f) - : name(strdup(n)), + JackPortState(const char* const cn, const char* const pn, const uint i, const uint f, const bool sys) + : name(strdup(pn)), fullname(nullptr), buffer(nullptr), index(i), - flags(f) + flags(f), + isSystem(sys) { char strBuf[STR_MAX+1]; - snprintf(strBuf, STR_MAX, "system:%s", n); + snprintf(strBuf, STR_MAX, "%s:%s", cn, pn); strBuf[STR_MAX] = '\0'; fullname = strdup(strBuf); @@ -98,6 +101,7 @@ struct JackPortState { struct JackClientState { bool activated; + bool prematurelyActivated; char* name; @@ -122,6 +126,7 @@ struct JackClientState { JackClientState() : activated(false), + prematurelyActivated(false), name(nullptr), bufferSize(0), sampleRate(0.0), @@ -327,13 +332,15 @@ public: if (fState.audioIns.count() == 0 && fState.audioOuts.count() == 0) { carla_stderr("Create 2 ins, 2 outs prematurely for the client"); - fState.audioIns.append(new JackPortState("in_1", 0, JackPortIsOutput)); - fState.audioIns.append(new JackPortState("in_2", 1, JackPortIsOutput)); + fState.audioIns.append(new JackPortState(fState.name, "in_1", 0, JackPortIsOutput, false)); + fState.audioIns.append(new JackPortState(fState.name, "in_2", 1, JackPortIsOutput, false)); fState.fakeIns = 2; - fState.audioOuts.append(new JackPortState("out_1", 0, JackPortIsInput)); - fState.audioOuts.append(new JackPortState("out_2", 1, JackPortIsInput)); + fState.audioOuts.append(new JackPortState(fState.name, "out_1", 0, JackPortIsInput, false)); + fState.audioOuts.append(new JackPortState(fState.name, "out_2", 1, JackPortIsInput, false)); fState.fakeOuts = 2; + + fState.prematurelyActivated = true; } char bufStr[STR_MAX+1]; @@ -463,7 +470,11 @@ public: { const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed); + fShmNonRtServerControl.commitWrite(); + fState.activated = false; + fState.prematurelyActivated = false; for (LinkedList::Itenerator it = fState.audioIns.begin2(); it.valid(); it.next()) { @@ -663,6 +674,11 @@ protected: if (fAudioOuts > 0) carla_zeroFloats(fdata, fState.bufferSize*fAudioOuts); + + if (! fState.activated) + { + fShmRtClientControl.data->procFlags = 1; + } } else { @@ -730,24 +746,43 @@ protected: } } - carla_stderr("CarlaJackClient run END"); - //callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr); - if (! quitReceived) + if (quitReceived) + { + carla_stderr("CarlaJackClient run END - quit by carla"); + + ::kill(::getpid(), SIGTERM); + } + else { const char* const message("Plugin bridge error, process thread has stopped"); const std::size_t messageSize(std::strlen(message)); - const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); - fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError); - fShmNonRtServerControl.writeUInt(messageSize); - fShmNonRtServerControl.writeCustomData(message, messageSize); - fShmNonRtServerControl.commitWrite(); - } + bool activated; + + { + const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); + activated = fState.activated; + + if (activated) + { + carla_stderr("CarlaJackClient run END - quit error"); + + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError); + fShmNonRtServerControl.writeUInt(messageSize); + fShmNonRtServerControl.writeCustomData(message, messageSize); + fShmNonRtServerControl.commitWrite(); + } + else + { + carla_stderr("CarlaJackClient run END - quit itself"); + } + } - if (fState.shutdown != nullptr) - fState.shutdown(fState.shutdownPtr); + if (activated && fState.shutdown != nullptr) + fState.shutdown(fState.shutdownPtr); + } } private: @@ -779,15 +814,19 @@ CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_USE_NAMESPACE -CarlaJackClient* global_client = nullptr; +static CarlaJackClient* gClient = nullptr; +static int gClientRefCount = 0; CARLA_EXPORT jack_client_t* jack_client_open(const char* client_name, jack_options_t /*options*/, jack_status_t* status, ...) { carla_stdout("CarlaJackClient :: %s", __FUNCTION__); - if (global_client != nullptr) - return (jack_client_t*)global_client; + if (gClient != nullptr) + { + ++gClientRefCount; + return (jack_client_t*)gClient; + } const char* const shmIds(std::getenv("CARLA_SHM_IDS")); @@ -823,7 +862,8 @@ jack_client_t* jack_client_open(const char* client_name, jack_options_t /*option return nullptr; } - global_client = client; + gClient = client; + ++gClientRefCount; return (jack_client_t*)client; } @@ -844,14 +884,14 @@ int jack_client_close(jack_client_t* client) JackClientState& jstate(jclient->fState); if (jstate.activated) - { jclient->deactivate(); - } - - return 0; - jclient->close(); - delete jclient; + if (--gClientRefCount == 0) + { + jclient->close(); + delete jclient; + gClient = nullptr; + } return 0; } @@ -866,9 +906,6 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr); JackClientState& jstate(jclient->fState); - const bool isActivated(jstate.activated); - - //CARLA_SAFE_ASSERT(! isActivated); CARLA_SAFE_ASSERT_RETURN(port_name != nullptr && port_name[0] != '\0', nullptr); CARLA_SAFE_ASSERT_RETURN(port_type != nullptr && port_type[0] != '\0', nullptr); @@ -879,7 +916,7 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co /**/ if (flags & JackPortIsInput) { - if (isActivated) + if (jstate.prematurelyActivated) { CARLA_SAFE_ASSERT_RETURN(jstate.fakeIns > 0, nullptr); jstate.fakeIns -= 1; @@ -888,14 +925,14 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co else { index = jstate.audioIns.count(); - jstate.audioIns.append(new JackPortState(port_name, index, flags)); + jstate.audioIns.append(new JackPortState(jstate.name, port_name, index, flags, false)); } return (jack_port_t*)jstate.audioIns.getAt(index, nullptr); } else if (flags & JackPortIsOutput) { - if (isActivated) + if (jstate.prematurelyActivated) { CARLA_SAFE_ASSERT_RETURN(jstate.fakeOuts > 0, nullptr); jstate.fakeOuts -= 1; @@ -904,7 +941,7 @@ jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, co else { index = jstate.audioOuts.count(); - jstate.audioOuts.append(new JackPortState(port_name, index, flags)); + jstate.audioOuts.append(new JackPortState(jstate.name, port_name, index, flags, false)); } return (jack_port_t*)jstate.audioOuts.getAt(index, nullptr); @@ -928,17 +965,34 @@ int jack_port_unregister(jack_client_t* client, jack_port_t* port) JackPortState* const jport = (JackPortState*)port; CARLA_SAFE_ASSERT_RETURN(jport != nullptr, 1); + CARLA_SAFE_ASSERT_RETURN(! jport->isSystem, 1); JackClientState& jstate(jclient->fState); - CARLA_SAFE_ASSERT_RETURN(! jstate.activated, 1); + //CARLA_SAFE_ASSERT_RETURN(! jstate.activated, 1); if (jport->flags & JackPortIsOutput) { - CARLA_SAFE_ASSERT_RETURN(jstate.audioIns.removeOne(jport), 1); + if (jstate.prematurelyActivated) + { + CARLA_SAFE_ASSERT_RETURN(jstate.fakeIns < 2, 1); + jstate.fakeIns += 1; + } + else + { + CARLA_SAFE_ASSERT_RETURN(jstate.audioIns.removeOne(jport), 1); + } } else { - CARLA_SAFE_ASSERT_RETURN(jstate.audioOuts.removeOne(jport), 1); + if (jstate.prematurelyActivated) + { + CARLA_SAFE_ASSERT_RETURN(jstate.fakeOuts < 2, 1); + jstate.fakeOuts += 1; + } + else + { + CARLA_SAFE_ASSERT_RETURN(jstate.audioOuts.removeOne(jport), 1); + } } return 0; @@ -1014,13 +1068,13 @@ int jack_deactivate(jack_client_t* client) { carla_stdout("CarlaJackClient :: %s", __FUNCTION__); - CarlaJackClient* const jclient = (CarlaJackClient*)client; - CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1); + //CarlaJackClient* const jclient = (CarlaJackClient*)client; + //CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1); - const JackClientState& jstate(jclient->fState); - CARLA_SAFE_ASSERT_RETURN(jstate.activated, 1); + //JackClientState& jstate(jclient->fState); + //CARLA_SAFE_ASSERT_RETURN(jstate.activated, 1); - jclient->deactivate(); + //jclient->deactivate(); return 0; } @@ -1349,6 +1403,14 @@ const char* jack_port_type(const jack_port_t* port) return JACK_DEFAULT_AUDIO_TYPE; } +CARLA_EXPORT +jack_uuid_t jack_port_uuid(const jack_port_t*) +{ + carla_stdout("CarlaJackClient :: %s", __FUNCTION__); + + return 0; +} + CARLA_EXPORT int jack_client_real_time_priority(jack_client_t*) { @@ -1373,6 +1435,14 @@ int jack_disconnect(jack_client_t*, const char*, const char*) return 0; } +CARLA_EXPORT +int jack_port_disconnect(jack_client_t*, jack_port_t*) +{ + carla_stdout("CarlaJackClient :: %s", __FUNCTION__); + + return 0; +} + CARLA_EXPORT const char** jack_get_ports(jack_client_t*, const char* a, const char* b, unsigned long flags) { @@ -1422,10 +1492,55 @@ const char** jack_get_ports(jack_client_t*, const char* a, const char* b, unsign } CARLA_EXPORT -jack_port_t* jack_port_by_name(jack_client_t*, const char*) +jack_port_t* jack_port_by_name(jack_client_t* /*client*/, const char* name) { - carla_stdout("CarlaJackClient :: %s", __FUNCTION__); + carla_stdout("CarlaJackClient :: %s | %s", __FUNCTION__, name); + +// CarlaJackClient* const jclient = (CarlaJackClient*)client; +// CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 0); + +// const JackClientState& jstate(jclient->fState); + //CARLA_SAFE_ASSERT_RETURN(jstate.activated, 0); + + static const JackPortState capturePorts[] = { + JackPortState("system", "capture_1", 0, JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal, true), + JackPortState("system", "capture_2", 1, JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal, true), + }; + static const JackPortState playbackPorts[] = { + JackPortState("system", "playback_1", 3, JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal, true), + JackPortState("system", "playback_2", 4, JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal, true), + }; + if (std::strncmp(name, "system:", 7) == 0) + { + name += 7; + + /**/ if (std::strncmp(name, "capture_", 8) == 0) + { + name += 8; + + const int index = std::atoi(name); + CARLA_SAFE_ASSERT_RETURN(index >= 0 && index < 2, nullptr); + + return (jack_port_t*)&capturePorts[index]; + } + else if (std::strncmp(name, "playback_", 9) == 0) + { + name += 9; + + const int index = std::atoi(name); + CARLA_SAFE_ASSERT_RETURN(index >= 0, nullptr); + + return (jack_port_t*)&playbackPorts[index]; + } + else + { + carla_stderr2("Invalid port short name: '%s'", name); + return nullptr; + } + } + + carla_stderr2("Invalid port name: '%s'", name); return nullptr; } @@ -1511,6 +1626,14 @@ int jack_port_name_size(void) return STR_MAX; } +CARLA_EXPORT +int jack_port_connected(const jack_port_t*) +{ + carla_stdout("CarlaJackClient :: %s", __FUNCTION__); + + return 1; +} + CARLA_EXPORT const char* JACK_METADATA_PRETTY_NAME; @@ -1518,7 +1641,6 @@ CARLA_EXPORT const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name"; // jack_ringbuffer_create -// jack_port_connected // jack_port_is_mine // jack_port_set_name // jack_port_get_all_connections diff --git a/source/utils/CarlaBridgeDefines.hpp b/source/utils/CarlaBridgeDefines.hpp index 2e235e36b..f7de62770 100644 --- a/source/utils/CarlaBridgeDefines.hpp +++ b/source/utils/CarlaBridgeDefines.hpp @@ -138,7 +138,7 @@ struct BridgeTimeInfo { // ------------------------------------------------------------------------------------------------------------------- -static const std::size_t kBridgeRtClientDataMidiOutSize = 512*4; +static const std::size_t kBridgeRtClientDataMidiOutSize = 511*4; // Server => Client RT struct BridgeRtClientData { @@ -146,6 +146,7 @@ struct BridgeRtClientData { BridgeTimeInfo timeInfo; SmallStackBuffer ringBuffer; uint8_t midiOut[kBridgeRtClientDataMidiOutSize]; + uint32_t procFlags; }; // Server => Client Non-RT diff --git a/source/utils/CarlaRingBuffer.hpp b/source/utils/CarlaRingBuffer.hpp index 103576929..00c9b8375 100644 --- a/source/utils/CarlaRingBuffer.hpp +++ b/source/utils/CarlaRingBuffer.hpp @@ -106,7 +106,7 @@ public: // ------------------------------------------------------------------- - void clear() noexcept + void clearData() noexcept { CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); @@ -315,7 +315,7 @@ protected: fBuffer = ringBuf; if (resetBuffer && ringBuf != nullptr) - clear(); + clearData(); } // ------------------------------------------------------------------- diff --git a/source/utils/Lv2AtomRingBuffer.hpp b/source/utils/Lv2AtomRingBuffer.hpp index 1a805892b..2a3bedfce 100644 --- a/source/utils/Lv2AtomRingBuffer.hpp +++ b/source/utils/Lv2AtomRingBuffer.hpp @@ -55,7 +55,7 @@ public: { const CarlaMutexLocker cml(ringBuf.fMutex); fHeapBuffer.copyDataFrom(ringBuf.fHeapBuffer); - ringBuf.clear(); + ringBuf.clearData(); } setRingBuffer(&fHeapBuffer, false);