diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 90e970a79..5e9a63785 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -1036,6 +1036,7 @@ protected: */ struct ProtectedData; ProtectedData* const pData; + friend class ScopedActionLock; // ------------------------------------------------------------------- // Internal stuff diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index db6183113..69cce09e9 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -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()"); } diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index ff8583da9..74d75914b 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -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(); diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 2c4d925be..c90fb7847 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -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) diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 4cd29a29d..d3fc98025 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -858,7 +858,7 @@ public: return; LinkedList newPlugins; - fNewGroups.spliceInsert(newPlugins, true); + fNewGroups.spliceInsert(newPlugins); for (LinkedList::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(); diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index 037e3542f..272e2e4bc 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -706,9 +706,9 @@ protected: uint32_t engineEventIndex = 0; fMidiInEvents.splice(); - while (! fMidiInEvents.data.isEmpty()) + for (LinkedList::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(portId) < fUsedMidiIns.count(), false); carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(%i)", portId); - const char* const portName(fUsedMidiIns.getAt(static_cast(portId)).name); + const PortNameToId fallback = { 0, { '\0' } }; + const char* const portName(fUsedMidiIns.getAt(static_cast(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(portId) < fUsedMidiOuts.count(), false); carla_debug("CarlaEngineRtAudio::connectRackMidiOutPort(%i)", portId); - const char* const portName(fUsedMidiOuts.getAt(static_cast(portId)).name); + const PortNameToId fallback = { 0, { '\0' } }; + const char* const portName(fUsedMidiOuts.getAt(static_cast(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(); diff --git a/source/backend/plugin/BridgePlugin.cpp b/source/backend/plugin/BridgePlugin.cpp index 7b36fbc6e..593b5b7a1 100644 --- a/source/backend/plugin/BridgePlugin.cpp +++ b/source/backend/plugin/BridgePlugin.cpp @@ -851,9 +851,9 @@ public: if (pData->extNotes.mutex.tryLock()) { - for (; ! pData->extNotes.data.isEmpty();) + for (RtLinkedList::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) diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 5adf6ff44..5b22935d2 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -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::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(); } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/CarlaPluginInternal.cpp b/source/backend/plugin/CarlaPluginInternal.cpp index 5ac83b527..1dc48617e 100644 --- a/source/backend/plugin/CarlaPluginInternal.cpp +++ b/source/backend/plugin/CarlaPluginInternal.cpp @@ -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); diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index 3d31dc671..374c090d3 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -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 }; diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index 9af2b1e7f..936aa182d 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -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); diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index 3b374170a..afb6eb493 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -1094,9 +1094,9 @@ public: if (pData->extNotes.mutex.tryLock()) { - while (! pData->extNotes.data.isEmpty()) + for (RtLinkedList::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) diff --git a/source/backend/plugin/JucePlugin.cpp b/source/backend/plugin/JucePlugin.cpp index 12cd6aee2..58f70a3dd 100644 --- a/source/backend/plugin/JucePlugin.cpp +++ b/source/backend/plugin/JucePlugin.cpp @@ -589,9 +589,9 @@ public: if (pData->extNotes.mutex.tryLock()) { - for (; ! pData->extNotes.data.isEmpty();) + for (RtLinkedList::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) diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 7441cbe30..fad895cd2 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -756,9 +756,9 @@ public: if (pData->extNotes.mutex.tryLock()) { - while (! pData->extNotes.data.isEmpty()) + for (RtLinkedList::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(note.channel)); } + pData->extNotes.data.clear(); pData->extNotes.mutex.unlock(); } // End of MIDI Input (External) diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index cba3873b1..4f24c1550 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -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::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(i), fCustomURIDs.getAt(i)); + osc_send_lv2_urid_map(pData->osc.data, static_cast(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(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); } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index 18551de46..1be7d7138 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -1355,9 +1355,12 @@ public: if (pData->extNotes.mutex.tryLock()) { + ExternalMidiNote note = { 0, 0, 0 }; + + //for (RtLinkedList::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); } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 76df6fa02..36b35b1f6 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -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); diff --git a/source/modules/native-plugins/zynaddsubfx-synth.cpp b/source/modules/native-plugins/zynaddsubfx-synth.cpp index a60e400f9..172780c7a 100644 --- a/source/modules/native-plugins/zynaddsubfx-synth.cpp +++ b/source/modules/native-plugins/zynaddsubfx-synth.cpp @@ -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; diff --git a/source/utils/LinkedList.hpp b/source/utils/LinkedList.hpp index 3b186bce7..a1cf58304 100644 --- a/source/utils/LinkedList.hpp +++ b/source/utils/LinkedList.hpp @@ -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);