diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 3480e5b10..6c1935501 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -3902,10 +3902,12 @@ public: if (pData->audioIn.count > 0) { CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fAudioInBuffers != nullptr, false); } if (pData->audioOut.count > 0) { CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false); } if (pData->cvIn.count > 0) { diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp index 59e027284..b5078111f 100644 --- a/source/backend/plugin/CarlaPluginVST2.cpp +++ b/source/backend/plugin/CarlaPluginVST2.cpp @@ -87,6 +87,7 @@ public: #endif fFirstActive(true), fBufferSize(engine->getBufferSize()), + fAudioOutBuffers(nullptr), fLastTimeInfo(), fEvents(), fUI(), @@ -639,7 +640,11 @@ public: if (aOuts > 0) { pData->audioOut.createNew(aOuts); + fAudioOutBuffers = new float*[aOuts]; needsCtrlIn = true; + + for (uint32_t i=0; i < aOuts; ++i) + fAudioOutBuffers[i] = nullptr; } if (params > 0) @@ -942,7 +947,7 @@ public: #endif } - //bufferSizeChanged(pData->engine->getBufferSize()); + bufferSizeChanged(pData->engine->getBufferSize()); reloadPrograms(true); if (pData->active) @@ -1595,6 +1600,7 @@ public: if (pData->audioOut.count > 0) { CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -1622,12 +1628,12 @@ public: // Set audio buffers float* vstInBuffer[pData->audioIn.count]; - float* vstOutBuffer[pData->audioOut.count]; for (uint32_t i=0; i < pData->audioIn.count; ++i) vstInBuffer[i] = const_cast(inBuffer[i]+timeOffset); + for (uint32_t i=0; i < pData->audioOut.count; ++i) - vstOutBuffer[i] = outBuffer[i]+timeOffset; + carla_zeroFloats(fAudioOutBuffers[i], frames); // -------------------------------------------------------------------------------------------------------- // Set MIDI events @@ -1646,15 +1652,18 @@ public: if (pData->hints & PLUGIN_CAN_PROCESS_REPLACING) { - fEffect->processReplacing(fEffect, (pData->audioIn.count > 0) ? vstInBuffer : nullptr, (pData->audioOut.count > 0) ? vstOutBuffer : nullptr, static_cast(frames)); + fEffect->processReplacing(fEffect, + (pData->audioIn.count > 0) ? vstInBuffer : nullptr, + (pData->audioOut.count > 0) ? fAudioOutBuffers : nullptr, + static_cast(frames)); } else { - for (uint32_t i=0; i < pData->audioOut.count; ++i) - carla_zeroFloats(vstOutBuffer[i], frames); - #if ! VST_FORCE_DEPRECATED - fEffect->process(fEffect, (pData->audioIn.count > 0) ? vstInBuffer : nullptr, (pData->audioOut.count > 0) ? vstOutBuffer : nullptr, static_cast(frames)); + fEffect->process(fEffect, + (pData->audioIn.count > 0) ? vstInBuffer : nullptr, + (pData->audioOut.count > 0) ? fAudioOutBuffers : nullptr, + static_cast(frames)); #endif } @@ -1666,9 +1675,9 @@ public: // Post-processing (dry/wet, volume and balance) { - const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && carla_isNotEqual(pData->postProc.volume, 1.0f); const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f); const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f)); + const bool isMono = (pData->audioIn.count == 1); bool isPair; float bufValue, oldBufLeft[doBalance ? frames : 1]; @@ -1678,10 +1687,12 @@ public: // Dry/Wet if (doDryWet) { + const uint32_t c = isMono ? 0 : i; + for (uint32_t k=0; k < frames; ++k) { - bufValue = inBuffer[(pData->audioIn.count == 1) ? 0 : i][k+timeOffset]; - outBuffer[i][k+timeOffset] = (outBuffer[i][k+timeOffset] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); + bufValue = inBuffer[c][k+timeOffset]; + fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); } } @@ -1693,7 +1704,7 @@ public: if (isPair) { CARLA_ASSERT(i+1 < pData->audioOut.count); - carla_copyFloats(oldBufLeft, outBuffer[i]+timeOffset, frames); + carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames); } float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f; @@ -1704,27 +1715,32 @@ public: if (isPair) { // left - outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL); - outBuffer[i][k+timeOffset] += outBuffer[i+1][k+timeOffset] * (1.0f - balRangeR); + fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL); + fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR); } else { // right - outBuffer[i][k+timeOffset] = outBuffer[i][k+timeOffset] * balRangeR; - outBuffer[i][k+timeOffset] += oldBufLeft[k] * balRangeL; + fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR; + fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL; } } } - // Volume - if (doVolume) + // Volume (and buffer copy) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] *= pData->postProc.volume; + outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } } // End of Post-processing +#else // BUILD_BRIDGE_ALTERNATIVE_ARCH + for (uint32_t i=0; i < pData->audioOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k]; + } #endif // -------------------------------------------------------------------------------------------------------- @@ -1743,6 +1759,13 @@ public: if (pData->active) deactivate(); + for (uint32_t i=0; i < pData->audioOut.count; ++i) + { + if (fAudioOutBuffers[i] != nullptr) + delete[] fAudioOutBuffers[i]; + fAudioOutBuffers[i] = new float[newBufferSize]; + } + #if ! VST_FORCE_DEPRECATED dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast(newBufferSize), nullptr, static_cast(pData->engine->getSampleRate())); #endif @@ -1772,7 +1795,29 @@ public: // ------------------------------------------------------------------- // Plugin buffers - // nothing + void clearBuffers() noexcept override + { + carla_debug("CarlaPluginVST2::clearBuffers() - start"); + + if (fAudioOutBuffers != nullptr) + { + for (uint32_t i=0; i < pData->audioOut.count; ++i) + { + if (fAudioOutBuffers[i] != nullptr) + { + delete[] fAudioOutBuffers[i]; + fAudioOutBuffers[i] = nullptr; + } + } + + delete[] fAudioOutBuffers; + fAudioOutBuffers = nullptr; + } + + CarlaPlugin::clearBuffers(); + + carla_debug("CarlaPluginVST2::clearBuffers() - end"); + } // ------------------------------------------------------------------- // Post-poned UI Stuff @@ -2443,6 +2488,7 @@ private: bool fFirstActive; // first process() call after activate() uint32_t fBufferSize; + float** fAudioOutBuffers; EngineTimeInfo fLastTimeInfo; struct FixedVstEvents {