diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 46cb3256e..f79ddc35c 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -44,7 +44,8 @@ public: fRdfDescriptor(nullptr), fAudioInBuffers(nullptr), fAudioOutBuffers(nullptr), - fParamBuffers(nullptr) + fParamBuffers(nullptr), + fLatencyIndex(-1) { carla_debug("LadspaPlugin::LadspaPlugin(%p, %i)", engine, id); } @@ -189,7 +190,8 @@ public: if (! isDssiVst) { - options |= PLUGIN_OPTION_FIXED_BUFFERS; + if (fLatencyIndex == -1) + options |= PLUGIN_OPTION_FIXED_BUFFERS; if (pData->engine->getProccessMode() != ENGINE_PROCESS_MODE_CONTINUOUS_RACK) { @@ -669,6 +671,7 @@ public: step = 1.0f; stepSmall = 1.0f; stepLarge = 1.0f; + fLatencyIndex = static_cast(j); pData->param.special[j] = PARAMETER_SPECIAL_LATENCY; } else @@ -779,60 +782,55 @@ public: pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK; // check latency -#ifdef BUILD_BRIDGE - if (aIns > 0 && aOuts > 0) -#else - if (pData->hints & PLUGIN_CAN_DRYWET) -#endif + if (fLatencyIndex >= 0) { - for (uint32_t i=0; i < pData->param.count; ++i) - { - if (pData->param.special[i] != PARAMETER_SPECIAL_LATENCY) - continue; + // we need to pre-run the plugin so it can update its latency control-port - // we need to pre-run the plugin so it can update its latency control-port + float tmpIn[aIns][2]; + float tmpOut[aOuts][2]; - float tmpIn[aIns][2]; - float tmpOut[aOuts][2]; + for (uint32_t j=0; j < aIns; ++j) + { + tmpIn[j][0] = 0.0f; + tmpIn[j][1] = 0.0f; - for (uint32_t j=0; j < aIns; ++j) - { - tmpIn[j][0] = 0.0f; - tmpIn[j][1] = 0.0f; + fDescriptor->connect_port(fHandle, pData->audioIn.ports[j].rindex, tmpIn[j]); + } - fDescriptor->connect_port(fHandle, pData->audioIn.ports[j].rindex, tmpIn[j]); - } + for (uint32_t j=0; j < aOuts; ++j) + { + tmpOut[j][0] = 0.0f; + tmpOut[j][1] = 0.0f; - for (uint32_t j=0; j < aOuts; ++j) - { - tmpOut[j][0] = 0.0f; - tmpOut[j][1] = 0.0f; + fDescriptor->connect_port(fHandle, pData->audioOut.ports[j].rindex, tmpOut[j]); + } - fDescriptor->connect_port(fHandle, pData->audioOut.ports[j].rindex, tmpOut[j]); - } + if (fDescriptor->activate != nullptr) + fDescriptor->activate(fHandle); - if (fDescriptor->activate != nullptr) - fDescriptor->activate(fHandle); + fDescriptor->run(fHandle, 2); - fDescriptor->run(fHandle, 2); + if (fDescriptor->deactivate != nullptr) + fDescriptor->deactivate(fHandle); - if (fDescriptor->deactivate != nullptr) - fDescriptor->deactivate(fHandle); + const int32_t latency(static_cast(fParamBuffers[fLatencyIndex])); - // TODO: check >= 0 - const uint32_t latency = (uint32_t)fParamBuffers[i]; + if (latency >= 0) + { + const uint32_t ulatency(static_cast(latency)); - if (pData->latency != latency) + if (pData->latency != ulatency) { - pData->latency = latency; - pData->client->setLatency(latency); + pData->latency = ulatency; + pData->client->setLatency(ulatency); + carla_stdout("latency = %i", latency); #ifndef BUILD_BRIDGE pData->recreateLatencyBuffers(); #endif } - - break; } + else + carla_safe_assert_int("latency >= 0", __FILE__, __LINE__, latency); } bufferSizeChanged(pData->engine->getBufferSize()); @@ -1073,7 +1071,27 @@ public: } // End of Plugin processing (no events) - CARLA_PROCESS_CONTINUE_CHECK; + // -------------------------------------------------------------------------------------------------------- + // Latency, save values for next callback + + if (pData->latency > 0) + { + if (pData->latency <= frames) + { + 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]; + } + } + } // -------------------------------------------------------------------------------------------------------- // Control Output @@ -1157,6 +1175,7 @@ public: { const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && pData->postProc.dryWet != 1.0f; const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && (pData->postProc.balanceLeft != -1.0f || pData->postProc.balanceRight != 1.0f); + const bool isMono = (pData->audioIn.count == 1); bool isPair; float bufValue, oldBufLeft[doBalance ? frames : 1]; @@ -1168,13 +1187,13 @@ public: { for (uint32_t k=0; k < frames; ++k) { - // TODO - //if (k < pData->latency && pData->latency < frames) - // bufValue = (pData->audioIn.count == 1) ? pData->latencyBuffers[0][k] : pData->latencyBuffers[i][k]; - //else - // bufValue = (pData->audioIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency]; + if (k < pData->latency) + bufValue = pData->latencyBuffers[isMono ? 0 : i][k]; + else if (pData->latency < frames) + bufValue = fAudioInBuffers[isMono ? 0 : i][k-pData->latency]; + else + bufValue = fAudioInBuffers[isMono ? 0 : i][k]; - bufValue = fAudioInBuffers[(pData->audioIn.count == 1) ? 0 : i][k]; fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); } } @@ -1217,14 +1236,6 @@ public: } } -#if 0 - // Latency, save values for next callback, TODO - if (pData->latency > 0 && pData->latency < frames) - { - for (i=0; i < pData->audioIn.count; ++i) - FLOAT_COPY(pData->latencyBuffers[i], inBuffer[i] + (frames - pData->latency), pData->latency); - } -#endif } // End of Post-processing #else // BUILD_BRIDGE @@ -1481,7 +1492,7 @@ public: // set default options pData->options = 0x0; - if (isDssiVst) + if (fLatencyIndex >= 0 || isDssiVst) pData->options |= PLUGIN_OPTION_FIXED_BUFFERS; if (pData->engine->getOptions().forceStereo) @@ -1499,7 +1510,7 @@ public: pData->options = pData->loadSettings(pData->options, getOptionsAvailable()); // ignore settings, we need this anyway - if (isDssiVst) + if (fLatencyIndex >= 0 || isDssiVst) pData->options |= PLUGIN_OPTION_FIXED_BUFFERS; #endif } @@ -1518,6 +1529,7 @@ private: float** fAudioInBuffers; float** fAudioOutBuffers; float* fParamBuffers; + int32_t fLatencyIndex; // -1 if invalid CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LadspaPlugin) };