Browse Source

libjack: reorder some code

tags/1.9.8
falkTX 7 years ago
parent
commit
ad28a03361
1 changed files with 334 additions and 333 deletions
  1. +334
    -333
      source/libjack/libjack.cpp

+ 334
- 333
source/libjack/libjack.cpp View File

@@ -36,7 +36,6 @@ public:
fServer(this),
fAudioPoolCopy(nullptr),
fAudioTmpBuf(nullptr),
fIsValid(false),
fIsOffline(false),
fLastPingTime(-1)
{
@@ -84,7 +83,6 @@ public:
fLastPingTime = -1;

stopThread(5000);
clear();

const CarlaMutexLocker cms(fRealtimeThreadMutex);

@@ -96,18 +94,6 @@ public:
delete jclient;
}

if (fAudioPoolCopy != nullptr)
{
delete[] fAudioPoolCopy;
fAudioPoolCopy = nullptr;
}

if (fAudioTmpBuf != nullptr)
{
delete[] fAudioTmpBuf;
fAudioTmpBuf = nullptr;
}

fClients.clear();
}

@@ -131,17 +117,18 @@ public:
return true;
}

void clear() noexcept;
bool isValid() const noexcept;

void handleNonRtData();

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

protected:
void run() override;

private:
bool initSharedMemmory();
void clearSharedMemory() noexcept;

bool handleRtData();
void handleNonRtData();

BridgeAudioPool fShmAudioPool;
BridgeRtClientControl fShmRtClientControl;
BridgeNonRtClientControl fShmNonRtClientControl;
@@ -155,7 +142,6 @@ private:
char fBaseNameNonRtClientControl[6+1];
char fBaseNameNonRtServerControl[6+1];

bool fIsValid;
bool fIsOffline;
int64_t fLastPingTime;

@@ -179,7 +165,108 @@ private:

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

void CarlaJackAppClient::clear() noexcept
bool CarlaJackAppClient::initSharedMemmory()
{
if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
{
carla_stderr("Failed to attach to audio pool shared memory");
return false;
}

if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
{
clearSharedMemory();
carla_stderr("Failed to attach to rt client control shared memory");
return false;
}

if (! fShmRtClientControl.mapData())
{
clearSharedMemory();
carla_stderr("Failed to map rt client control shared memory");
return false;
}

if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
{
clearSharedMemory();
carla_stderr("Failed to attach to non-rt client control shared memory");
return false;
}

if (! fShmNonRtClientControl.mapData())
{
clearSharedMemory();
carla_stderr("Failed to map non-rt control client shared memory");
return false;
}

if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
{
clearSharedMemory();
carla_stderr("Failed to attach to non-rt server control shared memory");
return false;
}

if (! fShmNonRtServerControl.mapData())
{
clearSharedMemory();
carla_stderr("Failed to map non-rt control server shared memory");
return false;
}

PluginBridgeNonRtClientOpcode opcode;

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);

const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));

const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));

const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));

if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
{
carla_stderr2("CarlaJackAppClient: data size mismatch");
return false;
}

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
fServer.bufferSize = fShmNonRtClientControl.readUInt();

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
fServer.sampleRate = fShmNonRtClientControl.readDouble();

if (fServer.bufferSize == 0 || carla_isZero(fServer.sampleRate))
{
carla_stderr2("CarlaJackAppClient: invalid empty state");
return false;
}

fAudioTmpBuf = new float[fServer.bufferSize];
FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);

// tell backend we're live
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);

fLastPingTime = Time::currentTimeMillis();
CARLA_SAFE_ASSERT(fLastPingTime > 0);

// ready!
fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
fShmNonRtServerControl.commitWrite();
fShmNonRtServerControl.waitIfDataIsReachingLimit();

return true;
}

void CarlaJackAppClient::clearSharedMemory() noexcept
{
if (fAudioPoolCopy != nullptr)
{
@@ -187,15 +274,232 @@ void CarlaJackAppClient::clear() noexcept
fAudioPoolCopy = nullptr;
}

if (fAudioTmpBuf != nullptr)
{
delete[] fAudioTmpBuf;
fAudioTmpBuf = nullptr;
}

fShmAudioPool.clear();
fShmRtClientControl.clear();
fShmNonRtClientControl.clear();
fShmNonRtServerControl.clear();
}

bool CarlaJackAppClient::isValid() const noexcept
bool CarlaJackAppClient::handleRtData()
{
return fIsValid;
const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);

if (! helper.ok)
return false;

for (; fShmRtClientControl.isDataAvailableForReading();)
{
const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
//#ifdef DEBUG
if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent)
{
carla_stdout("CarlaJackAppClientRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
}
//#endif

switch (opcode)
{
case kPluginBridgeRtClientNull:
break;

case kPluginBridgeRtClientSetAudioPool: {
if (fShmAudioPool.data != nullptr)
{
jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
fShmAudioPool.data = nullptr;
}
if (fAudioPoolCopy != nullptr)
{
delete[] fAudioPoolCopy;
fAudioPoolCopy = nullptr;
}
const uint64_t poolSize(fShmRtClientControl.readULong());
CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
fAudioPoolCopy = new float[poolSize];
break;
}

case kPluginBridgeRtClientControlEventParameter:
case kPluginBridgeRtClientControlEventMidiBank:
case kPluginBridgeRtClientControlEventMidiProgram:
case kPluginBridgeRtClientControlEventAllSoundOff:
case kPluginBridgeRtClientControlEventAllNotesOff:
case kPluginBridgeRtClientMidiEvent:
break;

case kPluginBridgeRtClientProcess: {
CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);

const CarlaMutexTryLocker cmtl(fRealtimeThreadMutex);

if (cmtl.wasLocked())
{
// location to start of audio outputs (shm buffer)
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())
{
// save tranport for all clients
const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

fServer.playing = bridgeTimeInfo.playing;
fServer.position.frame = bridgeTimeInfo.frame;
fServer.position.usecs = bridgeTimeInfo.usecs;

if (bridgeTimeInfo.valid & 0x1 /* kValidBBT */)
{
fServer.position.valid = JackPositionBBT;

fServer.position.bar = bridgeTimeInfo.bar;
fServer.position.beat = bridgeTimeInfo.beat;
fServer.position.tick = bridgeTimeInfo.tick;

fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
fServer.position.beat_type = bridgeTimeInfo.beatType;

fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
}
else
{
fServer.position.valid = static_cast<jack_position_bits_t>(0);
}

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

// now go through each client
for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
{
JackClientState* const jclient(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);

int numClientOutputsProcessed = 0;

const CarlaMutexTryLocker cmtl2(jclient->mutex);

// check if we can process
if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
{
if (jclient->deactivated)
{
fShmRtClientControl.data->procFlags = 1;
}
}
else
{
uint32_t i;
// direct access to shm buffer, used only for inputs
float* fdataReal = fShmAudioPool.data;
// safe temp location for output, mixed down to shm buffer later on
float* fdataCopy = fAudioPoolCopy;

// set inputs
i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next())
{
if (JackPortState* const jport = it.getValue(nullptr))
{
if (i++ < fNumPorts.audioIns)
{
jport->buffer = fdataReal;
fdataReal += fServer.bufferSize;
fdataCopy += fServer.bufferSize;
}
else
{
jport->buffer = fAudioTmpBuf;
}
}
}
// FIXME one single "if"
for (; i++ < fNumPorts.audioIns;)
{
fdataReal += fServer.bufferSize;
fdataCopy += fServer.bufferSize;
}

// location to start of audio outputs
float* const fdataCopyOuts = fdataCopy;

// set ouputs
i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next())
{
if (JackPortState* const jport = it.getValue(nullptr))
{
if (i++ < fNumPorts.audioOuts)
{
jport->buffer = fdataCopy;
fdataCopy += fServer.bufferSize;
}
else
{
jport->buffer = fAudioTmpBuf;
}
}
}
// FIXME one single "if"
for (; i++ < fNumPorts.audioOuts;)
{
FloatVectorOperations::clear(fdataCopy, fServer.bufferSize);
fdataCopy += fServer.bufferSize;
}

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

if (fNumPorts.audioOuts > 0)
{
++numClientOutputsProcessed;
FloatVectorOperations::add(fdataRealOuts, fdataCopyOuts,
fServer.bufferSize*fNumPorts.audioOuts);
}
}

if (numClientOutputsProcessed > 1)
{
FloatVectorOperations::multiply(fdataRealOuts,
1.0f/static_cast<float>(numClientOutputsProcessed),
fServer.bufferSize*fNumPorts.audioOuts);
}
}
}
}
else
{
carla_stderr2("CarlaJackAppClient: fRealtimeThreadMutex tryLock failed");
}

carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
break;
}

case kPluginBridgeRtClientQuit:
return true;
}

//#ifdef DEBUG
if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent)
{
carla_stdout("CarlaJackAppClientRtThread::run() - opcode %s done", PluginBridgeRtClientOpcode2str(opcode));
}
//#endif
}

return false;
}

void CarlaJackAppClient::handleNonRtData()
@@ -357,106 +661,8 @@ void CarlaJackAppClient::handleNonRtData()
void CarlaJackAppClient::run()
{
carla_stderr("CarlaJackAppClient run START");
initSharedMemmory();

if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
{
carla_stderr("Failed to attach to audio pool shared memory");
return;
}

if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
{
clear();
carla_stderr("Failed to attach to rt client control shared memory");
return;
}

if (! fShmRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map rt client control shared memory");
return;
}

if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
{
clear();
carla_stderr("Failed to attach to non-rt client control shared memory");
return;
}

if (! fShmNonRtClientControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control client shared memory");
return;
}

if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
{
clear();
carla_stderr("Failed to attach to non-rt server control shared memory");
return;
}

if (! fShmNonRtServerControl.mapData())
{
clear();
carla_stderr("Failed to map non-rt control server shared memory");
return;
}

PluginBridgeNonRtClientOpcode opcode;

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);

const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));

const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));

const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));

if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
{
carla_stderr2("CarlaJackAppClient: data size mismatch");
return;
}

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
fServer.bufferSize = fShmNonRtClientControl.readUInt();

opcode = fShmNonRtClientControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
fServer.sampleRate = fShmNonRtClientControl.readDouble();

if (fServer.bufferSize == 0 || carla_isZero(fServer.sampleRate))
{
carla_stderr2("CarlaJackAppClient: invalid empty state");
return;
}

fAudioTmpBuf = new float[fServer.bufferSize];
FloatVectorOperations::clear(fAudioTmpBuf, fServer.bufferSize);

// tell backend we're live
{
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);

fLastPingTime = Time::currentTimeMillis();
CARLA_SAFE_ASSERT(fLastPingTime > 0);

// ready!
fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
fShmNonRtServerControl.commitWrite();
fShmNonRtServerControl.waitIfDataIsReachingLimit();
}

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

@@ -467,221 +673,14 @@ void CarlaJackAppClient::run()

bool quitReceived = false;

for (; ! quitReceived && ! threadShouldExit();)
for (; ! threadShouldExit();)
{
handleNonRtData();

const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);

if (! helper.ok)
continue;

for (; fShmRtClientControl.isDataAvailableForReading();)
if (handleRtData())
{
const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
//#ifdef DEBUG
if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent)
{
carla_stdout("CarlaJackAppClientRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
}
//#endif

switch (opcode)
{
case kPluginBridgeRtClientNull:
break;

case kPluginBridgeRtClientSetAudioPool: {
if (fShmAudioPool.data != nullptr)
{
jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
fShmAudioPool.data = nullptr;
}
if (fAudioPoolCopy != nullptr)
{
delete[] fAudioPoolCopy;
fAudioPoolCopy = nullptr;
}
const uint64_t poolSize(fShmRtClientControl.readULong());
CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
fAudioPoolCopy = new float[poolSize];
break;
}

case kPluginBridgeRtClientControlEventParameter:
case kPluginBridgeRtClientControlEventMidiBank:
case kPluginBridgeRtClientControlEventMidiProgram:
case kPluginBridgeRtClientControlEventAllSoundOff:
case kPluginBridgeRtClientControlEventAllNotesOff:
case kPluginBridgeRtClientMidiEvent:
break;

case kPluginBridgeRtClientProcess: {
CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);

const CarlaMutexTryLocker cmtl(fRealtimeThreadMutex);

if (cmtl.wasLocked())
{
// location to start of audio outputs (shm buffer)
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())
{
// save tranport for all clients
const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

fServer.playing = bridgeTimeInfo.playing;
fServer.position.frame = bridgeTimeInfo.frame;
fServer.position.usecs = bridgeTimeInfo.usecs;

if (bridgeTimeInfo.valid & 0x1 /* kValidBBT */)
{
fServer.position.valid = JackPositionBBT;

fServer.position.bar = bridgeTimeInfo.bar;
fServer.position.beat = bridgeTimeInfo.beat;
fServer.position.tick = bridgeTimeInfo.tick;

fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
fServer.position.beat_type = bridgeTimeInfo.beatType;

fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
}
else
{
fServer.position.valid = static_cast<jack_position_bits_t>(0);
}

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

// now go through each client
for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
{
JackClientState* const jclient(it.getValue(nullptr));
CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);

int numClientOutputsProcessed = 0;

const CarlaMutexTryLocker cmtl2(jclient->mutex);

// check if we can process
if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
{
if (jclient->deactivated)
{
fShmRtClientControl.data->procFlags = 1;
}
}
else
{
uint32_t i;
// direct access to shm buffer, used only for inputs
float* fdataReal = fShmAudioPool.data;
// safe temp location for output, mixed down to shm buffer later on
float* fdataCopy = fAudioPoolCopy;

// set inputs
i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next())
{
if (JackPortState* const jport = it.getValue(nullptr))
{
if (i++ < fNumPorts.audioIns)
{
jport->buffer = fdataReal;
fdataReal += fServer.bufferSize;
fdataCopy += fServer.bufferSize;
}
else
{
jport->buffer = fAudioTmpBuf;
}
}
}
// FIXME one single "if"
for (; i++ < fNumPorts.audioIns;)
{
fdataReal += fServer.bufferSize;
fdataCopy += fServer.bufferSize;
}

// location to start of audio outputs
float* const fdataCopyOuts = fdataCopy;

// set ouputs
i = 0;
for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next())
{
if (JackPortState* const jport = it.getValue(nullptr))
{
if (i++ < fNumPorts.audioOuts)
{
jport->buffer = fdataCopy;
fdataCopy += fServer.bufferSize;
}
else
{
jport->buffer = fAudioTmpBuf;
}
}
}
// FIXME one single "if"
for (; i++ < fNumPorts.audioOuts;)
{
FloatVectorOperations::clear(fdataCopy, fServer.bufferSize);
fdataCopy += fServer.bufferSize;
}

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

if (fNumPorts.audioOuts > 0)
{
++numClientOutputsProcessed;
FloatVectorOperations::add(fdataRealOuts, fdataCopyOuts,
fServer.bufferSize*fNumPorts.audioOuts);
}
}

if (numClientOutputsProcessed > 1)
{
FloatVectorOperations::multiply(fdataRealOuts,
1.0f/static_cast<float>(numClientOutputsProcessed),
fServer.bufferSize*fNumPorts.audioOuts);
}
}
}
}
else
{
carla_stderr2("CarlaJackAppClient: fRealtimeThreadMutex tryLock failed");
}

carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
break;
}

case kPluginBridgeRtClientQuit:
quitReceived = true;
signalThreadShouldExit();
break;
}

//#ifdef DEBUG
if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent)
{
carla_stdout("CarlaJackAppClientRtThread::run() - opcode %s done", PluginBridgeRtClientOpcode2str(opcode));
}
//#endif
quitReceived = true;
break;
}
}

@@ -746,6 +745,8 @@ void CarlaJackAppClient::run()
}
*/
}

clearSharedMemory();
}

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


Loading…
Cancel
Save