Browse Source

Continue plugin-bridge work; Fixes to carla-shm utils

tags/1.9.6
falkTX 10 years ago
parent
commit
81c9a2b296
9 changed files with 359 additions and 386 deletions
  1. +63
    -77
      source/backend/engine/CarlaEngineBridge.cpp
  2. +0
    -8
      source/backend/engine/CarlaEngineOsc.cpp
  3. +6
    -27
      source/backend/plugin/CarlaPluginBridge.cpp
  4. +219
    -212
      source/utils/CarlaBridgeUtils.hpp
  5. +2
    -0
      source/utils/CarlaOscUtils.hpp
  6. +1
    -1
      source/utils/CarlaPipeUtils.cpp
  7. +40
    -34
      source/utils/CarlaRingBuffer.hpp
  8. +24
    -20
      source/utils/CarlaShmUtils.hpp
  9. +4
    -7
      source/utils/Lv2AtomRingBuffer.hpp

+ 63
- 77
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -94,9 +94,9 @@ struct BridgeAudioPool {

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

struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {
struct BridgeRtControl : public CarlaRingBufferControl<SmallStackBuffer> {
CarlaString filename;
BridgeRtData* data;
BridgeRtClientData* data;
char shm[64];

BridgeRtControl() noexcept
@@ -136,7 +136,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map2<BridgeRtData>(shm, data))
if (jackbridge_shm_map2<BridgeRtClientData>(shm, data))
{
CARLA_SAFE_ASSERT(data->midiOut[0] == 0);
setRingBuffer(&data->ringBuffer, false);
@@ -146,9 +146,9 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {
return false;
}

PluginBridgeRtOpcode readOpcode() noexcept
PluginBridgeRtClientOpcode readOpcode() noexcept
{
return static_cast<PluginBridgeRtOpcode>(readInt());
return static_cast<PluginBridgeRtClientOpcode>(readInt());
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtControl)
@@ -156,9 +156,9 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {

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

struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> {
struct BridgeNonRtControl : public CarlaRingBufferControl<BigStackBuffer> {
CarlaString filename;
BridgeNonRtData* data;
BridgeNonRtClientData* data;
char shm[64];

BridgeNonRtControl() noexcept
@@ -198,7 +198,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> {
{
CARLA_SAFE_ASSERT(data == nullptr);

if (jackbridge_shm_map2<BridgeNonRtData>(shm, data))
if (jackbridge_shm_map2<BridgeNonRtClientData>(shm, data))
{
setRingBuffer(&data->ringBuffer, false);
return true;
@@ -207,9 +207,9 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> {
return false;
}

PluginBridgeNonRtOpcode readOpcode() noexcept
PluginBridgeNonRtClientOpcode readOpcode() noexcept
{
return static_cast<PluginBridgeNonRtOpcode>(readInt());
return static_cast<PluginBridgeNonRtClientOpcode>(readInt());
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtControl)
@@ -299,32 +299,32 @@ public:
return false;
}

PluginBridgeNonRtOpcode opcode;
PluginBridgeNonRtClientOpcode opcode;

opcode = fShmNonRtControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtNull, opcode);
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientNull, opcode);

const uint32_t shmRtDataSize = fShmNonRtControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmRtDataSize == sizeof(BridgeRtData), shmRtDataSize, sizeof(BridgeRtData));
CARLA_SAFE_ASSERT_INT2(shmRtDataSize == sizeof(BridgeRtClientData), shmRtDataSize, sizeof(BridgeRtClientData));

const uint32_t shmNonRtDataSize = fShmNonRtControl.readUInt();
CARLA_SAFE_ASSERT_INT2(shmNonRtDataSize == sizeof(BridgeNonRtData), shmNonRtDataSize, sizeof(BridgeNonRtData));
CARLA_SAFE_ASSERT_INT2(shmNonRtDataSize == sizeof(BridgeNonRtClientData), shmNonRtDataSize, sizeof(BridgeNonRtClientData));

opcode = fShmNonRtControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtSetBufferSize, opcode);
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetBufferSize, opcode);
pData->bufferSize = fShmNonRtControl.readUInt();

opcode = fShmNonRtControl.readOpcode();
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtSetSampleRate, opcode);
CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode);
pData->sampleRate = fShmNonRtControl.readDouble();

carla_stdout("Carla Client Info:");
carla_stdout(" BufferSize: %i", pData->bufferSize);
carla_stdout(" SampleRate: %g", pData->sampleRate);
carla_stdout(" sizeof(BridgeRtData): %i/" P_SIZE, shmRtDataSize, sizeof(BridgeRtData));
carla_stdout(" sizeof(BridgeNonRtData): %i/" P_SIZE, shmNonRtDataSize, sizeof(BridgeNonRtData));
carla_stdout(" sizeof(BridgeRtData): %i/" P_SIZE, shmRtDataSize, sizeof(BridgeRtClientData));
carla_stdout(" sizeof(BridgeNonRtData): %i/" P_SIZE, shmNonRtDataSize, sizeof(BridgeNonRtClientData));

if (shmRtDataSize != sizeof(BridgeRtData) || shmNonRtDataSize != sizeof(BridgeNonRtData))
if (shmRtDataSize != sizeof(BridgeRtClientData) || shmNonRtDataSize != sizeof(BridgeNonRtClientData))
return false;

startThread();
@@ -385,59 +385,59 @@ public:
{
for (; fShmNonRtControl.isDataAvailableForReading();)
{
const PluginBridgeNonRtOpcode opcode(fShmNonRtControl.readOpcode());
const PluginBridgeNonRtClientOpcode opcode(fShmNonRtControl.readOpcode());
CarlaPlugin* const plugin(pData->plugins[0].plugin);

#ifdef DEBUG
if (opcode != kPluginBridgeNonRtPing) {
carla_debug("CarlaEngineBridge::handleNonRtData() - got opcode: %s", PluginBridgeNonRtOpcode2str(opcode));
if (opcode != kPluginBridgeNonRtClientPing) {
carla_debug("CarlaEngineBridge::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode));
}
#endif

switch (opcode)
{
case kPluginBridgeNonRtNull:
case kPluginBridgeNonRtClientNull:
break;

case kPluginBridgeNonRtPing:
case kPluginBridgeNonRtClientPing:
oscSend_bridge_pong();
break;

case kPluginBridgeNonRtActivate:
case kPluginBridgeNonRtClientActivate:
if (plugin != nullptr && plugin->isEnabled())
plugin->setActive(true, false, false);
break;

case kPluginBridgeNonRtDeactivate:
case kPluginBridgeNonRtClientDeactivate:
if (plugin != nullptr && plugin->isEnabled())
plugin->setActive(false, false, false);
break;

case kPluginBridgeNonRtSetBufferSize: {
case kPluginBridgeNonRtClientSetBufferSize: {
const uint32_t bufferSize(fShmNonRtControl.readUInt());
pData->bufferSize = bufferSize;
bufferSizeChanged(bufferSize);
break;
}

case kPluginBridgeNonRtSetSampleRate: {
case kPluginBridgeNonRtClientSetSampleRate: {
const double sampleRate(fShmNonRtControl.readDouble());
pData->sampleRate = sampleRate;
sampleRateChanged(sampleRate);
break;
}

case kPluginBridgeNonRtSetOffline:
case kPluginBridgeNonRtClientSetOffline:
fIsOffline = true;
offlineModeChanged(true);
break;

case kPluginBridgeNonRtSetOnline:
case kPluginBridgeNonRtClientSetOnline:
fIsOffline = false;
offlineModeChanged(false);
break;

case kPluginBridgeNonRtSetParameterValue: {
case kPluginBridgeNonRtClientSetParameterValue: {
const uint32_t index(fShmNonRtControl.readUInt());
const float value(fShmNonRtControl.readFloat());

@@ -446,7 +446,7 @@ public:
break;
}

case kPluginBridgeNonRtSetParameterMidiChannel: {
case kPluginBridgeNonRtClientSetParameterMidiChannel: {
const uint32_t index(fShmNonRtControl.readUInt());
const uint8_t channel(fShmNonRtControl.readByte());

@@ -455,7 +455,7 @@ public:
break;
}

case kPluginBridgeNonRtSetParameterMidiCC: {
case kPluginBridgeNonRtClientSetParameterMidiCC: {
const uint32_t index(fShmNonRtControl.readUInt());
const int16_t cc(fShmNonRtControl.readShort());

@@ -464,7 +464,7 @@ public:
break;
}

case kPluginBridgeNonRtSetProgram: {
case kPluginBridgeNonRtClientSetProgram: {
const int32_t index(fShmNonRtControl.readInt());

if (plugin != nullptr && plugin->isEnabled())
@@ -472,7 +472,7 @@ public:
break;
}

case kPluginBridgeNonRtSetMidiProgram: {
case kPluginBridgeNonRtClientSetMidiProgram: {
const int32_t index(fShmNonRtControl.readInt());

if (plugin != nullptr && plugin->isEnabled())
@@ -480,7 +480,7 @@ public:
break;
}

case kPluginBridgeNonRtSetCustomData: {
case kPluginBridgeNonRtClientSetCustomData: {
// type
const uint32_t typeSize(fShmNonRtControl.readUInt());
char typeStr[typeSize+1];
@@ -504,7 +504,7 @@ public:
break;
}

case kPluginBridgeNonRtSetChunkDataFile: {
case kPluginBridgeNonRtClientSetChunkDataFile: {
const uint32_t size(fShmNonRtControl.readUInt());
CARLA_SAFE_ASSERT_BREAK(size > 0);

@@ -535,7 +535,7 @@ public:
break;
}

case kPluginBridgeNonRtSetCtrlChannel: {
case kPluginBridgeNonRtClientSetCtrlChannel: {
const int16_t channel(fShmNonRtControl.readShort());
CARLA_SAFE_ASSERT_BREAK(channel >= -1 && channel < MAX_MIDI_CHANNELS);

@@ -544,21 +544,7 @@ public:
break;
}

case kPluginBridgeNonRtSetOscURL: {
const uint32_t size(fShmNonRtControl.readUInt());

char url[size+1];
carla_zeroChar(url, size+1);
fShmNonRtControl.readCustomData(url, size);

CARLA_SAFE_ASSERT_BREAK(url[0] != '\0');
if (plugin == nullptr || ! plugin->isEnabled()) break;

pData->oscData->setNewURL(url);
break;
}

case kPluginBridgeNonRtSetOption: {
case kPluginBridgeNonRtClientSetOption: {
const uint32_t option(fShmNonRtControl.readUInt());
const bool yesNo(fShmNonRtControl.readBool());

@@ -567,7 +553,7 @@ public:
break;
}

case kPluginBridgeNonRtPrepareForSave: {
case kPluginBridgeNonRtClientPrepareForSave: {
if (plugin == nullptr || ! plugin->isEnabled()) break;

plugin->prepareForSave();
@@ -599,21 +585,21 @@ public:
}
}

oscSend_bridge_configure(CARLA_BRIDGE_MSG_SAVED, "");
//oscSend_bridge_configure(CARLA_BRIDGE_MSG_SAVED, "");
break;
}

case kPluginBridgeNonRtShowUI:
case kPluginBridgeNonRtClientShowUI:
if (plugin != nullptr && plugin->isEnabled())
plugin->showCustomUI(true);
break;

case kPluginBridgeNonRtHideUI:
case kPluginBridgeNonRtClientHideUI:
if (plugin != nullptr && plugin->isEnabled())
plugin->showCustomUI(false);
break;

case kPluginBridgeNonRtUiParameterChange: {
case kPluginBridgeNonRtClientUiParameterChange: {
const uint32_t index(fShmNonRtControl.readUInt());
const float value(fShmNonRtControl.readFloat());

@@ -622,7 +608,7 @@ public:
break;
}

case kPluginBridgeNonRtUiProgramChange: {
case kPluginBridgeNonRtClientUiProgramChange: {
const uint32_t index(fShmNonRtControl.readUInt());

if (plugin != nullptr && plugin->isEnabled())
@@ -630,7 +616,7 @@ public:
break;
}

case kPluginBridgeNonRtUiMidiProgramChange: {
case kPluginBridgeNonRtClientUiMidiProgramChange: {
const uint32_t index(fShmNonRtControl.readUInt());

if (plugin != nullptr && plugin->isEnabled())
@@ -638,7 +624,7 @@ public:
break;
}

case kPluginBridgeNonRtUiNoteOn: {
case kPluginBridgeNonRtClientUiNoteOn: {
const uint8_t chnl(fShmNonRtControl.readByte());
const uint8_t note(fShmNonRtControl.readByte());
const uint8_t velo(fShmNonRtControl.readByte());
@@ -648,7 +634,7 @@ public:
break;
}

case kPluginBridgeNonRtUiNoteOff: {
case kPluginBridgeNonRtClientUiNoteOff: {
const uint8_t chnl(fShmNonRtControl.readByte());
const uint8_t note(fShmNonRtControl.readByte());

@@ -657,7 +643,7 @@ public:
break;
}

case kPluginBridgeNonRtQuit:
case kPluginBridgeNonRtClientQuit:
signalThreadShouldExit();
callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
break;
@@ -683,35 +669,35 @@ protected:

for (; fShmRtControl.isDataAvailableForReading();)
{
const PluginBridgeRtOpcode opcode(fShmRtControl.readOpcode());
const PluginBridgeRtClientOpcode opcode(fShmRtControl.readOpcode());
CarlaPlugin* const plugin(pData->plugins[0].plugin);

#ifdef DEBUG
if (opcode != kPluginBridgeRtProcess && opcode != kPluginBridgeRtMidiEvent) {
carla_debug("CarlaEngineBridgeRtThread::run() - got opcode: %s", PluginBridgeRtOpcode2str(opcode));
if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
carla_debug("CarlaEngineBridgeRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
}
#endif

switch (opcode)
{
case kPluginBridgeRtNull:
case kPluginBridgeRtClientNull:
break;

case kPluginBridgeRtSetAudioPool: {
case kPluginBridgeRtClientSetAudioPool: {
const uint64_t poolSize(fShmRtControl.readULong());
CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
break;
}

case kPluginBridgeRtSetCVPool: {
case kPluginBridgeRtClientSetCVPool: {
const uint64_t poolSize(fShmRtControl.readULong());
CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
//fShmCVPool.data = (float*)jackbridge_shm_map(fShmCVPool.shm, static_cast<size_t>(poolSize));
break;
}

case kPluginBridgeRtControlEventParameter: {
case kPluginBridgeRtClientControlEventParameter: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t channel(fShmRtControl.readByte());
const uint16_t param(fShmRtControl.readUShort());
@@ -729,7 +715,7 @@ protected:
break;
}

case kPluginBridgeRtControlEventMidiBank: {
case kPluginBridgeRtClientControlEventMidiBank: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t channel(fShmRtControl.readByte());
const uint16_t index(fShmRtControl.readUShort());
@@ -746,7 +732,7 @@ protected:
break;
}

case kPluginBridgeRtControlEventMidiProgram: {
case kPluginBridgeRtClientControlEventMidiProgram: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t channel(fShmRtControl.readByte());
const uint16_t index(fShmRtControl.readUShort());
@@ -763,7 +749,7 @@ protected:
break;
}

case kPluginBridgeRtControlEventAllSoundOff: {
case kPluginBridgeRtClientControlEventAllSoundOff: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t channel(fShmRtControl.readByte());

@@ -778,7 +764,7 @@ protected:
}
}

case kPluginBridgeRtControlEventAllNotesOff: {
case kPluginBridgeRtClientControlEventAllNotesOff: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t channel(fShmRtControl.readByte());

@@ -793,7 +779,7 @@ protected:
}
}

case kPluginBridgeRtMidiEvent: {
case kPluginBridgeRtClientMidiEvent: {
const uint32_t time(fShmRtControl.readUInt());
const uint8_t port(fShmRtControl.readByte());
const uint8_t size(fShmRtControl.readByte());
@@ -834,7 +820,7 @@ protected:
break;
}

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

if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(false))
@@ -896,7 +882,7 @@ protected:
break;
}

case kPluginBridgeRtQuit:
case kPluginBridgeRtClientQuit:
signalThreadShouldExit();
break;
}


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

@@ -29,14 +29,6 @@

CARLA_BACKEND_START_NAMESPACE

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------
// Bridge Helper, defined in BridgePlugin.cpp

extern int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeOscInfoType type,
const int argc, const lo_arg* const* const argv, const char* const types);
#endif

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

CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine) noexcept


+ 6
- 27
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -133,7 +133,7 @@ struct BridgeAudioPool {

if (data != nullptr)
{
carla_shm_unmap(shm, data, size);
carla_shm_unmap(shm, data);
data = nullptr;
}

@@ -144,7 +144,7 @@ struct BridgeAudioPool {
void resize(const uint32_t bufferSize, const uint32_t portCount) noexcept
{
if (data != nullptr)
carla_shm_unmap(shm, data, size);
carla_shm_unmap(shm, data);

size = portCount*bufferSize*sizeof(float);

@@ -192,7 +192,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {

if (data != nullptr)
{
carla_shm_unmap(shm, data, sizeof(BridgeRtData));
carla_shm_unmap(shm, data);
data = nullptr;
}

@@ -219,7 +219,7 @@ struct BridgeRtControl : public CarlaRingBuffer<StackBuffer> {
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

carla_shm_unmap(shm, data, sizeof(BridgeRtData));
carla_shm_unmap(shm, data);
data = nullptr;

setRingBuffer(nullptr, false);
@@ -279,7 +279,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> {

if (data != nullptr)
{
carla_shm_unmap(shm, data, sizeof(BridgeNonRtData));
carla_shm_unmap(shm, data);
data = nullptr;
}

@@ -303,7 +303,7 @@ struct BridgeNonRtControl : public CarlaRingBuffer<BigStackBuffer> {
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

carla_shm_unmap(shm, data, sizeof(BridgeNonRtData));
carla_shm_unmap(shm, data);
data = nullptr;

setRingBuffer(nullptr, false);
@@ -2294,27 +2294,6 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P
#endif
}

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------------------------------------------------------
// Bridge Helper

#define bridgePlugin ((BridgePlugin*)plugin)

extern int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeOscInfoType type,
const int argc, const lo_arg* const* const argv, const char* const types);

int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeOscInfoType /*type*/,
const int /*argc*/, const lo_arg* const* const /*argv*/, const char* const /*types*/)
{
CARLA_SAFE_ASSERT(plugin != nullptr && (plugin->getHints() & PLUGIN_IS_BRIDGE) != 0);
return 0;
//return bridgePlugin->setOscPluginBridgeInfo(type, argc, argv, types);
}

#undef bridgePlugin

#endif

CARLA_BACKEND_END_NAMESPACE

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

+ 219
- 212
source/utils/CarlaBridgeUtils.hpp View File

@@ -22,90 +22,84 @@

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

// carla-plugin receives these via osc
enum PluginBridgeOscInfoType {
kPluginBridgeOscNull = 0,
kPluginBridgeOscPong,
kPluginBridgeOscPluginInfo1, // uuuuh => category, hints, optionsAvailable, optionsEnabled, uniqueId
kPluginBridgeOscPluginInfo2, // ssss => realName, label, maker, copyright
kPluginBridgeOscAudioCount, // uu => ins, outs
kPluginBridgeOscMidiCount, // uu => ins, outs
kPluginBridgeOscParameterCount, // uu => ins, outs
kPluginBridgeOscProgramCount, // u => count
kPluginBridgeOscMidiProgramCount, // u => count
kPluginBridgeOscParameterData1, // uiuui => index, rindex, type, hints, cc
kPluginBridgeOscParameterData2, // uss => index, name, unit
kPluginBridgeOscParameterRanges1, // ufff => index, def, min, max
kPluginBridgeOscParameterRanges2, // ufff => index, step, stepSmall, stepLarge
kPluginBridgeOscParameterValue, // uf => index, value
kPluginBridgeOscDefaultValue, // uf => index, value
kPluginBridgeOscCurrentProgram, // i => index
kPluginBridgeOscCurrentMidiProgram, // i => index
kPluginBridgeOscProgramName, // us => index, name
kPluginBridgeOscMidiProgramData, // uuus => index, bank, program, name
kPluginBridgeOscConfigure, // ss => key, value
kPluginBridgeOscSetCustomData, // sss => type, key, value
kPluginBridgeOscSetChunkDataFile, // s => chunkFile
kPluginBridgeOscLatency, // u => value
kPluginBridgeOscReady,
kPluginBridgeOscError
// Server sends these to client during RT
enum PluginBridgeRtClientOpcode {
kPluginBridgeRtClientNull = 0,
kPluginBridgeRtClientSetAudioPool, // ulong/ptr
kPluginBridgeRtClientSetCVPool, // ulong/ptr
kPluginBridgeRtClientControlEventParameter, // uint/frame, byte/chan, ushort, float
kPluginBridgeRtClientControlEventMidiBank, // uint/frame, byte/chan, ushort
kPluginBridgeRtClientControlEventMidiProgram, // uint/frame, byte/chan, ushort
kPluginBridgeRtClientControlEventAllSoundOff, // uint/frame, byte/chan
kPluginBridgeRtClientControlEventAllNotesOff, // uint/frame, byte/chan
kPluginBridgeRtClientMidiEvent, // uint/frame, byte/port, byte/size, byte[]/data
kPluginBridgeRtClientProcess,
kPluginBridgeRtClientQuit
};

// carla-plugin sends these during RT
enum PluginBridgeRtOpcode {
kPluginBridgeRtNull = 0,
kPluginBridgeRtSetAudioPool, // ulong/ptr
kPluginBridgeRtSetCVPool, // ulong/ptr
kPluginBridgeRtControlEventParameter, // uint/frame, byte/chan, ushort, float
kPluginBridgeRtControlEventMidiBank, // uint/frame, byte/chan, ushort
kPluginBridgeRtControlEventMidiProgram, // uint/frame, byte/chan, ushort
kPluginBridgeRtControlEventAllSoundOff, // uint/frame, byte/chan
kPluginBridgeRtControlEventAllNotesOff, // uint/frame, byte/chan
kPluginBridgeRtMidiEvent, // uint/frame, byte/port, byte/size, byte[]/data
kPluginBridgeRtProcess,
kPluginBridgeRtQuit
// Server sends these to client during non-RT
enum PluginBridgeNonRtClientOpcode {
kPluginBridgeNonRtClientNull = 0,
kPluginBridgeNonRtClientPing,
kPluginBridgeNonRtClientActivate,
kPluginBridgeNonRtClientDeactivate,
kPluginBridgeNonRtClientSetBufferSize, // uint
kPluginBridgeNonRtClientSetSampleRate, // double
kPluginBridgeNonRtClientSetOffline,
kPluginBridgeNonRtClientSetOnline,
kPluginBridgeNonRtClientSetParameterValue, // uint, float
kPluginBridgeNonRtClientSetParameterMidiChannel, // uint, byte
kPluginBridgeNonRtClientSetParameterMidiCC, // uint, short
kPluginBridgeNonRtClientSetProgram, // int
kPluginBridgeNonRtClientSetMidiProgram, // int
kPluginBridgeNonRtClientSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[] (compressed)
kPluginBridgeNonRtClientSetChunkDataFile, // uint/size, str[] (filename)
kPluginBridgeNonRtClientSetCtrlChannel, // short
kPluginBridgeNonRtClientSetOption, // uint/option, bool
kPluginBridgeNonRtClientPrepareForSave,
kPluginBridgeNonRtClientShowUI,
kPluginBridgeNonRtClientHideUI,
kPluginBridgeNonRtClientUiParameterChange, // uint, float
kPluginBridgeNonRtClientUiProgramChange, // uint
kPluginBridgeNonRtClientUiMidiProgramChange, // uint
kPluginBridgeNonRtClientUiNoteOn, // byte, byte, byte
kPluginBridgeNonRtClientUiNoteOff, // byte, byte
kPluginBridgeNonRtClientQuit
};

// carla-plugin sends these during non-RT
enum PluginBridgeNonRtOpcode {
kPluginBridgeNonRtNull = 0,
kPluginBridgeNonRtPing,
kPluginBridgeNonRtActivate,
kPluginBridgeNonRtDeactivate,
kPluginBridgeNonRtSetBufferSize, // uint
kPluginBridgeNonRtSetSampleRate, // double
kPluginBridgeNonRtSetOffline,
kPluginBridgeNonRtSetOnline,
kPluginBridgeNonRtSetParameterValue, // uint, float
kPluginBridgeNonRtSetParameterMidiChannel, // uint, byte
kPluginBridgeNonRtSetParameterMidiCC, // uint, short
kPluginBridgeNonRtSetProgram, // int
kPluginBridgeNonRtSetMidiProgram, // int
kPluginBridgeNonRtSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[] TODO plugin
kPluginBridgeNonRtSetChunkDataFile, // uint/size, str[]/file
kPluginBridgeNonRtSetCtrlChannel, // short
kPluginBridgeNonRtSetOscURL, // uint/size, str[]/url
kPluginBridgeNonRtSetOption, // uint/option, bool
kPluginBridgeNonRtPrepareForSave,
kPluginBridgeNonRtShowUI,
kPluginBridgeNonRtHideUI,
kPluginBridgeNonRtUiParameterChange, // uint, float
kPluginBridgeNonRtUiProgramChange, // uint
kPluginBridgeNonRtUiMidiProgramChange, // uint
kPluginBridgeNonRtUiNoteOn, // byte, byte, byte
kPluginBridgeNonRtUiNoteOff, // byte, byte
kPluginBridgeNonRtQuit
// Client sends these to server during non-RT
enum PluginBridgeNonRtServerOpcode {
kPluginBridgeNonRtServerNull = 0,
kPluginBridgeNonRtServerPong,
kPluginBridgeNonRtServerPluginInfo1, // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId
kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright)
kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs
kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs
kPluginBridgeNonRtServerParameterCount, // uint/ins, uint/outs
kPluginBridgeNonRtServerProgramCount, // uint/count
kPluginBridgeNonRtServerMidiProgramCount, // uint/count
kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, int/cc
kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (unit)
kPluginBridgeNonRtServerParameterRanges1, // uint/index, float/def, float/min, float/max
kPluginBridgeNonRtServerParameterRanges2, // uint/index float/step, float/stepSmall, float/stepLarge
kPluginBridgeNonRtServerParameterValue, // uint/index float/value
kPluginBridgeNonRtServerDefaultValue, // uint/index float/value
kPluginBridgeNonRtServerCurrentProgram, // int/index
kPluginBridgeNonRtServerCurrentMidiProgram, // int/index
kPluginBridgeNonRtServerProgramName, // uint/index, uint/size, str[] (name)
kPluginBridgeNonRtServerMidiProgramData, // uint/index, uint/bank, uint/program, uint/size, str[] (name)
kPluginBridgeNonRtServerConfigure, // uint/size, str[], uint/size, str[]
kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[] (compressed)
kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename)
kPluginBridgeNonRtServerSetLatency, // uint
kPluginBridgeNonRtServerReady,
kPluginBridgeNonRtServerSaved,
kPluginBridgeNonRtServerUiClosed,
kPluginBridgeNonRtServerError
};

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

const char* const CARLA_BRIDGE_MSG_HIDE_GUI = "CarlaBridgeHideGUI"; //!< Plugin -> Host configure, tells host GUI is now hidden
const char* const CARLA_BRIDGE_MSG_SAVED = "CarlaBridgeSaved"; //!< Plugin -> Host configure, tells host state is saved

static const std::size_t kBridgeRtDataMidiOutSize = 512*4;

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

struct BridgeSemaphore {
union {
void* server;
@@ -129,175 +123,188 @@ struct BridgeTimeInfo {
double barStartTick, ticksPerBeat, beatsPerMinute;
};

struct BridgeRtData {
// -----------------------------------------------------------------------

static const std::size_t kBridgeRtDataMidiOutSize = 512*4;

// Server => Client RT
struct BridgeRtClientData {
BridgeSemaphore sem;
BridgeTimeInfo timeInfo;
StackBuffer ringBuffer;
SmallStackBuffer ringBuffer;
uint8_t midiOut[kBridgeRtDataMidiOutSize];
};

struct BridgeNonRtData {
// Server => Client Non-RT
struct BridgeNonRtClientData {
BigStackBuffer ringBuffer;
};

// Client => Server Non-RT
struct BridgeNonRtServerData {
HugeStackBuffer ringBuffer;
};

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

static inline
const char* PluginBridgeOscInfoType2str(const PluginBridgeOscInfoType type) noexcept
const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode) noexcept
{
switch (type)
switch (opcode)
{
case kPluginBridgeOscNull:
return "kPluginBridgeOscNull";
case kPluginBridgeOscPong:
return "kPluginBridgeOscPong";
case kPluginBridgeOscPluginInfo1:
return "kPluginBridgeOscPluginInfo1";
case kPluginBridgeOscPluginInfo2:
return "kPluginBridgeOscPluginInfo2";
case kPluginBridgeOscAudioCount:
return "kPluginBridgeOscAudioCount";
case kPluginBridgeOscMidiCount:
return "kPluginBridgeOscMidiCount";
case kPluginBridgeOscParameterCount:
return "kPluginBridgeOscParameterCount";
case kPluginBridgeOscProgramCount:
return "kPluginBridgeOscProgramCount";
case kPluginBridgeOscMidiProgramCount:
return "kPluginBridgeOscMidiProgramCount";
case kPluginBridgeOscParameterData1:
return "kPluginBridgeOscParameterData1";
case kPluginBridgeOscParameterData2:
return "kPluginBridgeOscParameterData2";
case kPluginBridgeOscParameterRanges1:
return "kPluginBridgeOscParameterRanges1";
case kPluginBridgeOscParameterRanges2:
return "kPluginBridgeOscParameterRanges2";
case kPluginBridgeOscParameterValue:
return "kPluginBridgeOscParameterValue";
case kPluginBridgeOscDefaultValue:
return "kPluginBridgeOscDefaultValue";
case kPluginBridgeOscCurrentProgram:
return "kPluginBridgeOscCurrentProgram";
case kPluginBridgeOscCurrentMidiProgram:
return "kPluginBridgeOscCurrentMidiProgram";
case kPluginBridgeOscProgramName:
return "kPluginBridgeOscProgramName";
case kPluginBridgeOscMidiProgramData:
return "kPluginBridgeOscMidiProgramData";
case kPluginBridgeOscConfigure:
return "kPluginBridgeOscConfigure";
case kPluginBridgeOscSetCustomData:
return "kPluginBridgeOscSetCustomData";
case kPluginBridgeOscSetChunkDataFile:
return "kPluginBridgeOscSetChunkDataFile";
case kPluginBridgeOscLatency:
return "kPluginBridgeOscLatency";
case kPluginBridgeOscReady:
return "kPluginBridgeOscReady";
case kPluginBridgeOscError:
return "kPluginBridgeOscError";
case kPluginBridgeRtClientNull:
return "kPluginBridgeRtClientNull";
case kPluginBridgeRtClientSetAudioPool:
return "kPluginBridgeRtClientSetAudioPool";
case kPluginBridgeRtClientSetCVPool:
return "kPluginBridgeRtClientSetCVPool";
case kPluginBridgeRtClientControlEventParameter:
return "kPluginBridgeRtClientControlEventParameter";
case kPluginBridgeRtClientControlEventMidiBank:
return "kPluginBridgeRtClientControlEventMidiBank";
case kPluginBridgeRtClientControlEventMidiProgram:
return "kPluginBridgeRtClientControlEventMidiProgram";
case kPluginBridgeRtClientControlEventAllSoundOff:
return "kPluginBridgeRtClientControlEventAllSoundOff";
case kPluginBridgeRtClientControlEventAllNotesOff:
return "kPluginBridgeRtClientControlEventAllNotesOff";
case kPluginBridgeRtClientMidiEvent:
return "kPluginBridgeRtClientMidiEvent";
case kPluginBridgeRtClientProcess:
return "kPluginBridgeRtClientProcess";
case kPluginBridgeRtClientQuit:
return "kPluginBridgeRtClientQuit";
}

carla_stderr("CarlaBackend::PluginBridgeOscInfoType2str(%i) - invalid type", type);
carla_stderr("CarlaBackend::PluginBridgeRtClientOpcode2str(%i) - invalid opcode", opcode);
return nullptr;
}

static inline
const char* PluginBridgeRtOpcode2str(const PluginBridgeRtOpcode opcode) noexcept
const char* PluginBridgeNonRtClientOpcode2str(const PluginBridgeNonRtClientOpcode opcode) noexcept
{
switch (opcode)
{
case kPluginBridgeRtNull:
return "kPluginBridgeRtNull";
case kPluginBridgeRtSetAudioPool:
return "kPluginBridgeRtSetAudioPool";
case kPluginBridgeRtSetCVPool:
return "kPluginBridgeRtSetCVPool";
case kPluginBridgeRtControlEventParameter:
return "kPluginBridgeRtControlEventParameter";
case kPluginBridgeRtControlEventMidiBank:
return "kPluginBridgeRtControlEventMidiBank";
case kPluginBridgeRtControlEventMidiProgram:
return "kPluginBridgeRtControlEventMidiProgram";
case kPluginBridgeRtControlEventAllSoundOff:
return "kPluginBridgeRtControlEventAllSoundOff";
case kPluginBridgeRtControlEventAllNotesOff:
return "kPluginBridgeRtControlEventAllNotesOff";
case kPluginBridgeRtMidiEvent:
return "kPluginBridgeRtMidiEvent";
case kPluginBridgeRtProcess:
return "kPluginBridgeRtProcess";
case kPluginBridgeRtQuit:
return "kPluginBridgeRtQuit";
case kPluginBridgeNonRtClientNull:
return "kPluginBridgeNonRtClientNull";
case kPluginBridgeNonRtClientPing:
return "kPluginBridgeNonRtClientPing";
case kPluginBridgeNonRtClientActivate:
return "kPluginBridgeNonRtClientActivate";
case kPluginBridgeNonRtClientDeactivate:
return "kPluginBridgeNonRtClientDeactivate";
case kPluginBridgeNonRtClientSetBufferSize:
return "kPluginBridgeNonRtClientSetBufferSize";
case kPluginBridgeNonRtClientSetSampleRate:
return "kPluginBridgeNonRtClientSetSampleRate";
case kPluginBridgeNonRtClientSetOffline:
return "kPluginBridgeNonRtClientSetOffline";
case kPluginBridgeNonRtClientSetOnline:
return "kPluginBridgeNonRtClientSetOnline";
case kPluginBridgeNonRtClientSetParameterValue:
return "kPluginBridgeNonRtClientSetParameterValue";
case kPluginBridgeNonRtClientSetParameterMidiChannel:
return "kPluginBridgeNonRtClientSetParameterMidiChannel";
case kPluginBridgeNonRtClientSetParameterMidiCC:
return "kPluginBridgeNonRtClientSetParameterMidiCC";
case kPluginBridgeNonRtClientSetProgram:
return "kPluginBridgeNonRtClientSetProgram";
case kPluginBridgeNonRtClientSetMidiProgram:
return "kPluginBridgeNonRtClientSetMidiProgram";
case kPluginBridgeNonRtClientSetCustomData:
return "kPluginBridgeNonRtClientSetCustomData";
case kPluginBridgeNonRtClientSetChunkDataFile:
return "kPluginBridgeNonRtClientSetChunkDataFile";
case kPluginBridgeNonRtClientSetCtrlChannel:
return "kPluginBridgeNonRtClientSetCtrlChannel";
case kPluginBridgeNonRtClientSetOption:
return "kPluginBridgeNonRtClientSetOption";
case kPluginBridgeNonRtClientPrepareForSave:
return "kPluginBridgeNonRtClientPrepareForSave";
case kPluginBridgeNonRtClientShowUI:
return "kPluginBridgeNonRtClientShowUI";
case kPluginBridgeNonRtClientHideUI:
return "kPluginBridgeNonRtClientHideUI";
case kPluginBridgeNonRtClientUiParameterChange:
return "kPluginBridgeNonRtClientUiParameterChange";
case kPluginBridgeNonRtClientUiProgramChange:
return "kPluginBridgeNonRtClientUiProgramChange";
case kPluginBridgeNonRtClientUiMidiProgramChange:
return "kPluginBridgeNonRtClientUiMidiProgramChange";
case kPluginBridgeNonRtClientUiNoteOn:
return "kPluginBridgeNonRtClientUiNoteOn";
case kPluginBridgeNonRtClientUiNoteOff:
return "kPluginBridgeNonRtClientUiNoteOff";
case kPluginBridgeNonRtClientQuit:
return "kPluginBridgeNonRtClientQuit";
}

carla_stderr("CarlaBackend::PluginBridgeRtOpcode2str(%i) - invalid opcode", opcode);
carla_stderr("CarlaBackend::PluginBridgeNonRtClientOpcode2str(%i) - invalid opcode", opcode);
return nullptr;
}

static inline
const char* PluginBridgeNonRtOpcode2str(const PluginBridgeNonRtOpcode opcode) noexcept
const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcode opcode) noexcept
{
switch (opcode)
{
case kPluginBridgeNonRtNull:
return "kPluginBridgeNonRtNull";
case kPluginBridgeNonRtPing:
return "kPluginBridgeNonRtPing";
case kPluginBridgeNonRtActivate:
return "kPluginBridgeNonRtActivate";
case kPluginBridgeNonRtDeactivate:
return "kPluginBridgeNonRtDeactivate";
case kPluginBridgeNonRtSetBufferSize:
return "kPluginBridgeNonRtSetBufferSize";
case kPluginBridgeNonRtSetSampleRate:
return "kPluginBridgeNonRtSetSampleRate";
case kPluginBridgeNonRtSetOffline:
return "kPluginBridgeNonRtSetOffline";
case kPluginBridgeNonRtSetOnline:
return "kPluginBridgeNonRtSetOnline";
case kPluginBridgeNonRtSetParameterValue:
return "kPluginBridgeNonRtSetParameterValue";
case kPluginBridgeNonRtSetParameterMidiChannel:
return "kPluginBridgeNonRtSetParameterMidiChannel";
case kPluginBridgeNonRtSetParameterMidiCC:
return "kPluginBridgeNonRtSetParameterMidiCC";
case kPluginBridgeNonRtSetProgram:
return "kPluginBridgeNonRtSetProgram";
case kPluginBridgeNonRtSetMidiProgram:
return "kPluginBridgeNonRtSetMidiProgram";
case kPluginBridgeNonRtSetCustomData:
return "kPluginBridgeNonRtSetCustomData";
case kPluginBridgeNonRtSetChunkDataFile:
return "kPluginBridgeNonRtSetChunkDataFile";
case kPluginBridgeNonRtSetCtrlChannel:
return "kPluginBridgeNonRtSetCtrlChannel";
case kPluginBridgeNonRtSetOscURL:
return "kPluginBridgeNonRtSetOscURL";
case kPluginBridgeNonRtSetOption:
return "kPluginBridgeNonRtSetOption";
case kPluginBridgeNonRtPrepareForSave:
return "kPluginBridgeNonRtPrepareForSave";
case kPluginBridgeNonRtShowUI:
return "kPluginBridgeNonRtShowUI";
case kPluginBridgeNonRtHideUI:
return "kPluginBridgeNonRtHideUI";
case kPluginBridgeNonRtUiParameterChange:
return "kPluginBridgeNonRtUiParameterChange";
case kPluginBridgeNonRtUiProgramChange:
return "kPluginBridgeNonRtUiProgramChange";
case kPluginBridgeNonRtUiMidiProgramChange:
return "kPluginBridgeNonRtUiMidiProgramChange";
case kPluginBridgeNonRtUiNoteOn:
return "kPluginBridgeNonRtUiNoteOn";
case kPluginBridgeNonRtUiNoteOff:
return "kPluginBridgeNonRtUiNoteOff";
case kPluginBridgeNonRtQuit:
return "kPluginBridgeNonRtQuit";
case kPluginBridgeNonRtServerNull:
return "kPluginBridgeNonRtServerNull";
case kPluginBridgeNonRtServerPong:
return "kPluginBridgeNonRtServerPong";
case kPluginBridgeNonRtServerPluginInfo1:
return "kPluginBridgeNonRtServerPluginInfo1";
case kPluginBridgeNonRtServerPluginInfo2:
return "kPluginBridgeNonRtServerPluginInfo2";
case kPluginBridgeNonRtServerAudioCount:
return "kPluginBridgeNonRtServerAudioCount";
case kPluginBridgeNonRtServerMidiCount:
return "kPluginBridgeNonRtServerMidiCount";
case kPluginBridgeNonRtServerParameterCount:
return "kPluginBridgeNonRtServerParameterCount";
case kPluginBridgeNonRtServerProgramCount:
return "kPluginBridgeNonRtServerProgramCount";
case kPluginBridgeNonRtServerMidiProgramCount:
return "kPluginBridgeNonRtServerMidiProgramCount";
case kPluginBridgeNonRtServerParameterData1:
return "kPluginBridgeNonRtServerParameterData1";
case kPluginBridgeNonRtServerParameterData2:
return "kPluginBridgeNonRtServerParameterData2";
case kPluginBridgeNonRtServerParameterRanges1:
return "kPluginBridgeNonRtServerParameterRanges1";
case kPluginBridgeNonRtServerParameterRanges2:
return "kPluginBridgeNonRtServerParameterRanges2";
case kPluginBridgeNonRtServerParameterValue:
return "kPluginBridgeNonRtServerParameterValue";
case kPluginBridgeNonRtServerDefaultValue:
return "kPluginBridgeNonRtServerDefaultValue";
case kPluginBridgeNonRtServerCurrentProgram:
return "kPluginBridgeNonRtServerCurrentProgram";
case kPluginBridgeNonRtServerCurrentMidiProgram:
return "kPluginBridgeNonRtServerCurrentMidiProgram";
case kPluginBridgeNonRtServerProgramName:
return "kPluginBridgeNonRtServerProgramName";
case kPluginBridgeNonRtServerMidiProgramData:
return "kPluginBridgeNonRtServerMidiProgramData";
case kPluginBridgeNonRtServerConfigure:
return "kPluginBridgeNonRtServerConfigure";
case kPluginBridgeNonRtServerSetCustomData:
return "kPluginBridgeNonRtServerSetCustomData";
case kPluginBridgeNonRtServerSetChunkDataFile:
return "kPluginBridgeNonRtServerSetChunkDataFile";
case kPluginBridgeNonRtServerSetLatency:
return "kPluginBridgeNonRtServerSetLatency";
case kPluginBridgeNonRtServerReady:
return "kPluginBridgeNonRtServerReady";
case kPluginBridgeNonRtServerSaved:
return "kPluginBridgeNonRtServerSaved";
case kPluginBridgeNonRtServerUiClosed:
return "kPluginBridgeNonRtServerUiClosed";
case kPluginBridgeNonRtServerError:
return "kPluginBridgeNonRtServerError";
}

carla_stderr("CarlaBackend::PluginBridgeNonRtOpcode2str(%i) - invalid opcode", opcode);
carla_stderr("CarlaBackend::PluginBridgeNonRtServerOpcode2str%i) - invalid opcode", opcode);
return nullptr;
}



+ 2
- 0
source/utils/CarlaOscUtils.hpp View File

@@ -69,6 +69,7 @@ struct CarlaOscData {
}
}

#if 0
void setNewURL(const char* const url)
{
if (path != nullptr)
@@ -93,6 +94,7 @@ struct CarlaOscData {
std::free(host);
std::free(port);
}
#endif

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_STRUCT(CarlaOscData)


+ 1
- 1
source/utils/CarlaPipeUtils.cpp View File

@@ -1053,7 +1053,7 @@ CarlaPipeServer::~CarlaPipeServer() /*noexcept*/
uintptr_t CarlaPipeServer::getPID() const noexcept
{
#ifndef CARLA_OS_WIN
return pData->pid;
return static_cast<uintptr_t>(pData->pid);
#else
return 0;
#endif


+ 40
- 34
source/utils/CarlaRingBuffer.hpp View File

@@ -61,7 +61,7 @@ struct HeapBuffer {
}
};

struct StackBuffer {
struct SmallStackBuffer {
static const uint32_t size = 4096;
uint32_t head, tail, wrtn;
bool invalidateCommit;
@@ -75,6 +75,13 @@ struct BigStackBuffer {
uint8_t buf[size];
};

struct HugeStackBuffer {
static const uint32_t size = 65536;
uint32_t head, tail, wrtn;
bool invalidateCommit;
uint8_t buf[size];
};

#ifdef CARLA_PROPER_CPP11_SUPPORT
# define HeapBuffer_INIT {0, 0, 0, 0, false, nullptr}
# define StackBuffer_INIT {0, 0, 0, false, {0}}
@@ -84,16 +91,16 @@ struct BigStackBuffer {
#endif

// -----------------------------------------------------------------------
// CarlaRingBuffer templated class
// CarlaRingBufferControl templated class

template <class BufferStruct>
class CarlaRingBuffer
class CarlaRingBufferControl
{
public:
CarlaRingBuffer() noexcept
CarlaRingBufferControl() noexcept
: fBuffer(nullptr) {}

virtual ~CarlaRingBuffer() noexcept {}
virtual ~CarlaRingBufferControl() noexcept {}

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

@@ -206,6 +213,7 @@ public:

void readCustomData(void* const data, const uint32_t size) noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size > 0,);

if (! tryRead(data, size))
@@ -256,6 +264,11 @@ public:
tryWrite(&value, sizeof(int64_t));
}

void writeULong(const uint64_t value) noexcept
{
tryWrite(&value, sizeof(uint64_t));
}

void writeFloat(const float value) noexcept
{
tryWrite(&value, sizeof(float));
@@ -266,29 +279,30 @@ public:
tryWrite(&value, sizeof(double));
}

void writeCustomData(const void* const value, const uint32_t size) noexcept
void writeCustomData(const void* const data, const uint32_t size) noexcept
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size > 0,);

tryWrite(value, size);
tryWrite(data, size);
}

template <typename T>
void writeCustomType(const T& value) noexcept
void writeCustomType(const T& type) noexcept
{
tryWrite(&value, sizeof(T));
tryWrite(&type, sizeof(T));
}

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

protected:
void setRingBuffer(BufferStruct* const ringBuf, const bool reset) noexcept
void setRingBuffer(BufferStruct* const ringBuf, const bool resetBuffer) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != ringBuf,);

fBuffer = ringBuf;

if (reset && ringBuf != nullptr)
if (resetBuffer && ringBuf != nullptr)
clear();
}

@@ -338,12 +352,12 @@ protected:
return true;
}

void tryWrite(const void* const buf, const uint32_t size) noexcept
bool tryWrite(const void* const buf, const uint32_t size) noexcept
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
CARLA_SAFE_ASSERT_RETURN(buf != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size > 0,);
CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size,);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(buf != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(size > 0, false);
CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false);

const uint8_t* const bytebuf(static_cast<const uint8_t*>(buf));

@@ -355,7 +369,7 @@ protected:
{
carla_stderr2("CarlaRingBuffer::tryWrite(%p, " P_SIZE "): failed, not enough space", buf, size);
fBuffer->invalidateCommit = true;
return;
return false;
}

uint32_t writeto(wrtn + size);
@@ -376,29 +390,27 @@ protected:
}

fBuffer->wrtn = writeto;
return true;
}

private:
BufferStruct* fBuffer;

CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(CarlaRingBuffer)
CARLA_DECLARE_NON_COPY_CLASS(CarlaRingBufferControl)
};

// -----------------------------------------------------------------------
// CarlaRingBuffer using heap space

class CarlaHeapRingBuffer : public CarlaRingBuffer<HeapBuffer>
class CarlaHeapRingBuffer : public CarlaRingBufferControl<HeapBuffer>
{
public:
CarlaHeapRingBuffer() noexcept
#ifdef CARLA_PROPER_CPP11_SUPPORT
: fHeapBuffer(HeapBuffer_INIT) {}
#else
: fHeapBuffer(HeapBuffer_INIT)
{
carla_zeroStruct(fHeapBuffer);
}
#endif

~CarlaHeapRingBuffer() noexcept override
{
@@ -443,28 +455,22 @@ private:
};

// -----------------------------------------------------------------------
// CarlaRingBuffer using stack space
// CarlaRingBuffer using small stack space

class CarlaStackRingBuffer : public CarlaRingBuffer<StackBuffer>
class CarlaSmallStackRingBuffer : public CarlaRingBufferControl<SmallStackBuffer>
{
public:
CarlaStackRingBuffer() noexcept
#ifdef CARLA_PROPER_CPP11_SUPPORT
CarlaSmallStackRingBuffer() noexcept
: fStackBuffer(StackBuffer_INIT)
{
setRingBuffer(&fStackBuffer, false);
}
#else
{
setRingBuffer(&fStackBuffer, true);
}
#endif

private:
StackBuffer fStackBuffer;
SmallStackBuffer fStackBuffer;

CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(CarlaStackRingBuffer)
CARLA_DECLARE_NON_COPY_CLASS(CarlaSmallStackRingBuffer)
};

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


+ 24
- 20
source/utils/CarlaShmUtils.hpp View File

@@ -26,7 +26,7 @@ struct shm_t { HANDLE shm; HANDLE map; };
#else
# include <fcntl.h>
# include <sys/mman.h>
struct shm_t { int fd; const char* filename; };
struct shm_t { int fd; const char* filename; std::size_t size; };
# define shm_t_INIT {-1, nullptr}
#endif

@@ -39,7 +39,7 @@ struct shm_t { int fd; const char* filename; };
#ifdef CARLA_OS_WIN
static const shm_t gNullCarlaShm = { nullptr, nullptr };
#else
static const shm_t gNullCarlaShm = { -1, nullptr };
static const shm_t gNullCarlaShm = { -1, nullptr, 0 };
#endif

/*
@@ -67,6 +67,7 @@ void carla_shm_init(shm_t& shm) noexcept
#else
shm.fd = -1;
shm.filename = nullptr;
shm.size = 0;
#endif
}

@@ -88,6 +89,7 @@ shm_t carla_shm_create(const char* const filename) noexcept
#else
ret.fd = ::shm_open(filename, O_CREAT|O_EXCL|O_RDWR, 0600);
ret.filename = (ret.fd >= 0) ? carla_strdup_safe(filename) : nullptr;
ret.size = 0;

if (ret.fd >= 0 && ret.filename == nullptr)
{
@@ -122,6 +124,7 @@ shm_t carla_shm_attach(const char* const filename) noexcept
#else
ret.fd = ::shm_open(filename, O_RDWR, 0);
ret.filename = nullptr;
ret.size = 0;
#endif
}
catch(...) {
@@ -171,6 +174,8 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept
CARLA_SAFE_ASSERT_RETURN(size > 0, nullptr);
#ifdef CARLA_OS_WIN
CARLA_SAFE_ASSERT_RETURN(shm.map == nullptr, nullptr);
#else
CARLA_SAFE_ASSERT_RETURN(shm.size == 0, nullptr);
#endif

try {
@@ -178,7 +183,7 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept
const HANDLE map(:CreateFileMapping(shm.shm, nullptr, PAGE_READWRITE, size, size, nullptr));
CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr);

const HANDLE ptr(::MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size));
void* const ptr(::MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size));

if (ptr == nullptr)
{
@@ -196,7 +201,16 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept
CARLA_SAFE_ASSERT_RETURN(ret == 0, nullptr);
}

return ::mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm.fd, 0);
void* const ptr(::mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm.fd, 0));

if (ptr == nullptr)
{
carla_safe_assert("ptr != nullptr", __FILE__, __LINE__);
return nullptr;
}

shm.size = size;
return ptr;
#endif
} CARLA_SAFE_EXCEPTION_RETURN("carla_shm_map", nullptr);
}
@@ -205,13 +219,14 @@ void* carla_shm_map(shm_t& shm, const std::size_t size) noexcept
* Unmap a shared memory object address.
*/
static inline
void carla_shm_unmap(shm_t& shm, void* const ptr, const std::size_t size) noexcept
void carla_shm_unmap(shm_t& shm, void* const ptr) noexcept
{
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),);
CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
CARLA_SAFE_ASSERT_RETURN(size > 0,);
#ifdef CARLA_OS_WIN
CARLA_SAFE_ASSERT_RETURN(shm.map != nullptr,);
#else
CARLA_SAFE_ASSERT_RETURN(shm.size > 0,);
#endif

try {
@@ -222,13 +237,13 @@ void carla_shm_unmap(shm_t& shm, void* const ptr, const std::size_t size) noexce
::UnmapViewOfFile(ptr);
::CloseHandle(map);
#else
const std::size_t size(shm.size);
shm.size = 0;

const int ret(::munmap(ptr, size));
CARLA_SAFE_ASSERT(ret == 0);
#endif
} CARLA_SAFE_EXCEPTION("carla_shm_unmap");

// unused depending on platform
return; (void)shm; (void)size;
}

// -----------------------------------------------------------------------
@@ -255,17 +270,6 @@ bool carla_shm_map(shm_t& shm, T*& value) noexcept
return (value != nullptr);
}

/*
* Unmap a shared memory object address and set it as null.
*/
template<typename T>
static inline
void carla_shm_unmap(shm_t& shm, T*& value) noexcept
{
carla_shm_unmap(shm, value, sizeof(T));
value = nullptr;
}

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

#endif // CARLA_SHM_UTILS_HPP_INCLUDED

+ 4
- 7
source/utils/Lv2AtomRingBuffer.hpp View File

@@ -25,7 +25,7 @@

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

class Lv2AtomRingBuffer : public CarlaRingBuffer<HeapBuffer>
class Lv2AtomRingBuffer : public CarlaRingBufferControl<HeapBuffer>
{
public:
Lv2AtomRingBuffer() noexcept
@@ -33,12 +33,11 @@ public:
fHeapBuffer(HeapBuffer_INIT),
fNeedsDataDelete(true)
#ifdef CARLA_PROPER_CPP11_SUPPORT
, fRetAtom{{0,0}, {0}} {}
#else
, fRetAtom{{0,0}, {0}}
#endif
{
carla_zeroStruct(fHeapBuffer);
}
#endif

Lv2AtomRingBuffer(Lv2AtomRingBuffer& ringBuf, uint8_t buf[]) noexcept
: fMutex(),
@@ -48,9 +47,7 @@ public:
, fRetAtom{{0,0}, {0}}
#endif
{
#ifndef CARLA_PROPER_CPP11_SUPPORT
carla_zeroStruct(fHeapBuffer);
#endif

fHeapBuffer.buf = buf;
fHeapBuffer.size = ringBuf.fHeapBuffer.size;
@@ -208,7 +205,7 @@ private:
HeapBuffer fHeapBuffer;
const bool fNeedsDataDelete;

static const size_t kMaxAtomDataSize = 8192;
static const std::size_t kMaxAtomDataSize = 8192;

struct RetAtom {
LV2_Atom atom;


Loading…
Cancel
Save