| @@ -1036,6 +1036,7 @@ protected: | |||
| */ | |||
| struct ProtectedData; | |||
| ProtectedData* const pData; | |||
| friend class ScopedActionLock; | |||
| // ------------------------------------------------------------------- | |||
| // Internal stuff | |||
| @@ -592,7 +592,7 @@ CarlaEnginePort* CarlaEngineClient::addPort(const EnginePortType portType, const | |||
| // Carla Engine | |||
| CarlaEngine::CarlaEngine() | |||
| : pData(new CarlaEngineProtectedData(this)) | |||
| : pData(new ProtectedData(this)) | |||
| { | |||
| carla_debug("CarlaEngine::CarlaEngine()"); | |||
| } | |||
| @@ -291,7 +291,7 @@ const char* const* RackGraph::getConnections() const | |||
| const char** const retConns = new const char*[connCount+1]; | |||
| for (size_t i=0; i < connCount; ++i) | |||
| retConns[i] = connList.getAt(i); | |||
| retConns[i] = connList.getAt(i, nullptr); | |||
| retConns[connCount] = nullptr; | |||
| connList.clear(); | |||
| @@ -364,9 +364,9 @@ bool PatchbayGraph::getPortIdFromName(const char* const /*portName*/, int& /*gro | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaEngineProtectedData | |||
| // CarlaEngine::ProtectedData | |||
| CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) noexcept | |||
| CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept | |||
| : osc(engine), | |||
| thread(engine), | |||
| oscData(nullptr), | |||
| @@ -383,7 +383,7 @@ CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) no | |||
| nextPluginId(0), | |||
| plugins(nullptr) {} | |||
| CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept | |||
| CarlaEngine::ProtectedData::~ProtectedData() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT(curPluginCount == 0); | |||
| CARLA_SAFE_ASSERT(maxPluginNumber == 0); | |||
| @@ -393,7 +393,7 @@ CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept | |||
| // ----------------------------------------------------------------------- | |||
| void CarlaEngineProtectedData::doPluginRemove() noexcept | |||
| void CarlaEngine::ProtectedData::doPluginRemove() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); | |||
| CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,); | |||
| @@ -425,7 +425,7 @@ void CarlaEngineProtectedData::doPluginRemove() noexcept | |||
| plugins[id].outsPeak[1] = 0.0f; | |||
| } | |||
| void CarlaEngineProtectedData::doPluginsSwitch() noexcept | |||
| void CarlaEngine::ProtectedData::doPluginsSwitch() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,); | |||
| @@ -447,7 +447,7 @@ void CarlaEngineProtectedData::doPluginsSwitch() noexcept | |||
| #endif | |||
| } | |||
| void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept | |||
| void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept | |||
| { | |||
| switch (nextAction.opcode) | |||
| { | |||
| @@ -478,7 +478,7 @@ void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept | |||
| // ----------------------------------------------------------------------- | |||
| #ifndef BUILD_BRIDGE | |||
| void CarlaEngineProtectedData::processRack(const float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) | |||
| void CarlaEngine::ProtectedData::processRack(const float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(events.in != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(events.out != nullptr,); | |||
| @@ -637,7 +637,7 @@ void CarlaEngineProtectedData::processRack(const float* inBufReal[2], float* out | |||
| } | |||
| } | |||
| void CarlaEngineProtectedData::processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) | |||
| void CarlaEngine::ProtectedData::processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) | |||
| { | |||
| const CarlaMutexLocker _crml(graph.rack->connectLock); // Recursive | |||
| @@ -726,7 +726,7 @@ void CarlaEngineProtectedData::processRackFull(const float* const* const inBuf, | |||
| // ----------------------------------------------------------------------- | |||
| // ScopedActionLock | |||
| ScopedActionLock::ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept | |||
| ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept | |||
| : fData(data) | |||
| { | |||
| fData->nextAction.mutex.lock(); | |||
| @@ -418,7 +418,7 @@ struct EnginePluginData { | |||
| // ----------------------------------------------------------------------- | |||
| // CarlaEngineProtectedData | |||
| struct CarlaEngineProtectedData { | |||
| struct CarlaEngine::ProtectedData { | |||
| CarlaEngineOsc osc; | |||
| CarlaEngineThread thread; | |||
| @@ -458,8 +458,8 @@ struct CarlaEngineProtectedData { | |||
| // ------------------------------------------------------------------- | |||
| CarlaEngineProtectedData(CarlaEngine* const engine) noexcept; | |||
| ~CarlaEngineProtectedData() noexcept; | |||
| ProtectedData(CarlaEngine* const engine) noexcept; | |||
| ~ProtectedData() noexcept; | |||
| // ------------------------------------------------------------------- | |||
| @@ -479,9 +479,11 @@ struct CarlaEngineProtectedData { | |||
| // ------------------------------------------------------------------- | |||
| //friend class ScopedActionLock; | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| CarlaEngineProtectedData() = delete; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) | |||
| ProtectedData() = delete; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData) | |||
| #endif | |||
| }; | |||
| @@ -490,11 +492,11 @@ struct CarlaEngineProtectedData { | |||
| class ScopedActionLock | |||
| { | |||
| public: | |||
| ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept; | |||
| ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept; | |||
| ~ScopedActionLock() noexcept; | |||
| private: | |||
| CarlaEngineProtectedData* const fData; | |||
| CarlaEngine::ProtectedData* const fData; | |||
| CARLA_PREVENT_HEAP_ALLOCATION | |||
| CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock) | |||
| @@ -858,7 +858,7 @@ public: | |||
| return; | |||
| LinkedList<int> newPlugins; | |||
| fNewGroups.spliceInsert(newPlugins, true); | |||
| fNewGroups.spliceInsert(newPlugins); | |||
| for (LinkedList<int>::Itenerator it = newPlugins.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -1210,7 +1210,7 @@ public: | |||
| const char** const retConns = new const char*[connCount+1]; | |||
| for (size_t i=0; i < connCount; ++i) | |||
| retConns[i] = connList.getAt(i); | |||
| retConns[i] = connList.getAt(i, nullptr); | |||
| retConns[connCount] = nullptr; | |||
| connList.clear(); | |||
| @@ -706,9 +706,9 @@ protected: | |||
| uint32_t engineEventIndex = 0; | |||
| fMidiInEvents.splice(); | |||
| while (! fMidiInEvents.data.isEmpty()) | |||
| for (LinkedList<RtMidiEvent>::Itenerator it = fMidiInEvents.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true)); | |||
| const RtMidiEvent& midiEvent(it.getValue()); | |||
| EngineEvent& engineEvent(pData->events.in[engineEventIndex++]); | |||
| if (midiEvent.time < pData->timeInfo.frame) | |||
| @@ -729,6 +729,7 @@ protected: | |||
| break; | |||
| } | |||
| fMidiInEvents.data.clear(); | |||
| fMidiInEvents.mutex.unlock(); | |||
| } | |||
| @@ -803,7 +804,8 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiIns.count(), false); | |||
| carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(%i)", portId); | |||
| const char* const portName(fUsedMidiIns.getAt(static_cast<size_t>(portId)).name); | |||
| const PortNameToId fallback = { 0, { '\0' } }; | |||
| const char* const portName(fUsedMidiIns.getAt(static_cast<size_t>(portId), fallback).name); | |||
| char newPortName[STR_MAX+1]; | |||
| std::snprintf(newPortName, STR_MAX, "%s:in-%i", getName(), portId+1); | |||
| @@ -849,7 +851,8 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiOuts.count(), false); | |||
| carla_debug("CarlaEngineRtAudio::connectRackMidiOutPort(%i)", portId); | |||
| const char* const portName(fUsedMidiOuts.getAt(static_cast<size_t>(portId)).name); | |||
| const PortNameToId fallback = { 0, { '\0' } }; | |||
| const char* const portName(fUsedMidiOuts.getAt(static_cast<size_t>(portId), fallback).name); | |||
| char newPortName[STR_MAX+1]; | |||
| std::snprintf(newPortName, STR_MAX, "%s:out-%i", getName(), portId+1); | |||
| @@ -1128,7 +1131,7 @@ const char* const* CarlaEngine::getRtAudioApiDeviceNames(const uint index) | |||
| gRetNames = new const char*[realDevCount+1]; | |||
| for (size_t i=0; i < realDevCount; ++i) | |||
| gRetNames[i] = devNames.getAt(i); | |||
| gRetNames[i] = devNames.getAt(i, nullptr); | |||
| gRetNames[realDevCount] = nullptr; | |||
| devNames.clear(); | |||
| @@ -851,9 +851,9 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| for (; ! pData->extNotes.data.isEmpty();) | |||
| for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| const ExternalMidiNote& note(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -873,6 +873,7 @@ public: | |||
| fShmControl.commitWrite(); | |||
| } | |||
| pData->extNotes.data.clear(); | |||
| pData->extNotes.mutex.unlock(); | |||
| } // End of MIDI Input (External) | |||
| @@ -67,7 +67,7 @@ struct ParamSymbol { | |||
| // ----------------------------------------------------------------------- | |||
| void CarlaPluginProtectedData::tryTransient() | |||
| void CarlaPlugin::ProtectedData::tryTransient() | |||
| { | |||
| if (engine->getOptions().frontendWinId != 0) | |||
| transientTryCounter = 1; | |||
| @@ -120,7 +120,7 @@ CarlaPlugin* CarlaPlugin::newFileSFZ(const Initializer& init) | |||
| // Constructor and destructor | |||
| CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id) | |||
| : pData(new CarlaPluginProtectedData(engine, id, this)) | |||
| : pData(new ProtectedData(engine, id, this)) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(engine != nullptr,); | |||
| CARLA_SAFE_ASSERT(id < engine->getMaxPluginNumber()); | |||
| @@ -302,7 +302,7 @@ const MidiProgramData& CarlaPlugin::getMidiProgramData(const uint32_t index) con | |||
| const CustomData& CarlaPlugin::getCustomData(const uint32_t index) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < pData->custom.count(), kCustomDataNull); | |||
| return pData->custom.getAt(index); | |||
| return pData->custom.getAt(index, kCustomDataNull); | |||
| } | |||
| int32_t CarlaPlugin::getChunkData(void** const dataPtr) const noexcept | |||
| @@ -1867,9 +1867,9 @@ void CarlaPlugin::postRtEventsRun() | |||
| const bool sendOsc(pData->engine->isOscControlRegistered()); | |||
| #endif | |||
| while (! pData->postRtEvents.data.isEmpty()) | |||
| for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const PluginPostRtEvent& event(pData->postRtEvents.data.getFirst(true)); | |||
| const PluginPostRtEvent& event(it.getValue()); | |||
| switch (event.type) | |||
| { | |||
| @@ -2009,6 +2009,8 @@ void CarlaPlugin::postRtEventsRun() | |||
| } | |||
| } | |||
| } | |||
| pData->postRtEvents.data.clear(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -404,18 +404,18 @@ const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPluginProtectedData::ExternalNotes::ExternalNotes() | |||
| CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() | |||
| : dataPool(32, 152), | |||
| data(dataPool) {} | |||
| CarlaPluginProtectedData::ExternalNotes::~ExternalNotes() | |||
| CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() | |||
| { | |||
| mutex.lock(); | |||
| data.clear(); | |||
| mutex.unlock(); | |||
| } | |||
| void CarlaPluginProtectedData::ExternalNotes::append(const ExternalMidiNote& note) | |||
| void CarlaPlugin::ProtectedData::ExternalNotes::append(const ExternalMidiNote& note) | |||
| { | |||
| mutex.lock(); | |||
| data.append_sleepy(note); | |||
| @@ -424,22 +424,22 @@ void CarlaPluginProtectedData::ExternalNotes::append(const ExternalMidiNote& not | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPluginProtectedData::PostRtEvents::PostRtEvents() | |||
| CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() | |||
| : dataPool(128, 128), | |||
| data(dataPool), | |||
| dataPendingRT(dataPool) {} | |||
| CarlaPluginProtectedData::PostRtEvents::~PostRtEvents() | |||
| CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() | |||
| { | |||
| clear(); | |||
| } | |||
| void CarlaPluginProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) | |||
| void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) | |||
| { | |||
| dataPendingRT.append(e); | |||
| } | |||
| void CarlaPluginProtectedData::PostRtEvents::trySplice() | |||
| void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() | |||
| { | |||
| if (mutex.tryLock()) | |||
| { | |||
| @@ -448,7 +448,7 @@ void CarlaPluginProtectedData::PostRtEvents::trySplice() | |||
| } | |||
| } | |||
| void CarlaPluginProtectedData::PostRtEvents::clear() | |||
| void CarlaPlugin::ProtectedData::PostRtEvents::clear() | |||
| { | |||
| mutex.lock(); | |||
| data.clear(); | |||
| @@ -459,7 +459,7 @@ void CarlaPluginProtectedData::PostRtEvents::clear() | |||
| // ----------------------------------------------------------------------- | |||
| #ifndef BUILD_BRIDGE | |||
| CarlaPluginProtectedData::PostProc::PostProc() noexcept | |||
| CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept | |||
| : dryWet(1.0f), | |||
| volume(1.0f), | |||
| balanceLeft(-1.0f), | |||
| @@ -469,12 +469,12 @@ CarlaPluginProtectedData::PostProc::PostProc() noexcept | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPluginProtectedData::OSC::OSC(CarlaEngine* const eng, CarlaPlugin* const plug) | |||
| CarlaPlugin::ProtectedData::OSC::OSC(CarlaEngine* const eng, CarlaPlugin* const plug) | |||
| : thread(eng, plug) {} | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const unsigned int idx, CarlaPlugin* const self) | |||
| CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const unsigned int idx, CarlaPlugin* const self) | |||
| : engine(eng), | |||
| client(nullptr), | |||
| id(idx), | |||
| @@ -496,7 +496,7 @@ CarlaPluginProtectedData::CarlaPluginProtectedData(CarlaEngine* const eng, const | |||
| identifier(nullptr), | |||
| osc(eng, self) {} | |||
| CarlaPluginProtectedData::~CarlaPluginProtectedData() | |||
| CarlaPlugin::ProtectedData::~ProtectedData() | |||
| { | |||
| CARLA_SAFE_ASSERT(! needsReset); | |||
| CARLA_SAFE_ASSERT(transientTryCounter == 0); | |||
| @@ -594,7 +594,7 @@ CarlaPluginProtectedData::~CarlaPluginProtectedData() | |||
| // ----------------------------------------------------------------------- | |||
| // Buffer functions | |||
| void CarlaPluginProtectedData::clearBuffers() | |||
| void CarlaPlugin::ProtectedData::clearBuffers() | |||
| { | |||
| if (latencyBuffers != nullptr) | |||
| { | |||
| @@ -623,7 +623,7 @@ void CarlaPluginProtectedData::clearBuffers() | |||
| event.clear(); | |||
| } | |||
| void CarlaPluginProtectedData::recreateLatencyBuffers() | |||
| void CarlaPlugin::ProtectedData::recreateLatencyBuffers() | |||
| { | |||
| if (latencyBuffers != nullptr) | |||
| { | |||
| @@ -656,7 +656,7 @@ void CarlaPluginProtectedData::recreateLatencyBuffers() | |||
| // ----------------------------------------------------------------------- | |||
| // Post-poned events | |||
| void CarlaPluginProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) | |||
| void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,); | |||
| @@ -670,43 +670,43 @@ void CarlaPluginProtectedData::postponeRtEvent(const PluginPostRtEventType type, | |||
| static LibCounter sLibCounter; | |||
| const char* CarlaPluginProtectedData::libError(const char* const fname) | |||
| const char* CarlaPlugin::ProtectedData::libError(const char* const fname) | |||
| { | |||
| return lib_error(fname); | |||
| } | |||
| bool CarlaPluginProtectedData::libOpen(const char* const fname) | |||
| bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) | |||
| { | |||
| lib = sLibCounter.open(fname); | |||
| return (lib != nullptr); | |||
| } | |||
| bool CarlaPluginProtectedData::libClose() | |||
| bool CarlaPlugin::ProtectedData::libClose() | |||
| { | |||
| const bool ret = sLibCounter.close(lib); | |||
| lib = nullptr; | |||
| return ret; | |||
| } | |||
| void* CarlaPluginProtectedData::libSymbol(const char* const symbol) | |||
| void* CarlaPlugin::ProtectedData::libSymbol(const char* const symbol) | |||
| { | |||
| return lib_symbol(lib, symbol); | |||
| } | |||
| bool CarlaPluginProtectedData::uiLibOpen(const char* const fname, const bool canDelete) | |||
| bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) | |||
| { | |||
| uiLib = sLibCounter.open(fname, canDelete); | |||
| return (uiLib != nullptr); | |||
| } | |||
| bool CarlaPluginProtectedData::uiLibClose() | |||
| bool CarlaPlugin::ProtectedData::uiLibClose() | |||
| { | |||
| const bool ret = sLibCounter.close(uiLib); | |||
| uiLib = nullptr; | |||
| return ret; | |||
| } | |||
| void* CarlaPluginProtectedData::uiLibSymbol(const char* const symbol) | |||
| void* CarlaPlugin::ProtectedData::uiLibSymbol(const char* const symbol) | |||
| { | |||
| return lib_symbol(uiLib, symbol); | |||
| } | |||
| @@ -714,7 +714,7 @@ void* CarlaPluginProtectedData::uiLibSymbol(const char* const symbol) | |||
| // ----------------------------------------------------------------------- | |||
| // Settings functions | |||
| void CarlaPluginProtectedData::saveSetting(const uint option, const bool yesNo) | |||
| void CarlaPlugin::ProtectedData::saveSetting(const uint option, const bool yesNo) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0',); | |||
| @@ -757,7 +757,7 @@ void CarlaPluginProtectedData::saveSetting(const uint option, const bool yesNo) | |||
| settings.endGroup(); | |||
| } | |||
| uint CarlaPluginProtectedData::loadSettings(const uint curOptions, const uint availOptions) | |||
| uint CarlaPlugin::ProtectedData::loadSettings(const uint curOptions, const uint availOptions) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0', 0x0); | |||
| @@ -224,7 +224,7 @@ struct PluginMidiProgramData { | |||
| // ----------------------------------------------------------------------- | |||
| struct CarlaPluginProtectedData { | |||
| struct CarlaPlugin::ProtectedData { | |||
| CarlaEngine* const engine; | |||
| CarlaEngineClient* client; | |||
| @@ -324,8 +324,8 @@ struct CarlaPluginProtectedData { | |||
| #endif | |||
| } osc; | |||
| CarlaPluginProtectedData(CarlaEngine* const eng, const unsigned int idx, CarlaPlugin* const self); | |||
| ~CarlaPluginProtectedData(); | |||
| ProtectedData(CarlaEngine* const eng, const unsigned int idx, CarlaPlugin* const self); | |||
| ~ProtectedData(); | |||
| // ------------------------------------------------------------------- | |||
| // Buffer functions | |||
| @@ -365,8 +365,8 @@ struct CarlaPluginProtectedData { | |||
| // ------------------------------------------------------------------- | |||
| #ifdef CARLA_PROPER_CPP11_SUPPORT | |||
| CarlaPluginProtectedData() = delete; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(CarlaPluginProtectedData) | |||
| ProtectedData() = delete; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData) | |||
| #endif | |||
| }; | |||
| @@ -1042,9 +1042,11 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| ExternalMidiNote note = { 0, 0, 0 }; | |||
| for (; midiEventCount < kPluginMaxMidiEvents && ! pData->extNotes.data.isEmpty();) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| note = pData->extNotes.data.getFirst(note, true); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -1094,9 +1094,9 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| while (! pData->extNotes.data.isEmpty()) | |||
| for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| const ExternalMidiNote& note(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -1106,6 +1106,7 @@ public: | |||
| fluid_synth_noteoff(fSynth,note.channel, note.note); | |||
| } | |||
| pData->extNotes.data.clear(); | |||
| pData->extNotes.mutex.unlock(); | |||
| } // End of MIDI Input (External) | |||
| @@ -589,9 +589,9 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| for (; ! pData->extNotes.data.isEmpty();) | |||
| for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| const ExternalMidiNote& note(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -603,6 +603,7 @@ public: | |||
| fMidiBuffer.addEvent(midiEvent, 3, 0); | |||
| } | |||
| pData->extNotes.data.clear(); | |||
| pData->extNotes.mutex.unlock(); | |||
| } // End of MIDI Input (External) | |||
| @@ -756,9 +756,9 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| while (! pData->extNotes.data.isEmpty()) | |||
| for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| const ExternalMidiNote& note(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -768,6 +768,7 @@ public: | |||
| fMidiInputPort->DispatchNoteOff(note.note, note.velo, static_cast<uint>(note.channel)); | |||
| } | |||
| pData->extNotes.data.clear(); | |||
| pData->extNotes.mutex.unlock(); | |||
| } // End of MIDI Input (External) | |||
| @@ -1493,7 +1493,7 @@ public: | |||
| for (uint32_t i=0; i < count; ++i) | |||
| { | |||
| const uint32_t& type(evIns.getAt(i)); | |||
| const uint32_t& type(evIns.getAt(i, 0x0)); | |||
| if (type == CARLA_EVENT_DATA_ATOM) | |||
| { | |||
| @@ -1525,7 +1525,7 @@ public: | |||
| for (uint32_t i=0; i < count; ++i) | |||
| { | |||
| const uint32_t& type(evOuts.getAt(i)); | |||
| const uint32_t& type(evOuts.getAt(i, 0x0)); | |||
| if (type == CARLA_EVENT_DATA_ATOM) | |||
| { | |||
| @@ -2678,9 +2678,9 @@ public: | |||
| { | |||
| const uint32_t j = fEventsIn.ctrlIndex; | |||
| for (; ! pData->extNotes.data.isEmpty();) | |||
| for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| const ExternalMidiNote& note(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -2698,6 +2698,8 @@ public: | |||
| else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL) | |||
| lv2midi_put_event(&evInMidiStates[j], 0.0, 3, midiEvent); | |||
| } | |||
| pData->extNotes.data.clear(); | |||
| } | |||
| pData->extNotes.mutex.unlock(); | |||
| @@ -3560,7 +3562,7 @@ public: | |||
| bool updateOscDataExtra() override | |||
| { | |||
| for (size_t i=CARLA_URI_MAP_ID_COUNT, count=fCustomURIDs.count(); i < count; ++i) | |||
| osc_send_lv2_urid_map(pData->osc.data, static_cast<uint32_t>(i), fCustomURIDs.getAt(i)); | |||
| osc_send_lv2_urid_map(pData->osc.data, static_cast<uint32_t>(i), fCustomURIDs.getAt(i, nullptr)); | |||
| osc_send_lv2_urid_map(pData->osc.data, CARLA_URI_MAP_ID_NULL, "Complete"); | |||
| @@ -3893,7 +3895,7 @@ public: | |||
| for (size_t i=0; i < fCustomURIDs.count(); ++i) | |||
| { | |||
| const char* const thisUri(fCustomURIDs.getAt(i)); | |||
| const char* const thisUri(fCustomURIDs.getAt(i, nullptr)); | |||
| if (thisUri != nullptr && std::strcmp(thisUri, uri) == 0) | |||
| return static_cast<LV2_URID>(i); | |||
| } | |||
| @@ -3914,7 +3916,7 @@ public: | |||
| CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.count(), nullptr); | |||
| carla_debug("Lv2Plugin::getCustomURIString(%i)", urid); | |||
| return fCustomURIDs.getAt(urid); | |||
| return fCustomURIDs.getAt(urid, nullptr); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -1355,9 +1355,12 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| ExternalMidiNote note = { 0, 0, 0 }; | |||
| //for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next()) | |||
| while (fMidiEventCount < kPluginMaxMidiEvents*2 && ! pData->extNotes.data.isEmpty()) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| note = pData->extNotes.data.getFirst(note, true); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -2199,7 +2202,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(index < gPluginDescriptors.count(), nullptr); | |||
| return gPluginDescriptors.getAt(index); | |||
| return gPluginDescriptors.getAt(index, nullptr); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -1133,9 +1133,11 @@ public: | |||
| if (pData->extNotes.mutex.tryLock()) | |||
| { | |||
| ExternalMidiNote note = { 0, 0, 0 }; | |||
| for (; fMidiEventCount < kPluginMaxMidiEvents*2 && ! pData->extNotes.data.isEmpty();) | |||
| { | |||
| const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
| note = pData->extNotes.data.getFirst(note, true); | |||
| CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); | |||
| @@ -172,7 +172,8 @@ public: | |||
| if (index >= fPrograms.count()) | |||
| return nullptr; | |||
| const ProgramInfo* const pInfo(fPrograms.getAt(index)); | |||
| const ProgramInfo* const pInfo(fPrograms.getAt(index, nullptr)); | |||
| CARLA_SAFE_ASSERT_RETURN(pInfo != nullptr, nullptr); | |||
| fRetProgram.bank = pInfo->bank; | |||
| fRetProgram.program = pInfo->prog; | |||
| @@ -132,11 +132,11 @@ public: | |||
| Data* const data = list_entry(entry, Data, siblings); | |||
| CARLA_SAFE_ASSERT_CONTINUE(data != nullptr); | |||
| _delete(entry, data); | |||
| if (kIsClass) | |||
| data->~Data(); | |||
| _deallocate(data); | |||
| } | |||
| CARLA_SAFE_ASSERT(fCount == 0); | |||
| _init(); | |||
| } | |||
| @@ -170,7 +170,7 @@ public: | |||
| return _add(value, false, it.fEntry->prev); | |||
| } | |||
| T& getAt(const size_t index, T& fallback) const noexcept | |||
| const T& getAt(const size_t index, const T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
| @@ -189,18 +189,23 @@ public: | |||
| return fallback; | |||
| } | |||
| T& getFirst(T& fallback) const noexcept | |||
| T& getAt(const size_t index, T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0 && index < fCount, fallback); | |||
| return _get(fQueue.next, fallback); | |||
| } | |||
| size_t i = 0; | |||
| k_list_head* entry; | |||
| k_list_head* entry2; | |||
| T& getLast(T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| for (entry = fQueue.next, entry2 = entry->next; entry != &fQueue; entry = entry2, entry2 = entry->next) | |||
| { | |||
| if (index != i++) | |||
| continue; | |||
| return _get(fQueue.prev, fallback); | |||
| return _get(entry, fallback); | |||
| } | |||
| return fallback; | |||
| } | |||
| T getAt(const size_t index, T& fallback, const bool removeObj) noexcept | |||
| @@ -222,6 +227,20 @@ public: | |||
| return fallback; | |||
| } | |||
| const T& getFirst(const T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| return _get(fQueue.next, fallback); | |||
| } | |||
| T& getFirst(T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| return _get(fQueue.next, fallback); | |||
| } | |||
| T getFirst(T& fallback, const bool removeObj) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| @@ -229,6 +248,20 @@ public: | |||
| return _get(fQueue.next, fallback, removeObj); | |||
| } | |||
| const T& getLast(const T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| return _get(fQueue.prev, fallback); | |||
| } | |||
| T& getLast(T& fallback) const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| return _get(fQueue.prev, fallback); | |||
| } | |||
| T getLast(T& fallback, const bool removeObj) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fCount > 0, fallback); | |||
| @@ -308,10 +341,9 @@ protected: | |||
| void _createData(Data* const data, const T& value) noexcept | |||
| { | |||
| if (kIsClass) | |||
| new(data)Data(value); | |||
| else | |||
| data->value = value; | |||
| new(data)Data(); | |||
| data->value = value; | |||
| ++fCount; | |||
| } | |||
| @@ -350,6 +382,14 @@ private: | |||
| _deallocate(data); | |||
| } | |||
| const T& _get(k_list_head* const entry, const T& fallback) const noexcept | |||
| { | |||
| const Data* const data = list_entry(entry, Data, siblings); | |||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback); | |||
| return data->value; | |||
| } | |||
| T& _get(k_list_head* const entry, T& fallback) const noexcept | |||
| { | |||
| Data* const data = list_entry(entry, Data, siblings); | |||