Browse Source

Start move of bridge code into common classes

tags/1.9.7b
falkTX 7 years ago
parent
commit
ff77cc6ff2
6 changed files with 341 additions and 290 deletions
  1. +7
    -57
      source/backend/engine/CarlaEngineBridge.cpp
  2. +6
    -86
      source/backend/plugin/CarlaPluginBridge.cpp
  3. +2
    -3
      source/bridges-plugin/Makefile
  4. +163
    -0
      source/utils/CarlaBridgeDefines.hpp
  5. +138
    -0
      source/utils/CarlaBridgeUtils.cpp
  6. +25
    -144
      source/utils/CarlaBridgeUtils.hpp

+ 7
- 57
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -51,58 +51,6 @@ CARLA_BACKEND_START_NAMESPACE

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

struct BridgeAudioPool {
CarlaString filename;
float* data;
char shm[64];

BridgeAudioPool() noexcept
: filename(),
data(nullptr)
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

~BridgeAudioPool() noexcept
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

void clear() noexcept
{
filename.clear();

if (! jackbridge_shm_is_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

data = nullptr;

jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

bool attach() noexcept
{
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
};

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

struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
CarlaString filename;
BridgeRtClientData* data;
@@ -417,15 +365,13 @@ public:
fShmRtClientControl(),
fShmNonRtClientControl(),
fShmNonRtServerControl(),
fBaseNameAudioPool(audioPoolBaseName),
fIsOffline(false),
fFirstIdle(true),
fLastPingTime(-1)
{
carla_debug("CarlaEngineBridge::CarlaEngineBridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioPoolBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);

fShmAudioPool.filename = PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL;
fShmAudioPool.filename += audioPoolBaseName;

fShmRtClientControl.filename = PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT;
fShmRtClientControl.filename += rtClientBaseName;

@@ -456,7 +402,7 @@ public:
return false;
}

if (! fShmAudioPool.attach())
if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
{
carla_stderr("Failed to attach to audio pool shared memory");
return false;
@@ -1639,6 +1585,8 @@ private:
BridgeNonRtClientControl fShmNonRtClientControl;
BridgeNonRtServerControl fShmNonRtServerControl;

CarlaString fBaseNameAudioPool;

bool fIsOffline;
bool fFirstIdle;
int64_t fLastPingTime;
@@ -1655,7 +1603,7 @@ CarlaEngine* CarlaEngine::newBridge(const char* const audioPoolBaseName, const c

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

#ifdef BRIDGE_PLUGIN
#ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
CarlaPlugin* CarlaPlugin::newNative(const CarlaPlugin::Initializer&) { return nullptr; }
CarlaPlugin* CarlaPlugin::newFileGIG(const CarlaPlugin::Initializer&, const bool) { return nullptr; }
CarlaPlugin* CarlaPlugin::newFileSF2(const CarlaPlugin::Initializer&, const bool) { return nullptr; }
@@ -1674,4 +1622,6 @@ extern "C" __attribute__ ((visibility("default")))
void carla_register_native_plugin_carla();
void carla_register_native_plugin_carla(){}

#include "CarlaBridgeUtils.cpp"

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

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

@@ -1,6 +1,6 @@
/*
* Carla Plugin Bridge
* Copyright (C) 2011-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,7 +15,7 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#if defined(BUILD_BRIDGE) && defined(BRIDGE_PLUGIN)
#ifdef BUILD_BRIDGE
# error This file should be used under bridge mode
#endif

@@ -51,88 +51,6 @@ static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };

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

struct BridgeAudioPool {
CarlaString filename;
std::size_t size;
float* data;
carla_shm_t shm;

BridgeAudioPool() noexcept
: filename(),
size(0),
data(nullptr)
#ifdef CARLA_PROPER_CPP11_SUPPORT
, shm(carla_shm_t_INIT) {}
#else
{
carla_shm_init(shm);
}
#endif

~BridgeAudioPool() noexcept
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

bool initialize() noexcept
{
char tmpFileBase[64];

std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "XXXXXX");

shm = carla_shm_create_temp(tmpFileBase);

CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm), false);

filename = tmpFileBase;
return true;
}

void clear() noexcept
{
filename.clear();

if (! carla_is_shm_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

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

size = 0;
carla_shm_close(shm);
carla_shm_init(shm);
}

void resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept
{
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),);

if (data != nullptr)
carla_shm_unmap(shm, data);

size = (audioPortCount+cvPortCount)*bufferSize*sizeof(float);

if (size == 0)
size = sizeof(float);

data = (float*)carla_shm_map(shm, size);
std::memset(data, 0, size);
}

CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
};

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

struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
BridgeRtClientData* data;
CarlaString filename;
@@ -2559,7 +2477,7 @@ public:
// ---------------------------------------------------------------
// init sem/shm

if (! fShmAudioPool.initialize())
if (! fShmAudioPool.initializeServer())
{
carla_stderr("Failed to initialize shared memory audio pool");
return false;
@@ -2757,7 +2675,7 @@ private:
fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts, fInfo.cvIns+fInfo.cvOuts);

fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.size));
fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.dataSize));
fShmRtClientControl.commitWrite();

waitForClient("resize-pool", 5000);
@@ -2814,3 +2732,5 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P
CARLA_BACKEND_END_NAMESPACE

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

#include "CarlaBridgeUtils.cpp"

+ 2
- 3
source/bridges-plugin/Makefile View File

@@ -30,8 +30,8 @@ ifeq ($(CARLA_VESTIGE_HEADER),true)
BUILD_CXX_FLAGS += -DVESTIGE_HEADER
endif

32BIT_FLAGS += -DBRIDGE_PLUGIN
64BIT_FLAGS += -DBRIDGE_PLUGIN
32BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH
64BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH

# ----------------------------------------------------------------------------------------------------------------------------

@@ -170,7 +170,6 @@ OBJS_native = \
$(OBJDIR)/CarlaEngineBridge.cpp.o \
$(OBJDIR)/CarlaPlugin.cpp.o \
$(OBJDIR)/CarlaPluginInternal.cpp.o \
$(OBJDIR)/CarlaPluginBridge.cpp.o \
$(OBJDIR)/CarlaPluginNative.cpp.o \
$(OBJDIR)/CarlaPluginLADSPA.cpp.o \
$(OBJDIR)/CarlaPluginDSSI.cpp.o \


+ 163
- 0
source/utils/CarlaBridgeDefines.hpp View File

@@ -0,0 +1,163 @@
/*
* Carla Bridge definitions
* Copyright (C) 2013-2017 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#ifndef CARLA_BRIDGE_DEFINES_HPP_INCLUDED
#define CARLA_BRIDGE_DEFINES_HPP_INCLUDED

#include "CarlaRingBuffer.hpp"

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

// Server sends these to client during RT
enum PluginBridgeRtClientOpcode {
kPluginBridgeRtClientNull = 0,
kPluginBridgeRtClientSetAudioPool, // 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
};

// Server sends these to client during non-RT
enum PluginBridgeNonRtClientOpcode {
kPluginBridgeNonRtClientNull = 0,
kPluginBridgeNonRtClientPing,
kPluginBridgeNonRtClientPingOnOff, // bool
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[]
kPluginBridgeNonRtClientSetChunkDataFile, // uint/size, str[] (filename, base64 content)
kPluginBridgeNonRtClientSetCtrlChannel, // short
kPluginBridgeNonRtClientSetOption, // uint/option, bool
kPluginBridgeNonRtClientPrepareForSave,
kPluginBridgeNonRtClientShowUI,
kPluginBridgeNonRtClientHideUI,
kPluginBridgeNonRtClientUiParameterChange, // uint, float
kPluginBridgeNonRtClientUiProgramChange, // uint
kPluginBridgeNonRtClientUiMidiProgramChange, // uint
kPluginBridgeNonRtClientUiNoteOn, // byte, byte, byte
kPluginBridgeNonRtClientUiNoteOff, // byte, byte
kPluginBridgeNonRtClientQuit
};

// 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
kPluginBridgeNonRtServerCvCount, // uint/ins, uint/outs
kPluginBridgeNonRtServerParameterCount, // uint/count
kPluginBridgeNonRtServerProgramCount, // uint/count
kPluginBridgeNonRtServerMidiProgramCount, // uint/count
kPluginBridgeNonRtServerPortName, // byte/type, uint/index, uint/size, str[] (name)
kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc
kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit)
kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
kPluginBridgeNonRtServerParameterValue, // uint/index, float/value
kPluginBridgeNonRtServerParameterValue2, // uint/index, float/value (used for init/output parameters only, don't resend values)
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)
kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[]
kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename, base64 content)
kPluginBridgeNonRtServerSetLatency, // uint
kPluginBridgeNonRtServerReady,
kPluginBridgeNonRtServerSaved,
kPluginBridgeNonRtServerUiClosed,
kPluginBridgeNonRtServerError // uint/size, str[]
};

// used for kPluginBridgeNonRtServerPortName
enum PluginBridgePortType {
kPluginBridgePortNull = 0,
kPluginBridgePortAudioInput,
kPluginBridgePortAudioOutput,
kPluginBridgePortCvInput,
kPluginBridgePortCvOutput,
kPluginBridgePortMidiInput,
kPluginBridgePortMidiOutput,
kPluginBridgePortTypeCount
};

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

struct BridgeSemaphore {
union {
void* server;
char _padServer[64];
};
union {
void* client;
char _padClient[64];
};
};

// needs to be 64bit aligned
struct BridgeTimeInfo {
uint64_t playing;
uint64_t frame;
uint64_t usecs;
uint32_t valid;
// bbt
int32_t bar, beat, tick;
float beatsPerBar, beatType;
double barStartTick, ticksPerBeat, beatsPerMinute;
};

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

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

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

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

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

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

#endif // CARLA_BRIDGE_DEFINES_HPP_INCLUDED

+ 138
- 0
source/utils/CarlaBridgeUtils.cpp View File

@@ -0,0 +1,138 @@
/*
* Carla Bridge utils
* Copyright (C) 2013-2017 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaBridgeUtils.hpp"

#ifndef BUILD_BRIDGE
# include "CarlaShmUtils.hpp"
#endif

// must be last
#include "jackbridge/JackBridge.hpp"

#if defined(CARLA_OS_WIN) && defined(BUILDING_CARLA_FOR_WINDOWS)
# define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "Global\\carla-bridge_shm_ap_"
# define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "Global\\carla-bridge_shm_rtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "Global\\carla-bridge_shm_nonrtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "Global\\carla-bridge_shm_nonrtS_"
#else
# define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "/crlbrdg_shm_ap_"
# define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "/crlbrdg_shm_rtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "/crlbrdg_shm_nonrtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "/crlbrdg_shm_nonrtS_"
#endif

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

BridgeAudioPool::BridgeAudioPool() noexcept
: data(nullptr),
dataSize(0),
filename()
{
carla_zeroChars(shm, 64);
jackbridge_shm_init(shm);
}

BridgeAudioPool::~BridgeAudioPool() noexcept
{
// should be cleared by now
CARLA_SAFE_ASSERT(data == nullptr);

clear();
}

bool BridgeAudioPool::initializeServer() noexcept
{
#ifndef BUILD_BRIDGE
char tmpFileBase[64];
std::sprintf(tmpFileBase, PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "XXXXXX");

const carla_shm_t shm2 = carla_shm_create_temp(tmpFileBase);
CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm2), false);

void* const shmptr = shm;
carla_shm_t& shm1 = *(carla_shm_t*)shmptr;
carla_copyStruct(shm1, shm2);

filename = tmpFileBase;
return true;
#else
return false;
#endif
}

bool BridgeAudioPool::attachClient(const char* const basename) noexcept
{
CARLA_SAFE_ASSERT_RETURN(basename != nullptr && basename[0] != '\0', false);

#ifdef BUILD_BRIDGE
// must be invalid right now
CARLA_SAFE_ASSERT_RETURN(! jackbridge_shm_is_valid(shm), false);

filename = PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL;
filename += basename;

jackbridge_shm_attach(shm, filename);

return jackbridge_shm_is_valid(shm);
#else
return false;
#endif
}

void BridgeAudioPool::clear() noexcept
{
filename.clear();

if (! jackbridge_shm_is_valid(shm))
{
CARLA_SAFE_ASSERT(data == nullptr);
return;
}

if (data != nullptr)
{
#ifndef BUILD_BRIDGE
jackbridge_shm_unmap(shm, data);
#endif
data = nullptr;
}

dataSize = 0;
jackbridge_shm_close(shm);
jackbridge_shm_init(shm);
}

void BridgeAudioPool::resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept
{
CARLA_SAFE_ASSERT_RETURN(jackbridge_shm_is_valid(shm),);

if (data != nullptr)
jackbridge_shm_unmap(shm, data);

dataSize = (audioPortCount+cvPortCount)*bufferSize*sizeof(float);

if (dataSize == 0)
dataSize = sizeof(float);

data = (float*)jackbridge_shm_map(shm, dataSize);
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);

std::memset(data, 0, dataSize);
}

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

+ 25
- 144
source/utils/CarlaBridgeUtils.hpp View File

@@ -1,6 +1,6 @@
/*
* Carla Bridge utils
* Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2017 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,159 +18,20 @@
#ifndef CARLA_BRIDGE_UTILS_HPP_INCLUDED
#define CARLA_BRIDGE_UTILS_HPP_INCLUDED

#include "CarlaRingBuffer.hpp"
#include "CarlaBridgeDefines.hpp"
#include "CarlaString.hpp"

#if defined(CARLA_OS_WIN) && defined(BUILDING_CARLA_FOR_WINDOWS)
# define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "Global\\carla-bridge_shm_ap_"
# define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "Global\\carla-bridge_shm_rtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "Global\\carla-bridge_shm_nonrtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "Global\\carla-bridge_shm_nonrtS_"
#else
# define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "/crlbrdg_shm_ap_"
# define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "/crlbrdg_shm_rtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "/crlbrdg_shm_nonrtC_"
# define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "/crlbrdg_shm_nonrtS_"
#endif

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

// Server sends these to client during RT
enum PluginBridgeRtClientOpcode {
kPluginBridgeRtClientNull = 0,
kPluginBridgeRtClientSetAudioPool, // 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
};

// Server sends these to client during non-RT
enum PluginBridgeNonRtClientOpcode {
kPluginBridgeNonRtClientNull = 0,
kPluginBridgeNonRtClientPing,
kPluginBridgeNonRtClientPingOnOff, // bool
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[]
kPluginBridgeNonRtClientSetChunkDataFile, // uint/size, str[] (filename, base64 content)
kPluginBridgeNonRtClientSetCtrlChannel, // short
kPluginBridgeNonRtClientSetOption, // uint/option, bool
kPluginBridgeNonRtClientPrepareForSave,
kPluginBridgeNonRtClientShowUI,
kPluginBridgeNonRtClientHideUI,
kPluginBridgeNonRtClientUiParameterChange, // uint, float
kPluginBridgeNonRtClientUiProgramChange, // uint
kPluginBridgeNonRtClientUiMidiProgramChange, // uint
kPluginBridgeNonRtClientUiNoteOn, // byte, byte, byte
kPluginBridgeNonRtClientUiNoteOff, // byte, byte
kPluginBridgeNonRtClientQuit
};

// 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
kPluginBridgeNonRtServerCvCount, // uint/ins, uint/outs
kPluginBridgeNonRtServerParameterCount, // uint/count
kPluginBridgeNonRtServerProgramCount, // uint/count
kPluginBridgeNonRtServerMidiProgramCount, // uint/count
kPluginBridgeNonRtServerPortName, // byte/type, uint/index, uint/size, str[] (name)
kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc
kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit)
kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
kPluginBridgeNonRtServerParameterValue, // uint/index, float/value
kPluginBridgeNonRtServerParameterValue2, // uint/index, float/value (used for init/output parameters only, don't resend values)
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)
kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[]
kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename, base64 content)
kPluginBridgeNonRtServerSetLatency, // uint
kPluginBridgeNonRtServerReady,
kPluginBridgeNonRtServerSaved,
kPluginBridgeNonRtServerUiClosed,
kPluginBridgeNonRtServerError // uint/size, str[]
};

// used for kPluginBridgeNonRtServerPortName
enum PluginBridgePortType {
kPluginBridgePortNull = 0,
kPluginBridgePortAudioInput,
kPluginBridgePortAudioOutput,
kPluginBridgePortCvInput,
kPluginBridgePortCvOutput,
kPluginBridgePortMidiInput,
kPluginBridgePortMidiOutput,
kPluginBridgePortTypeCount
};

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

struct BridgeSemaphore {
union {
void* server;
char _padServer[64];
};
union {
void* client;
char _padClient[64];
};
};

// needs to be 64bit aligned
struct BridgeTimeInfo {
uint64_t playing;
uint64_t frame;
uint64_t usecs;
uint32_t valid;
// bbt
int32_t bar, beat, tick;
float beatsPerBar, beatType;
double barStartTick, ticksPerBeat, beatsPerMinute;
};

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

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

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

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

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

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

static inline
const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode) noexcept
@@ -335,6 +196,26 @@ const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcod
return nullptr;
}

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

struct BridgeAudioPool {
float* data;
std::size_t dataSize;
CarlaString filename;
char shm[64];

BridgeAudioPool() noexcept;
~BridgeAudioPool() noexcept;

bool initializeServer() noexcept;
bool attachClient(const char* const fname) noexcept;
void clear() noexcept;

void resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept;

CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
};

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

#endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED

Loading…
Cancel
Save