diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index 44541f6de..c8419d355 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -49,6 +49,7 @@ public: fAudioInBuffers(nullptr), fAudioOutBuffers(nullptr), fParamBuffers(nullptr), + fLatencyChanged(false), fLatencyIndex(-1) { carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id); @@ -421,6 +422,36 @@ public: } } + void idle() override + { + if (fLatencyChanged && fLatencyIndex != -1) + { + fLatencyChanged = false; + + const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); + + if (latency >= 0) + { + const uint32_t ulatency(static_cast(latency)); + + if (pData->latency != ulatency) + { + carla_stdout("latency changed to %i", latency); + + const ScopedSingleProcessLocker sspl(this, true); + + pData->latency = ulatency; + pData->client->setLatency(ulatency); +#ifndef BUILD_BRIDGE + pData->recreateLatencyBuffers(); +#endif + } + } + else + carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + } + } + // ------------------------------------------------------------------- // Plugin state @@ -896,6 +927,8 @@ public: } else carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + + fLatencyChanged = false; } bufferSizeChanged(pData->engine->getBufferSize()); @@ -1020,29 +1053,6 @@ public: } CARLA_SAFE_EXCEPTION("DSSI activate #2"); } } - - if (fLatencyIndex < 0) - return; - - const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); - CARLA_SAFE_ASSERT_RETURN(latency >= 0,); - - const uint32_t ulatency(static_cast(latency)); - - if (pData->latency != ulatency) - { - carla_stdout("latency changed to %i", latency); - - pData->latency = ulatency; - pData->client->setLatency(ulatency); -#ifndef BUILD_BRIDGE - try { - pData->recreateLatencyBuffers(); // FIXME - } CARLA_SAFE_EXCEPTION("DSSI recreateLatencyBuffers()"); -#endif - } - else - carla_stdout("latency still the same %i", latency); } void deactivate() noexcept override @@ -1510,21 +1520,28 @@ public: // -------------------------------------------------------------------------------------------------------- // Latency, save values for next callback - if (pData->latency > 0) + if (fLatencyIndex != -1) { - if (pData->latency <= frames) + if (pData->latency != static_cast(fParamBuffers[fLatencyIndex])) { - for (uint32_t i=0; i < pData->audioIn.count; ++i) - FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + fLatencyChanged = true; } - else + else if (pData->latency > 0) { - for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + if (pData->latency <= frames) { - for (k=0; k < pData->latency-frames; ++k) - pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; - for (j=0; k < pData->latency; ++j, ++k) - pData->latencyBuffers[i][k] = inBuffer[i][j]; + for (uint32_t i=0; i < pData->audioIn.count; ++i) + FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + } + else + { + for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + { + for (k=0; k < pData->latency-frames; ++k) + pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; + for (j=0; k < pData->latency; ++j, ++k) + pData->latencyBuffers[i][k] = inBuffer[i][j]; + } } } } @@ -2155,6 +2172,8 @@ private: float** fAudioInBuffers; float** fAudioOutBuffers; float* fParamBuffers; + + bool fLatencyChanged; int32_t fLatencyIndex; // -1 if invalid snd_seq_event_t fMidiEvents[kPluginMaxMidiEvents]; diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index aff43c66d..41c698a2e 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -45,6 +45,7 @@ public: fAudioInBuffers(nullptr), fAudioOutBuffers(nullptr), fParamBuffers(nullptr), + fLatencyChanged(false), fLatencyIndex(-1) { carla_debug("LadspaPlugin::LadspaPlugin(%p, %i)", engine, id); @@ -407,7 +408,35 @@ public: // ------------------------------------------------------------------- // Set ui stuff - // nothing + void idle() override + { + if (fLatencyChanged && fLatencyIndex != -1) + { + fLatencyChanged = false; + + const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); + + if (latency >= 0) + { + const uint32_t ulatency(static_cast(latency)); + + if (pData->latency != ulatency) + { + carla_stdout("latency changed to %i", latency); + + const ScopedSingleProcessLocker sspl(this, true); + + pData->latency = ulatency; + pData->client->setLatency(ulatency); +#ifndef BUILD_BRIDGE + pData->recreateLatencyBuffers(); +#endif + } + } + else + carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + } + } // ------------------------------------------------------------------- // Plugin state @@ -867,6 +896,8 @@ public: } else carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + + fLatencyChanged = false; } bufferSizeChanged(pData->engine->getBufferSize()); @@ -898,29 +929,6 @@ public: } CARLA_SAFE_EXCEPTION("LADSPA activate #2"); } } - - if (fLatencyIndex < 0) - return; - - const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); - CARLA_SAFE_ASSERT_RETURN(latency >= 0,); - - const uint32_t ulatency(static_cast(latency)); - - if (pData->latency != ulatency) - { - carla_stdout("latency changed to %i", latency); - - pData->latency = ulatency; - pData->client->setLatency(ulatency); -#ifndef BUILD_BRIDGE - try { - pData->recreateLatencyBuffers(); // FIXME - } CARLA_SAFE_EXCEPTION("LADSPA recreateLatencyBuffers()"); -#endif - } - else - carla_stdout("latency still the same %i", latency); } void deactivate() noexcept override @@ -1134,21 +1142,28 @@ public: // -------------------------------------------------------------------------------------------------------- // Latency, save values for next callback - if (pData->latency > 0) + if (fLatencyIndex != -1) { - if (pData->latency <= frames) + if (pData->latency != static_cast(fParamBuffers[fLatencyIndex])) { - for (uint32_t i=0; i < pData->audioIn.count; ++i) - FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + fLatencyChanged = true; } - else + else if (pData->latency > 0) { - for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + if (pData->latency <= frames) { - for (k=0; k < pData->latency-frames; ++k) - pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; - for (j=0; k < pData->latency; ++j, ++k) - pData->latencyBuffers[i][k] = inBuffer[i][j]; + for (uint32_t i=0; i < pData->audioIn.count; ++i) + FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + } + else + { + for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + { + for (k=0; k < pData->latency-frames; ++k) + pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; + for (j=0; k < pData->latency; ++j, ++k) + pData->latencyBuffers[i][k] = inBuffer[i][j]; + } } } } @@ -1638,6 +1653,8 @@ private: float** fAudioInBuffers; float** fAudioOutBuffers; float* fParamBuffers; + + bool fLatencyChanged; int32_t fLatencyIndex; // -1 if invalid // ------------------------------------------------------------------- diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 46e822682..2007cfb39 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -398,6 +398,7 @@ public: fCvInBuffers(nullptr), fCvOutBuffers(nullptr), fParamBuffers(nullptr), + fLatencyChanged(false), fLatencyIndex(-1), fFirstActive(true) { @@ -1287,11 +1288,13 @@ public: { if (! fAtomQueueOut.isEmpty()) { + fAtomQueueOut.lock(); char dumpBuf[fAtomQueueOut.getSize()]; Lv2AtomQueue tmpQueue; tmpQueue.copyAndDumpDataFromQueue(fAtomQueueOut, dumpBuf); CARLA_SAFE_ASSERT(! tmpQueue.isEmpty()); + fAtomQueueOut.unlock(); uint32_t portIndex; const LV2_Atom* atom; @@ -1320,6 +1323,33 @@ public: } } + if (fLatencyChanged && fLatencyIndex != -1) + { + fLatencyChanged = false; + + const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); + + if (latency >= 0) + { + const uint32_t ulatency(static_cast(latency)); + + if (pData->latency != ulatency) + { + carla_stdout("latency changed to %i", latency); + + const ScopedSingleProcessLocker sspl(this, true); + + pData->latency = ulatency; + pData->client->setLatency(ulatency); +#ifndef BUILD_BRIDGE + pData->recreateLatencyBuffers(); +#endif + } + } + else + carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + } + if (fUi.handle != nullptr && fUi.descriptor != nullptr) { if (fUi.type == UI::TYPE_EXTERNAL && fUi.widget != nullptr) @@ -2218,6 +2248,8 @@ public: } else carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); + + fLatencyChanged = false; } bufferSizeChanged(pData->engine->getBufferSize()); @@ -2376,29 +2408,6 @@ public: } fFirstActive = true; - - if (fLatencyIndex < 0) - return; - - const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); - CARLA_SAFE_ASSERT_RETURN(latency >= 0,); - - const uint32_t ulatency(static_cast(latency)); - - if (pData->latency != ulatency) - { - carla_stdout("latency changed to %i", latency); - - pData->latency = ulatency; - pData->client->setLatency(ulatency); -#ifndef BUILD_BRIDGE - try { - pData->recreateLatencyBuffers(); // FIXME - } CARLA_SAFE_EXCEPTION("LADSPA recreateLatencyBuffers()"); -#endif - } - else - carla_stdout("latency still the same %i", latency); } void deactivate() noexcept override @@ -3116,21 +3125,28 @@ public: // -------------------------------------------------------------------------------------------------------- // Latency, save values for next callback - if (pData->latency > 0) + if (fLatencyIndex != -1) { - if (pData->latency <= frames) + if (pData->latency != static_cast(fParamBuffers[fLatencyIndex])) { - for (uint32_t i=0; i < pData->audioIn.count; ++i) - FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + fLatencyChanged = true; } - else + else if (pData->latency > 0) { - for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + if (pData->latency <= frames) { - for (k=0; k < pData->latency-frames; ++k) - pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; - for (j=0; k < pData->latency; ++j, ++k) - pData->latencyBuffers[i][k] = inBuffer[i][j]; + for (uint32_t i=0; i < pData->audioIn.count; ++i) + FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), pData->latency); + } + else + { + for (uint32_t i=0, j, k; i < pData->audioIn.count; ++i) + { + for (k=0; k < pData->latency-frames; ++k) + pData->latencyBuffers[i][k] = pData->latencyBuffers[i][k+frames]; + for (j=0; k < pData->latency; ++j, ++k) + pData->latencyBuffers[i][k] = inBuffer[i][j]; + } } } } @@ -5209,6 +5225,8 @@ private: float** fCvInBuffers; float** fCvOutBuffers; float* fParamBuffers; + + bool fLatencyChanged; int32_t fLatencyIndex; // -1 if invalid Lv2AtomQueue fAtomQueueIn; diff --git a/source/utils/Lv2AtomQueue.hpp b/source/utils/Lv2AtomQueue.hpp index 18f32234b..d093acdcc 100644 --- a/source/utils/Lv2AtomQueue.hpp +++ b/source/utils/Lv2AtomQueue.hpp @@ -259,8 +259,7 @@ public: // used for tmp buffers only void copyAndDumpDataFromQueue(Lv2AtomQueue& queue, char dumpBuf[]) noexcept { - // lock source - const CarlaMutexLocker cml1(queue.fMutex); + // source is locked { // copy data from source