| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -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 | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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; | |||
| } | |||
| @@ -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) | |||
| @@ -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 | |||
| @@ -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) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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 | |||
| @@ -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; | |||