Browse Source

libjack: performance tweaks

tags/1.9.8
falkTX 8 years ago
parent
commit
c08141da8b
2 changed files with 69 additions and 34 deletions
  1. +2
    -2
      source/backend/engine/CarlaEngineBridge.cpp
  2. +67
    -32
      source/libjack/libjack.cpp

+ 2
- 2
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -201,7 +201,7 @@ public:
fShmNonRtServerControl.commitWrite(); fShmNonRtServerControl.commitWrite();
} }


startThread(10);
startThread(Thread::realtimeAudioPriority);


return true; return true;
} }
@@ -1185,7 +1185,7 @@ protected:
std::size_t curMidiDataPos = 0; std::size_t curMidiDataPos = 0;


if (pData->events.in[0].type != kEngineEventTypeNull) if (pData->events.in[0].type != kEngineEventTypeNull)
carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);


if (pData->events.out[0].type != kEngineEventTypeNull) if (pData->events.out[0].type != kEngineEventTypeNull)
{ {


+ 67
- 32
source/libjack/libjack.cpp View File

@@ -21,13 +21,14 @@
#include "CarlaThread.hpp" #include "CarlaThread.hpp"


using juce::FloatVectorOperations; using juce::FloatVectorOperations;
using juce::Thread;
using juce::Time; using juce::Time;


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


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


class CarlaJackRealtimeThread : public CarlaThread
class CarlaJackRealtimeThread : public Thread
{ {
public: public:
struct Callback { struct Callback {
@@ -37,7 +38,7 @@ public:
}; };


CarlaJackRealtimeThread(Callback* const callback) CarlaJackRealtimeThread(Callback* const callback)
: CarlaThread("CarlaJackRealtimeThread"),
: Thread("CarlaJackRealtimeThread"),
fCallback(callback) {} fCallback(callback) {}


protected: protected:
@@ -52,7 +53,7 @@ private:


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


class CarlaJackNonRealtimeThread : public CarlaThread
class CarlaJackNonRealtimeThread : public Thread
{ {
public: public:
struct Callback { struct Callback {
@@ -62,7 +63,7 @@ public:
}; };


CarlaJackNonRealtimeThread(Callback* const callback) CarlaJackNonRealtimeThread(Callback* const callback)
: CarlaThread("CarlaJackNonRealtimeThread"),
: Thread("CarlaJackNonRealtimeThread"),
fCallback(callback) {} fCallback(callback) {}


protected: protected:
@@ -173,7 +174,7 @@ public:


pthread_t getRealtimeThreadId() const noexcept pthread_t getRealtimeThreadId() const noexcept
{ {
return fRealtimeThread.getThreadId();
return (pthread_t)fRealtimeThread.getThreadId();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -413,11 +414,6 @@ bool CarlaJackAppClient::handleRtData()
// location to start of audio outputs (shm buffer) // location to start of audio outputs (shm buffer)
float* const fdataRealOuts = fShmAudioPool.data+(fServer.bufferSize*fNumPorts.audioIns); float* const fdataRealOuts = fShmAudioPool.data+(fServer.bufferSize*fNumPorts.audioIns);


// silence outputs first
if (fNumPorts.audioOuts > 0)
FloatVectorOperations::clear(fdataRealOuts, fServer.bufferSize*fNumPorts.audioOuts);

// see if there's any clients
if (! fClients.isEmpty()) if (! fClients.isEmpty())
{ {
// save tranport for all clients // save tranport for all clients
@@ -447,8 +443,7 @@ bool CarlaJackAppClient::handleRtData()
fServer.position.valid = static_cast<jack_position_bits_t>(0); fServer.position.valid = static_cast<jack_position_bits_t>(0);
} }


// clear audio buffer for unused ports
FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);
int numClientOutputsProcessed = 0;


// now go through each client // now go through each client
for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next()) for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
@@ -456,17 +451,16 @@ bool CarlaJackAppClient::handleRtData()
JackClientState* const jclient(it.getValue(nullptr)); JackClientState* const jclient(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr); CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);


int numClientOutputsProcessed = 0;

const CarlaMutexTryLocker cmtl2(jclient->mutex); const CarlaMutexTryLocker cmtl2(jclient->mutex);


// check if we can process // check if we can process
if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated) if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
{ {
if (fNumPorts.audioOuts > 0)
FloatVectorOperations::clear(fdataRealOuts, fServer.bufferSize*fNumPorts.audioOuts);

if (jclient->deactivated) if (jclient->deactivated)
{
fShmRtClientControl.data->procFlags = 1; fShmRtClientControl.data->procFlags = 1;
}
} }
else else
{ {
@@ -475,6 +469,8 @@ bool CarlaJackAppClient::handleRtData()
float* fdataReal = fShmAudioPool.data; float* fdataReal = fShmAudioPool.data;
// safe temp location for output, mixed down to shm buffer later on // safe temp location for output, mixed down to shm buffer later on
float* fdataCopy = fAudioPoolCopy; float* fdataCopy = fAudioPoolCopy;
// wherever we're using fAudioTmpBuf
bool needsTmpBufClear = false;


// set inputs // set inputs
i = 0; i = 0;
@@ -491,6 +487,7 @@ bool CarlaJackAppClient::handleRtData()
else else
{ {
jport->buffer = fAudioTmpBuf; jport->buffer = fAudioTmpBuf;
needsTmpBufClear = true;
} }
} }
} }
@@ -518,6 +515,7 @@ bool CarlaJackAppClient::handleRtData()
else else
{ {
jport->buffer = fAudioTmpBuf; jport->buffer = fAudioTmpBuf;
needsTmpBufClear = true;
} }
} }
} }
@@ -528,26 +526,45 @@ bool CarlaJackAppClient::handleRtData()
fdataCopy += fServer.bufferSize; fdataCopy += fServer.bufferSize;
} }


if (needsTmpBufClear)
FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);

jclient->processCb(fServer.bufferSize, jclient->processCbPtr); jclient->processCb(fServer.bufferSize, jclient->processCbPtr);


if (fNumPorts.audioOuts > 0) if (fNumPorts.audioOuts > 0)
{ {
++numClientOutputsProcessed;
FloatVectorOperations::add(fdataRealOuts, fdataCopyOuts,
fServer.bufferSize*fNumPorts.audioOuts);
if (++numClientOutputsProcessed == 1)
{
// first client, we can copy stuff over
FloatVectorOperations::copy(fdataRealOuts, fdataCopyOuts,
fServer.bufferSize*fNumPorts.audioOuts);
}
else
{
// subsequent clients, add data (then divide by number of clients later on)
FloatVectorOperations::add(fdataRealOuts, fdataCopyOuts,
fServer.bufferSize*fNumPorts.audioOuts);
}
} }
} }
}


if (numClientOutputsProcessed > 1)
{
FloatVectorOperations::multiply(fdataRealOuts,
1.0f/static_cast<float>(numClientOutputsProcessed),
fServer.bufferSize*fNumPorts.audioOuts);
}
if (numClientOutputsProcessed > 1)
{
// more than 1 client active, need to divide buffers
FloatVectorOperations::multiply(fdataRealOuts,
1.0f/static_cast<float>(numClientOutputsProcessed),
fServer.bufferSize*fNumPorts.audioOuts);
} }
} }
// fClients.isEmpty()
else if (fNumPorts.audioOuts > 0)
{
FloatVectorOperations::clear(fdataRealOuts, fServer.bufferSize*fNumPorts.audioOuts);
}


carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
if (fNumPorts.midiOuts > 0)
carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
} }
else else
{ {
@@ -743,7 +760,7 @@ void CarlaJackAppClient::runRealtimeThread()


bool quitReceived = false; bool quitReceived = false;


for (; ! fRealtimeThread.shouldThreadExit();)
for (; ! fRealtimeThread.threadShouldExit();)
{ {
if (handleRtData()) if (handleRtData())
{ {
@@ -764,20 +781,31 @@ void CarlaJackAppClient::runNonRealtimeThread()
if (! initSharedMemmory()) if (! initSharedMemmory())
return; return;


fRealtimeThread.startThread();
fRealtimeThread.startThread(Thread::realtimeAudioPriority);


fLastPingTime = Time::currentTimeMillis(); fLastPingTime = Time::currentTimeMillis();
carla_stdout("Carla Jack Client Ready!"); carla_stdout("Carla Jack Client Ready!");


bool quitReceived = false;
bool quitReceived = false,
timedOut = false;


for (; ! fNonRealtimeThread.shouldThreadExit();)
for (; ! fNonRealtimeThread.threadShouldExit();)
{ {
carla_msleep(50); carla_msleep(50);


if (handleNonRtData())
try {
quitReceived = handleNonRtData();
} CARLA_SAFE_EXCEPTION("handleNonRtData");

if (quitReceived)
break;

if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000)
{ {
quitReceived = true;
carla_stderr("Did not receive ping message from server for 30 secs, closing...");

timedOut = true;
fRealtimeThread.signalThreadShouldExit();
break; break;
} }
} }
@@ -790,6 +818,13 @@ void CarlaJackAppClient::runNonRealtimeThread()


::kill(::getpid(), SIGTERM); ::kill(::getpid(), SIGTERM);
} }
else if (timedOut)
{
// TODO send shutdown?
carla_stderr("CarlaJackAppClient runNonRealtimeThread END - timedOut");

::kill(::getpid(), SIGTERM);
}
else else
{ {
const char* const message("Plugin bridge error, process thread has stopped"); const char* const message("Plugin bridge error, process thread has stopped");


Loading…
Cancel
Save