@@ -348,7 +348,17 @@ struct EngineTimeInfo { | |||
{ | |||
clear(); | |||
} | |||
#endif | |||
void clear() | |||
{ | |||
playing = false; | |||
frame = 0; | |||
usecs = 0; | |||
valid = 0x0; | |||
} | |||
#ifndef DOXYGEN | |||
// quick operator, doesn't check all values | |||
bool operator==(const EngineTimeInfo& timeInfo) const | |||
{ | |||
@@ -366,17 +376,6 @@ struct EngineTimeInfo { | |||
return !operator==(timeInfo); | |||
} | |||
#endif | |||
void clear() | |||
{ | |||
playing = false; | |||
frame = 0; | |||
usecs = 0; | |||
valid = 0x0; | |||
} | |||
#ifndef DOXYGEN | |||
CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(EngineTimeInfo) | |||
#endif | |||
}; | |||
@@ -393,7 +392,7 @@ public: | |||
/*! | |||
* The contructor.\n | |||
* Param \a isInput defines wherever this is an input port or not (output otherwise).\n | |||
* Input/output state and process mode are constant for the lifetime of the port. | |||
* Input/output and process mode are constant for the lifetime of the port. | |||
*/ | |||
CarlaEnginePort(const bool isInput, const ProcessMode processMode); | |||
@@ -501,16 +500,11 @@ public: | |||
*/ | |||
virtual void initBuffer(CarlaEngine* const engine) override; | |||
/*! | |||
* Clear the port's internal buffer. | |||
*/ | |||
virtual void clearBuffer(); | |||
/*! | |||
* Get the number of events present in the buffer. | |||
* \note You must only call this for input ports. | |||
*/ | |||
virtual uint32_t getEventCount(); | |||
virtual uint32_t getEventCount() const; | |||
/*! | |||
* Get the event at \a index. | |||
@@ -558,8 +552,7 @@ public: | |||
#ifndef DOXYGEN | |||
private: | |||
const uint32_t kMaxEventCount; | |||
EngineEvent* fBuffer; | |||
EngineEvent* fBuffer; | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineEventPort) | |||
#endif | |||
@@ -1068,10 +1061,10 @@ protected: | |||
*/ | |||
void setPeaks(const unsigned int pluginId, float const inPeaks[MAX_PEAKS], float const outPeaks[MAX_PEAKS]); | |||
# ifndef BUILD_BRIDGE | |||
// Rack mode data | |||
EngineEvent* getRackEventBuffer(const bool isInput); | |||
// Internal data, used in Rack and Bridge modes | |||
EngineEvent* getInternalEventBuffer(const bool isInput) const; | |||
# ifndef BUILD_BRIDGE | |||
/*! | |||
* Proccess audio buffer in rack mode. | |||
*/ | |||
@@ -849,9 +849,6 @@ protected: | |||
// ------------------------------------------------------------------- | |||
// Helper classes | |||
// Get default event input port | |||
virtual CarlaEngineEventPort* getDefaultEventInPort() const; | |||
// Fully disable plugin in scope and also its engine client | |||
// May wait-block on constructor for plugin process to end | |||
class ScopedDisabler | |||
@@ -114,20 +114,19 @@ void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | |||
CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode) | |||
: CarlaEnginePort(isInput, processMode), | |||
kMaxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? RACK_EVENT_COUNT : PATCHBAY_EVENT_COUNT), | |||
fBuffer(nullptr) | |||
{ | |||
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) | |||
fBuffer = new EngineEvent[kMaxEventCount]; | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
fBuffer = new EngineEvent[INTERNAL_EVENT_COUNT]; | |||
} | |||
CarlaEngineEventPort::~CarlaEngineEventPort() | |||
{ | |||
carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
@@ -141,67 +140,58 @@ void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine) | |||
CARLA_ASSERT(engine != nullptr); | |||
if (engine == nullptr) | |||
{ | |||
fBuffer = nullptr; | |||
return; | |||
} | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
fBuffer = engine->getRackEventBuffer(kIsInput); | |||
else | |||
#endif | |||
if ((kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) && ! kIsInput) | |||
carla_zeroStruct<EngineEvent>(fBuffer, kMaxEventCount); | |||
} | |||
void CarlaEngineEventPort::clearBuffer() | |||
{ | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
if (fBuffer == nullptr) | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_BRIDGE) | |||
{ | |||
fBuffer = engine->getInternalEventBuffer(kIsInput); | |||
return; | |||
} | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) | |||
carla_zeroStruct<EngineEvent>(fBuffer, kMaxEventCount); | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) | |||
carla_zeroStruct<EngineEvent>(fBuffer, INTERNAL_EVENT_COUNT); | |||
} | |||
uint32_t CarlaEngineEventPort::getEventCount() | |||
uint32_t CarlaEngineEventPort::getEventCount() const | |||
{ | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE); | |||
CARLA_ASSERT(kProcessMode != PROCESS_MODE_SINGLE_CLIENT && kProcessMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
if (! kIsInput) | |||
return 0; | |||
if (fBuffer == nullptr) | |||
return 0; | |||
if (kProcessMode != PROCESS_MODE_CONTINUOUS_RACK && kProcessMode != PROCESS_MODE_PATCHBAY && kProcessMode != PROCESS_MODE_BRIDGE) | |||
if (kProcessMode == PROCESS_MODE_SINGLE_CLIENT || kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
return 0; | |||
uint32_t count = 0; | |||
const EngineEvent* const events = fBuffer; | |||
for (uint32_t i=0; i < kMaxEventCount; ++i, ++count) | |||
for (uint32_t i=0; i < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
if (events[i].type == kEngineEventTypeNull) | |||
break; | |||
if (fBuffer[i].type == kEngineEventTypeNull) | |||
return i; | |||
} | |||
return count; | |||
CARLA_ASSERT(false); // should never happen | |||
return 0; | |||
} | |||
const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) | |||
{ | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE); | |||
CARLA_ASSERT(index < kMaxEventCount); | |||
CARLA_ASSERT(kProcessMode != PROCESS_MODE_SINGLE_CLIENT && kProcessMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
CARLA_ASSERT(index < INTERNAL_EVENT_COUNT); | |||
if (! kIsInput) | |||
return kFallbackEngineEvent; | |||
if (fBuffer == nullptr) | |||
return kFallbackEngineEvent; | |||
if (kProcessMode != PROCESS_MODE_CONTINUOUS_RACK && kProcessMode != PROCESS_MODE_PATCHBAY && kProcessMode != PROCESS_MODE_BRIDGE) | |||
if (kProcessMode == PROCESS_MODE_SINGLE_CLIENT || kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
return kFallbackEngineEvent; | |||
if (index >= kMaxEventCount) | |||
if (index >= INTERNAL_EVENT_COUNT) | |||
return kFallbackEngineEvent; | |||
return fBuffer[index]; | |||
@@ -211,7 +201,7 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
{ | |||
CARLA_ASSERT(! kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE); | |||
CARLA_ASSERT(kProcessMode != PROCESS_MODE_SINGLE_CLIENT && kProcessMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
CARLA_ASSERT(type != kEngineControlEventTypeNull); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); | |||
@@ -220,7 +210,7 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
return; | |||
if (fBuffer == nullptr) | |||
return; | |||
if (kProcessMode != PROCESS_MODE_CONTINUOUS_RACK && kProcessMode != PROCESS_MODE_PATCHBAY && kProcessMode != PROCESS_MODE_BRIDGE) | |||
if (kProcessMode == PROCESS_MODE_SINGLE_CLIENT || kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
return; | |||
if (type == kEngineControlEventTypeNull) | |||
return; | |||
@@ -231,7 +221,7 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); | |||
} | |||
for (uint32_t i=0; i < kMaxEventCount; ++i) | |||
for (uint32_t i=0; i < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
if (fBuffer[i].type != kEngineEventTypeNull) | |||
continue; | |||
@@ -243,7 +233,6 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
fBuffer[i].ctrl.type = type; | |||
fBuffer[i].ctrl.param = param; | |||
fBuffer[i].ctrl.value = carla_fixValue<float>(0.0f, 1.0f, value); | |||
return; | |||
} | |||
@@ -252,33 +241,27 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size) | |||
{ | |||
#ifndef BUILD_BRIDGE | |||
CARLA_ASSERT(! kIsInput); | |||
#endif | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE); | |||
CARLA_ASSERT(kProcessMode != PROCESS_MODE_SINGLE_CLIENT && kProcessMode != PROCESS_MODE_MULTIPLE_CLIENTS); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_ASSERT(data != nullptr); | |||
CARLA_ASSERT(size > 0); | |||
#ifndef BUILD_BRIDGE | |||
if (kIsInput) | |||
return; | |||
#endif | |||
if (fBuffer == nullptr) | |||
return; | |||
if (kProcessMode != PROCESS_MODE_CONTINUOUS_RACK && kProcessMode != PROCESS_MODE_PATCHBAY && kProcessMode != PROCESS_MODE_BRIDGE) | |||
if (kProcessMode == PROCESS_MODE_SINGLE_CLIENT || kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
return; | |||
if (channel >= MAX_MIDI_CHANNELS) | |||
return; | |||
if (data == nullptr) | |||
return; | |||
if (size == 0) | |||
return; | |||
if (size > 4) | |||
if (size == 0 || size > 4) | |||
return; | |||
for (uint32_t i=0; i < kMaxEventCount; ++i) | |||
for (uint32_t i=0; i < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
if (fBuffer[i].type != kEngineEventTypeNull) | |||
continue; | |||
@@ -292,6 +275,8 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
carla_copy<uint8_t>(fBuffer[i].midi.data, data, size); | |||
// strip MIDI channel from 1st byte | |||
fBuffer[i].midi.data[0] = MIDI_GET_STATUS_FROM_DATA(fBuffer[i].midi.data); | |||
return; | |||
} | |||
@@ -615,13 +600,12 @@ unsigned int CarlaEngine::maxPluginNumber() const | |||
bool CarlaEngine::init(const char* const clientName) | |||
{ | |||
CARLA_ASSERT(kData->oscData == nullptr); | |||
CARLA_ASSERT(kData->plugins == nullptr); | |||
carla_debug("CarlaEngine::init(\"%s\")", clientName); | |||
#ifndef BUILD_BRIDGE | |||
CARLA_ASSERT(kData->rack.in == nullptr); | |||
CARLA_ASSERT(kData->rack.out == nullptr); | |||
#endif | |||
CARLA_ASSERT(kData->bufEvent.in == nullptr); | |||
CARLA_ASSERT(kData->bufEvent.out == nullptr); | |||
fName = clientName; | |||
fName.toBasic(); | |||
@@ -630,25 +614,31 @@ bool CarlaEngine::init(const char* const clientName) | |||
kData->aboutToClose = false; | |||
kData->curPluginCount = 0; | |||
kData->maxPluginNumber = 0; | |||
#ifdef BUILD_BRIDGE | |||
kData->maxPluginNumber = 1; | |||
#else | |||
switch (fOptions.processMode) | |||
{ | |||
case PROCESS_MODE_SINGLE_CLIENT: | |||
case PROCESS_MODE_MULTIPLE_CLIENTS: | |||
kData->maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||
break; | |||
case PROCESS_MODE_CONTINUOUS_RACK: | |||
kData->maxPluginNumber = MAX_RACK_PLUGINS; | |||
kData->rack.in = new EngineEvent[RACK_EVENT_COUNT]; | |||
kData->rack.out = new EngineEvent[RACK_EVENT_COUNT]; | |||
kData->bufEvent.in = new EngineEvent[INTERNAL_EVENT_COUNT]; | |||
kData->bufEvent.out = new EngineEvent[INTERNAL_EVENT_COUNT]; | |||
break; | |||
case PROCESS_MODE_PATCHBAY: | |||
kData->maxPluginNumber = MAX_PATCHBAY_PLUGINS; | |||
break; | |||
default: | |||
kData->maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||
case PROCESS_MODE_BRIDGE: | |||
kData->maxPluginNumber = 1; | |||
kData->bufEvent.in = new EngineEvent[INTERNAL_EVENT_COUNT]; | |||
kData->bufEvent.out = new EngineEvent[INTERNAL_EVENT_COUNT]; | |||
break; | |||
} | |||
#endif | |||
kData->plugins = new EnginePluginData[kData->maxPluginNumber]; | |||
@@ -656,14 +646,10 @@ bool CarlaEngine::init(const char* const clientName) | |||
#ifndef BUILD_BRIDGE | |||
kData->oscData = kData->osc.getControlData(); | |||
#else | |||
kData->oscData = nullptr; // set later in setOscBridgeData() | |||
#endif | |||
#ifndef BUILD_BRIDGE | |||
if (type() != kEngineTypePlugin) | |||
carla_setprocname(clientName); | |||
#endif | |||
kData->nextAction.ready(); | |||
kData->thread.startNow(); | |||
@@ -696,19 +682,17 @@ bool CarlaEngine::close() | |||
kData->plugins = nullptr; | |||
} | |||
#ifndef BUILD_BRIDGE | |||
if (kData->rack.in != nullptr) | |||
if (kData->bufEvent.in != nullptr) | |||
{ | |||
delete[] kData->rack.in; | |||
kData->rack.in = nullptr; | |||
delete[] kData->bufEvent.in; | |||
kData->bufEvent.in = nullptr; | |||
} | |||
if (kData->rack.out != nullptr) | |||
if (kData->bufEvent.out != nullptr) | |||
{ | |||
delete[] kData->rack.out; | |||
kData->rack.out = nullptr; | |||
delete[] kData->bufEvent.out; | |||
kData->bufEvent.out = nullptr; | |||
} | |||
#endif | |||
fName.clear(); | |||
@@ -1800,12 +1784,12 @@ void CarlaEngine::setPeaks(const unsigned int pluginId, float const inPeaks[MAX_ | |||
kData->plugins[pluginId].outsPeak[1] = outPeaks[1]; | |||
} | |||
#ifndef BUILD_BRIDGE | |||
EngineEvent* CarlaEngine::getRackEventBuffer(const bool isInput) | |||
EngineEvent* CarlaEngine::getInternalEventBuffer(const bool isInput) const | |||
{ | |||
return isInput ? kData->rack.in : kData->rack.out; | |||
return isInput ? kData->bufEvent.in : kData->bufEvent.out; | |||
} | |||
#ifndef BUILD_BRIDGE | |||
void setValueIfHigher(float& value, const float& compare) | |||
{ | |||
if (value < compare) | |||
@@ -1814,13 +1798,13 @@ void setValueIfHigher(float& value, const float& compare) | |||
void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames) | |||
{ | |||
CARLA_ASSERT(kData->rack.in != nullptr); | |||
CARLA_ASSERT(kData->rack.out != nullptr); | |||
CARLA_ASSERT(kData->bufEvent.in != nullptr); | |||
CARLA_ASSERT(kData->bufEvent.out != nullptr); | |||
// initialize outputs (zero) | |||
carla_zeroFloat(outBuf[0], frames); | |||
carla_zeroFloat(outBuf[1], frames); | |||
carla_zeroMem(kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT); | |||
carla_zeroMem(kData->bufEvent.out, sizeof(EngineEvent)*INTERNAL_EVENT_COUNT); | |||
bool processed = false; | |||
@@ -1837,12 +1821,12 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t | |||
// initialize inputs (from previous outputs) | |||
carla_copyFloat(inBuf[0], outBuf[0], frames); | |||
carla_copyFloat(inBuf[1], outBuf[1], frames); | |||
std::memcpy(kData->rack.in, kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT); | |||
std::memcpy(kData->bufEvent.in, kData->bufEvent.out, sizeof(EngineEvent)*INTERNAL_EVENT_COUNT); | |||
// initialize outputs (zero) | |||
carla_zeroFloat(outBuf[0], frames); | |||
carla_zeroFloat(outBuf[1], frames); | |||
carla_zeroMem(kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT); | |||
carla_zeroMem(kData->bufEvent.out, sizeof(EngineEvent)*INTERNAL_EVENT_COUNT); | |||
} | |||
// process | |||
@@ -60,6 +60,7 @@ SOURCES = \ | |||
CarlaEngineThread.cpp \ | |||
CarlaEngineBridge.cpp \ | |||
CarlaEngineJack.cpp \ | |||
CarlaEngineNative.cpp \ | |||
CarlaEnginePlugin.cpp \ | |||
CarlaEngineRtAudio.cpp | |||
@@ -43,8 +43,7 @@ public: | |||
CarlaEngineBridge(const char* const audioBaseName, const char* const controlBaseName) | |||
: CarlaEngine(), | |||
fIsRunning(false), | |||
fQuitNow(false), | |||
fEventsInPort(nullptr) | |||
fQuitNow(false) | |||
{ | |||
carla_debug("CarlaEngineBridge::CarlaEngineBridge()"); | |||
@@ -109,11 +108,15 @@ public: | |||
} | |||
// Read values from memory | |||
CARLA_ASSERT(rdwr_readOpcode(&fShmControl.data->ringBuffer) == kPluginBridgeOpcodeSetBufferSize); | |||
PluginBridgeOpcode opcode; | |||
opcode = rdwr_readOpcode(&fShmControl.data->ringBuffer); | |||
CARLA_ASSERT(opcode == kPluginBridgeOpcodeSetBufferSize); | |||
fBufferSize = rdwr_readInt(&fShmControl.data->ringBuffer); | |||
carla_stderr("BufferSize: %i", fBufferSize); | |||
CARLA_ASSERT(rdwr_readOpcode(&fShmControl.data->ringBuffer) == kPluginBridgeOpcodeSetSampleRate); | |||
opcode = rdwr_readOpcode(&fShmControl.data->ringBuffer); | |||
CARLA_ASSERT(opcode == kPluginBridgeOpcodeSetSampleRate); | |||
fSampleRate = rdwr_readFloat(&fShmControl.data->ringBuffer); | |||
carla_stderr("SampleRate: %f", fSampleRate); | |||
@@ -184,14 +187,6 @@ public: | |||
{ | |||
const int poolSize(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
fShmAudioPool.data = (float*)carla_shm_map(fShmAudioPool.shm, poolSize); | |||
fEventsInPort = nullptr; | |||
CarlaPlugin* const plugin(getPluginUnchecked(0)); | |||
if (plugin != nullptr && plugin->enabled()) | |||
fEventsInPort = plugin->getDefaultEventInPort(); | |||
break; | |||
} | |||
@@ -266,10 +261,12 @@ public: | |||
for (int i=0; i < dataSize && i < 4; ++i) | |||
data[i] = rdwr_readChar(&fShmControl.data->ringBuffer); | |||
CARLA_ASSERT(fEventsInPort != nullptr); | |||
CARLA_ASSERT(kData->bufEvent.in != nullptr); | |||
if (fEventsInPort != nullptr) | |||
fEventsInPort->writeMidiEvent(time, data, dataSize); | |||
if (kData->bufEvent.in != nullptr) | |||
{ | |||
// TODO | |||
} | |||
break; | |||
} | |||
@@ -295,9 +292,6 @@ public: | |||
plugin->initBuffers(); | |||
plugin->process(inBuffer, outBuffer, fBufferSize); | |||
plugin->unlock(); | |||
if (fEventsInPort != nullptr) | |||
fEventsInPort->clearBuffer(); | |||
} | |||
break; | |||
} | |||
@@ -344,8 +338,6 @@ private: | |||
bool fIsRunning; | |||
bool fQuitNow; | |||
CarlaEngineEventPort* fEventsInPort; | |||
void _cleanup() | |||
{ | |||
if (fShmAudioPool.filename.isNotEmpty()) | |||
@@ -110,9 +110,8 @@ const char* EngineControlEventType2Str(const EngineControlEventType type) | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
const unsigned short INTERNAL_EVENT_COUNT = 512; | |||
const uint32_t PATCHBAY_BUFFER_SIZE = 128; | |||
const unsigned short PATCHBAY_EVENT_COUNT = 512; | |||
const unsigned short RACK_EVENT_COUNT = 512; | |||
enum EnginePostAction { | |||
kEnginePostActionNull, | |||
@@ -150,6 +149,15 @@ struct CarlaEngineProtectedData { | |||
unsigned int curPluginCount; // number of plugins loaded (0...max) | |||
unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255) | |||
struct InternalEventBuffer { | |||
EngineEvent* in; | |||
EngineEvent* out; | |||
InternalEventBuffer() | |||
: in(nullptr), | |||
out(nullptr) {} | |||
} bufEvent; | |||
struct NextAction { | |||
EnginePostAction opcode; | |||
unsigned int pluginId; | |||
@@ -173,17 +181,6 @@ struct CarlaEngineProtectedData { | |||
} | |||
} nextAction; | |||
#ifndef BUILD_BRIDGE | |||
struct Rack { | |||
EngineEvent* in; | |||
EngineEvent* out; | |||
Rack() | |||
: in(nullptr), | |||
out(nullptr) {} | |||
} rack; | |||
#endif | |||
struct Time { | |||
bool playing; | |||
uint32_t frame; | |||
@@ -35,7 +35,12 @@ CARLA_BACKEND_START_NAMESPACE | |||
} // Fix editor indentation | |||
#endif | |||
// ------------------------------------------------------------------- | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Fallback data | |||
static const EngineEvent kFallbackJackEngineEvent; | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Plugin Helpers, defined in CarlaPlugin.cpp | |||
extern CarlaEngine* CarlaPluginGetEngine(CarlaPlugin* const plugin); | |||
@@ -105,8 +110,6 @@ private: | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Carla Engine JACK-Event port | |||
static const EngineEvent kFallbackJackEngineEvent; | |||
class CarlaEngineJackEventPort : public CarlaEngineEventPort | |||
{ | |||
public: | |||
@@ -155,7 +158,7 @@ public: | |||
jackbridge_midi_clear_buffer(fJackBuffer); | |||
} | |||
uint32_t getEventCount() override | |||
uint32_t getEventCount() const override | |||
{ | |||
if (kPort == nullptr) | |||
return CarlaEngineEventPort::getEventCount(); | |||
@@ -185,8 +188,11 @@ public: | |||
return kFallbackJackEngineEvent; | |||
jack_midi_event_t jackEvent; | |||
carla_zeroStruct<jack_midi_event_t>(jackEvent); | |||
if ((! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) || jackEvent.size > 4) | |||
if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index)) | |||
return kFallbackJackEngineEvent; | |||
if (jackEvent.size == 0 || jackEvent.size > 4) | |||
return kFallbackJackEngineEvent; | |||
fRetEvent.clear(); | |||
@@ -199,6 +205,8 @@ public: | |||
if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 2 || jackEvent.size == 3); | |||
const uint8_t midiControl = jackEvent.buffer[1]; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
@@ -224,6 +232,8 @@ public: | |||
} | |||
else | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 3); | |||
const uint8_t midiValue = jackEvent.buffer[2]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeParameter; | |||
@@ -233,6 +243,8 @@ public: | |||
} | |||
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) | |||
{ | |||
CARLA_ASSERT(jackEvent.size == 2); | |||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
@@ -243,11 +255,11 @@ public: | |||
else | |||
{ | |||
fRetEvent.type = kEngineEventTypeMidi; | |||
fRetEvent.midi.data[0] = midiStatus; | |||
fRetEvent.midi.data[1] = jackEvent.buffer[1]; | |||
fRetEvent.midi.data[2] = jackEvent.buffer[2]; | |||
fRetEvent.midi.size = static_cast<uint8_t>(jackEvent.size); | |||
if (jackEvent.size > 1) | |||
carla_copy<uint8_t>(fRetEvent.midi.data+1, jackEvent.buffer+1, jackEvent.size-1); | |||
} | |||
return fRetEvent; | |||
@@ -280,10 +292,10 @@ public: | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); | |||
} | |||
const float fixedValue = carla_fixValue<float>(0.0f, 1.0f, value); | |||
const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value)); | |||
uint8_t data[4] = { 0 }; | |||
uint8_t size = 0; | |||
size_t size = 0; | |||
jack_midi_data_t data[4] = { 0 }; | |||
switch (type) | |||
{ | |||
@@ -291,30 +303,32 @@ public: | |||
break; | |||
case kEngineControlEventTypeParameter: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = static_cast<uint8_t>(param); | |||
data[2] = uint8_t(fixedValue * 127.0f); | |||
data[1] = param; | |||
data[2] = fixedValue * 127.0f; | |||
size = 3; | |||
break; | |||
case kEngineControlEventTypeMidiBank: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||
data[2] = static_cast<uint8_t>(param); | |||
data[2] = param; | |||
size = 3; | |||
break; | |||
case kEngineControlEventTypeMidiProgram: | |||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel; | |||
data[1] = static_cast<uint8_t>(param); | |||
data[1] = param; | |||
size = 2; | |||
break; | |||
case kEngineControlEventTypeAllSoundOff: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
size = 2; | |||
data[2] = 0; | |||
size = 3; | |||
break; | |||
case kEngineControlEventTypeAllNotesOff: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
size = 2; | |||
data[2] = 0; | |||
size = 3; | |||
break; | |||
} | |||
@@ -347,7 +361,7 @@ public: | |||
uint8_t jdata[size]; | |||
carla_copy<uint8_t>(jdata, data, size); | |||
jdata[0] = data[0] + channel; | |||
jdata[0] = MIDI_GET_STATUS_FROM_DATA(data) + channel; | |||
jackbridge_midi_event_write(fJackBuffer, time, jdata, size); | |||
} | |||
@@ -389,11 +403,8 @@ public: | |||
{ | |||
carla_debug("CarlaEngineClient::~CarlaEngineClient()"); | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
if (kClient) | |||
jackbridge_client_close(kClient); | |||
} | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS && kClient != nullptr) | |||
jackbridge_client_close(kClient); | |||
} | |||
void activate() override | |||
@@ -402,9 +413,9 @@ public: | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
CARLA_ASSERT(kClient && ! fActive); | |||
CARLA_ASSERT(kClient != nullptr && ! fActive); | |||
if (kClient && ! fActive) | |||
if (kClient != nullptr && ! fActive) | |||
jackbridge_activate(kClient); | |||
} | |||
@@ -417,9 +428,9 @@ public: | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
CARLA_ASSERT(kClient && fActive); | |||
CARLA_ASSERT(kClient != nullptr && fActive); | |||
if (kClient && fActive) | |||
if (kClient != nullptr && fActive) | |||
jackbridge_deactivate(kClient); | |||
} | |||
@@ -1063,7 +1074,7 @@ protected: | |||
float* outBuf[2] = { audioOut1, audioOut2 }; | |||
// initialize input events | |||
carla_zeroStruct<EngineEvent>(kData->rack.in, RACK_EVENT_COUNT); | |||
carla_zeroStruct<EngineEvent>(kData->bufEvent.in, INTERNAL_EVENT_COUNT); | |||
{ | |||
uint32_t engineEventIndex = 0; | |||
@@ -1075,7 +1086,7 @@ protected: | |||
if (jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex) != 0) | |||
continue; | |||
EngineEvent* const engineEvent = &kData->rack.in[engineEventIndex++]; | |||
EngineEvent* const engineEvent = &kData->bufEvent.in[engineEventIndex++]; | |||
engineEvent->clear(); | |||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer); | |||
@@ -1137,7 +1148,7 @@ protected: | |||
engineEvent->midi.size = static_cast<uint8_t>(jackEvent.size); | |||
} | |||
if (engineEventIndex >= RACK_EVENT_COUNT) | |||
if (engineEventIndex >= INTERNAL_EVENT_COUNT) | |||
break; | |||
} | |||
} | |||
@@ -1149,9 +1160,9 @@ protected: | |||
{ | |||
jackbridge_midi_clear_buffer(eventOut); | |||
for (unsigned short i=0; i < RACK_EVENT_COUNT; ++i) | |||
for (unsigned short i=0; i < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
EngineEvent* const engineEvent = &kData->rack.out[i]; | |||
EngineEvent* const engineEvent = &kData->bufEvent.out[i]; | |||
uint8_t data[3] = { 0 }; | |||
uint8_t size = 0; | |||
@@ -17,8 +17,6 @@ | |||
#ifndef BUILD_BRIDGE | |||
#define WANT_LV2 | |||
#include "CarlaEngineInternal.hpp" | |||
#include "CarlaStateUtils.hpp" | |||
@@ -286,7 +284,7 @@ protected: | |||
plugin->setParameterValue(index, value, false, false, false); | |||
} | |||
void setMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) override | |||
void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override | |||
{ | |||
if (kData->curPluginCount == 0 || kData->plugins == nullptr) | |||
return; | |||
@@ -382,11 +380,11 @@ protected: | |||
// --------------------------------------------------------------- | |||
// initialize input events | |||
carla_zeroStruct<EngineEvent>(kData->rack.in, RACK_EVENT_COUNT); | |||
carla_zeroStruct<EngineEvent>(kData->bufEvent.in, INTERNAL_EVENT_COUNT); | |||
{ | |||
uint32_t engineEventIndex = 0; | |||
for (uint32_t i=0; i < midiEventCount && engineEventIndex < RACK_EVENT_COUNT; ++i) | |||
for (uint32_t i=0; i < midiEventCount && engineEventIndex < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
const ::MidiEvent& midiEvent(midiEvents[i]); | |||
@@ -410,7 +408,7 @@ protected: | |||
if (control == MIDI_CONTROL_ALL_SOUND_OFF || control == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
engineEvent.type = kEngineEventTypeControl; | |||
@@ -425,7 +423,7 @@ protected: | |||
} | |||
} | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
engineEvent.type = kEngineEventTypeMidi; | |||
@@ -491,6 +489,7 @@ protected: | |||
// TODO | |||
// unused | |||
(void)channel; | |||
(void)bank; | |||
(void)program; | |||
} | |||
@@ -41,7 +41,7 @@ static const unsigned int kParamVolume = 5; | |||
static const unsigned int kParamBalance = 6; | |||
static const unsigned int kParamPan = 8; | |||
static const unsigned int kParamCount = sizeof(paramMap); | |||
static const unsigned int kParamCount = sizeof(kParamMap); | |||
static const unsigned int kProgramCount = 128; | |||
static const unsigned int kStateCount = MAX_RACK_PLUGINS; | |||
@@ -434,16 +434,16 @@ protected: | |||
// --------------------------------------------------------------- | |||
// initialize input events | |||
carla_zeroStruct<EngineEvent>(kData->rack.in, RACK_EVENT_COUNT); | |||
carla_zeroStruct<EngineEvent>(kData->bufEvent.in, INTERNAL_EVENT_COUNT); | |||
{ | |||
uint32_t engineEventIndex = 0; | |||
for (unsigned int i=0; i < kParamCount && engineEventIndex+midiEventCount < RACK_EVENT_COUNT; ++i) | |||
for (unsigned int i=0; i < kParamCount && engineEventIndex+midiEventCount < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
if (fParamBuffers[i] == fPrevParamBuffers[i]) | |||
continue; | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
engineEvent.type = kEngineEventTypeControl; | |||
@@ -457,7 +457,7 @@ protected: | |||
fPrevParamBuffers[i] = fParamBuffers[i]; | |||
} | |||
for (uint32_t i=0; i < midiEventCount && engineEventIndex < RACK_EVENT_COUNT; ++i) | |||
for (uint32_t i=0; i < midiEventCount && engineEventIndex < INTERNAL_EVENT_COUNT; ++i) | |||
{ | |||
const DISTRHO::MidiEvent& midiEvent(midiEvents[i]); | |||
@@ -481,7 +481,7 @@ protected: | |||
if (control == MIDI_CONTROL_ALL_SOUND_OFF || control == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
engineEvent.type = kEngineEventTypeControl; | |||
@@ -496,7 +496,7 @@ protected: | |||
} | |||
} | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
engineEvent.type = kEngineEventTypeMidi; | |||
@@ -824,7 +824,7 @@ protected: | |||
carla_zeroFloat(fAudioBufRackOut[1], nframes); | |||
// initialize input events | |||
carla_zeroMem(kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT); | |||
carla_zeroMem(kData->bufEvent.in, sizeof(EngineEvent)*INTERNAL_EVENT_COUNT); | |||
if (fMidiInEvents.mutex.tryLock()) | |||
{ | |||
@@ -835,7 +835,7 @@ protected: | |||
{ | |||
const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||
EngineEvent& engineEvent(kData->rack.in[engineEventIndex++]); | |||
EngineEvent& engineEvent(kData->bufEvent.in[engineEventIndex++]); | |||
engineEvent.clear(); | |||
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(midiEvent.data); | |||
@@ -909,7 +909,7 @@ protected: | |||
engineEvent.midi.size = midiEvent.size; | |||
} | |||
if (engineEventIndex >= RACK_EVENT_COUNT) | |||
if (engineEventIndex >= INTERNAL_EVENT_COUNT) | |||
break; | |||
} | |||
@@ -2104,14 +2104,6 @@ void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note) | |||
(void)note; | |||
} | |||
// ------------------------------------------------------------------- | |||
// Helpers | |||
CarlaEngineEventPort* CarlaPlugin::getDefaultEventInPort() const | |||
{ | |||
return kData->event.portIn; | |||
} | |||
// ------------------------------------------------------------------- | |||
// Scoped Disabler | |||
@@ -3452,14 +3452,6 @@ public: | |||
} | |||
// ------------------------------------------------------------------- | |||
// Helpers | |||
CarlaEngineEventPort* getDefaultEventInPort() const override | |||
{ | |||
return (fEventsIn.ctrl != nullptr) ? fEventsIn.ctrl->port : nullptr; | |||
} | |||
// ------------------------------------------------------------------- | |||
protected: | |||
void guiClosedCallback() override | |||
@@ -114,7 +114,11 @@ | |||
#define CARLA_SAFE_ASSERT_INT(cond, value) ((!(cond)) ? carla_assert_int(#cond, __FILE__, __LINE__, value) : pass()) | |||
#define CARLA_SAFE_ASSERT_INT2(cond, v1, v2) ((!(cond)) ? carla_assert_int2(#cond, __FILE__, __LINE__, v1, v2) : pass()) | |||
#ifdef NDEBUG | |||
#if defined(CARLA_NO_ASSERTS) | |||
# define CARLA_ASSERT(cond) | |||
# define CARLA_ASSERT_INT(cond, value) | |||
# define CARLA_ASSERT_INT2(cond, v1, v2) | |||
#elif defined(NDEBUG) | |||
# define CARLA_ASSERT CARLA_SAFE_ASSERT | |||
# define CARLA_ASSERT_INT CARLA_SAFE_ASSERT_INT | |||
# define CARLA_ASSERT_INT2 CARLA_SAFE_ASSERT_INT2 | |||