From dac744cd0cce13e7ddb07fda7baae99db89e5768 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 5 Sep 2014 15:31:06 +0100 Subject: [PATCH] Pass CV buffers directly in plugin process function --- source/backend/CarlaPlugin.hpp | 3 +- source/backend/engine/CarlaEngineGraph.cpp | 10 +- source/backend/engine/CarlaEngineJack.cpp | 48 +++++--- source/backend/plugin/BridgePlugin.cpp | 92 +++++++++++---- source/backend/plugin/DssiPlugin.cpp | 88 +++++++++++--- source/backend/plugin/FluidSynthPlugin.cpp | 8 +- source/backend/plugin/JucePlugin.cpp | 6 +- source/backend/plugin/LadspaPlugin.cpp | 88 +++++++++++--- source/backend/plugin/LinuxSamplerPlugin.cpp | 8 +- source/backend/plugin/Lv2Plugin.cpp | 89 +++++++++------ source/backend/plugin/NativePlugin.cpp | 114 +++++++++++++------ source/backend/plugin/VstPlugin.cpp | 14 +-- source/utils/CarlaBridgeUtils.hpp | 3 + 13 files changed, 403 insertions(+), 168 deletions(-) diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index fbf6fa9ce..d74892190 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -662,7 +662,8 @@ public: /*! * Plugin process call. */ - virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) = 0; + virtual void process(const float** const audioIn, float** const audioOut, + const float** const cvIn, float** const cvOut, const uint32_t frames) = 0; /*! * Tell the plugin the current buffer size changed. diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index 3961f6513..e74a6f731 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -553,7 +553,7 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB // safe copy float inBuf0[frames]; float inBuf1[frames]; - float* inBuf[2] = { inBuf0, inBuf1 }; + const float* inBuf[2] = { inBuf0, inBuf1 }; // initialize audio inputs FloatVectorOperations::copy(inBuf0, inBufReal[0], iframes); @@ -613,7 +613,7 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB // process plugin->initBuffers(); - plugin->process(inBuf, outBuf, frames); + plugin->process(inBuf, outBuf, nullptr, nullptr, frames); plugin->unlock(); // if plugin has no audio inputs, add input buffer @@ -985,6 +985,8 @@ public: midi.clear(); + // TODO - CV support + const uint32_t bufferSize(static_cast(audio.getNumSamples())); if (const int numChan = audio.getNumChannels()) @@ -1011,7 +1013,7 @@ public: } } - fPlugin->process(audioBuffers, audioBuffers, bufferSize); + fPlugin->process(const_cast(audioBuffers), audioBuffers, nullptr, nullptr, bufferSize); for (int i=0; iprocess(nullptr, nullptr, bufferSize); + fPlugin->process(nullptr, nullptr, nullptr, nullptr, bufferSize); } midi.clear(); diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index d8c222e96..3abe455d9 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1955,45 +1955,61 @@ private: void processPlugin(CarlaPlugin* const plugin, const uint32_t nframes) { - const uint32_t inCount(plugin->getAudioInCount()); - const uint32_t outCount(plugin->getAudioOutCount()); + const uint32_t audioInCount(plugin->getAudioInCount()); + const uint32_t audioOutCount(plugin->getAudioOutCount()); + const uint32_t cvInCount(plugin->getCVInCount()); + const uint32_t cvOutCount(plugin->getCVOutCount()); - float* inBuffer[inCount]; - float* outBuffer[outCount]; + const float* audioIn[audioInCount]; + /* */ float* audioOut[audioOutCount]; + const float* cvIn[cvInCount]; + /* */ float* cvOut[cvOutCount]; - float inPeaks[2] = { 0.0f }; - float outPeaks[2] = { 0.0f }; - - for (uint32_t i=0; i < inCount; ++i) + for (uint32_t i=0; i < audioInCount; ++i) { CarlaEngineAudioPort* const port(plugin->getAudioInPort(i)); - inBuffer[i] = port->getBuffer(); + audioIn[i] = port->getBuffer(); } - for (uint32_t i=0; i < outCount; ++i) + for (uint32_t i=0; i < audioOutCount; ++i) { CarlaEngineAudioPort* const port(plugin->getAudioOutPort(i)); - outBuffer[i] = port->getBuffer(); + audioOut[i] = port->getBuffer(); + } + + for (uint32_t i=0; i < cvInCount; ++i) + { + CarlaEngineCVPort* const port(plugin->getCVInPort(i)); + cvIn[i] = port->getBuffer(); } - for (uint32_t i=0; i < inCount && i < 2; ++i) + for (uint32_t i=0; i < cvOutCount; ++i) + { + CarlaEngineCVPort* const port(plugin->getCVOutPort(i)); + cvOut[i] = port->getBuffer(); + } + + float inPeaks[2] = { 0.0f }; + float outPeaks[2] = { 0.0f }; + + for (uint32_t i=0; i < audioInCount && i < 2; ++i) { for (uint32_t j=0; j < nframes; ++j) { - const float absV(std::abs(inBuffer[i][j])); + const float absV(std::abs(audioIn[i][j])); if (absV > inPeaks[i]) inPeaks[i] = absV; } } - plugin->process(inBuffer, outBuffer, nframes); + plugin->process(audioIn, audioOut, cvIn, cvOut, nframes); - for (uint32_t i=0; i < outCount && i < 2; ++i) + for (uint32_t i=0; i < audioOutCount && i < 2; ++i) { for (uint32_t j=0; j < nframes; ++j) { - const float absV(std::abs(outBuffer[i][j])); + const float absV(std::abs(audioOut[i][j])); if (absV > outPeaks[i]) outPeaks[i] = absV; diff --git a/source/backend/plugin/BridgePlugin.cpp b/source/backend/plugin/BridgePlugin.cpp index aaaa54e50..8d40b7ced 100644 --- a/source/backend/plugin/BridgePlugin.cpp +++ b/source/backend/plugin/BridgePlugin.cpp @@ -345,6 +345,7 @@ public: fLastPongCounter(-1), fBridgeBinary(), fShmAudioPool(), + fShmCVPool(), fShmRtControl(), fShmNonRtControl(), fInfo(), @@ -923,7 +924,7 @@ public: fTimedOut = false; } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -932,7 +933,9 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return; } @@ -1158,20 +1161,28 @@ public: } // End of Event Input - processSingle(inBuffer, outBuffer, frames); + processSingle(audioIn, audioOut, cvIn, cvOut, frames); } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames) + bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) { CARLA_SAFE_ASSERT_RETURN(frames > 0, false); if (pData->audioIn.count > 0) { - CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); + } + if (pData->cvIn.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); + } + if (pData->cvOut.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -1184,17 +1195,20 @@ public: else if (! pData->singleMutex.tryLock()) { for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return false; } // -------------------------------------------------------------------------------------------------------- // Reset audio buffers - //std::memset(fShmAudioPool.data, 0, fShmAudioPool.size); - for (uint32_t i=0; i < fInfo.aIns; ++i) - FloatVectorOperations::copy(fShmAudioPool.data + (i * frames), inBuffer[i], static_cast(frames)); + FloatVectorOperations::copy(fShmAudioPool.data + (i * frames), audioIn[i], static_cast(frames)); + + for (uint32_t i=0; i < fInfo.cvIns; ++i) + FloatVectorOperations::copy(fShmCVPool.data + (i * frames), cvIn[i], static_cast(frames)); // -------------------------------------------------------------------------------------------------------- // TimeInfo @@ -1236,7 +1250,10 @@ public: } for (uint32_t i=0; i < fInfo.aOuts; ++i) - FloatVectorOperations::copy(outBuffer[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), static_cast(frames)); + FloatVectorOperations::copy(audioOut[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), static_cast(frames)); + + for (uint32_t i=0; i < fInfo.cvOuts; ++i) + FloatVectorOperations::copy(cvOut[i], fShmCVPool.data + ((i + fInfo.cvIns) * frames), static_cast(frames)); // -------------------------------------------------------------------------------------------------------- // Post-processing (dry/wet, volume and balance) @@ -1256,8 +1273,8 @@ public: { for (uint32_t k=0; k < frames; ++k) { - bufValue = inBuffer[(pData->audioIn.count == 1) ? 0 : i][k]; - outBuffer[i][k] = (outBuffer[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); + bufValue = audioIn[(pData->audioIn.count == 1) ? 0 : i][k]; + audioOut[i][k] = (audioOut[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); } } @@ -1269,7 +1286,7 @@ public: if (isPair) { CARLA_ASSERT(i+1 < pData->audioOut.count); - FloatVectorOperations::copy(oldBufLeft, outBuffer[i], static_cast(frames)); + FloatVectorOperations::copy(oldBufLeft, audioOut[i], static_cast(frames)); } float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f; @@ -1280,14 +1297,14 @@ public: if (isPair) { // left - outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL); - outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR); + audioOut[i][k] = oldBufLeft[k] * (1.0f - balRangeL); + audioOut[i][k] += audioOut[i+1][k] * (1.0f - balRangeR); } else { // right - outBuffer[i][k] = outBuffer[i][k] * balRangeR; - outBuffer[i][k] += oldBufLeft[k] * balRangeL; + audioOut[i][k] = audioOut[i][k] * balRangeR; + audioOut[i][k] += oldBufLeft[k] * balRangeL; } } } @@ -1296,7 +1313,7 @@ public: if (doVolume) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k] *= pData->postProc.volume; + audioOut[i][k] *= pData->postProc.volume; } } @@ -1310,7 +1327,7 @@ public: void bufferSizeChanged(const uint32_t newBufferSize) override { - resizeAudioPool(newBufferSize); + resizeAudioAndCVPool(newBufferSize); { const CarlaMutexLocker _cml(fShmNonRtControl.mutex); @@ -2126,11 +2143,13 @@ private: CarlaString fBridgeBinary; BridgeAudioPool fShmAudioPool; + BridgeAudioPool fShmCVPool; BridgeRtControl fShmRtControl; BridgeNonRtControl fShmNonRtControl; struct Info { uint32_t aIns, aOuts; + uint32_t cvIns, cvOuts; uint32_t mIns, mOuts; PluginCategory category; uint optionsAvailable; @@ -2144,6 +2163,8 @@ private: Info() : aIns(0), aOuts(0), + cvIns(0), + cvOuts(0), mIns(0), mOuts(0), category(PLUGIN_CATEGORY_NONE), @@ -2158,12 +2179,17 @@ private: BridgeParamInfo* fParams; - void resizeAudioPool(const uint32_t bufferSize) + void resizeAudioAndCVPool(const uint32_t bufferSize) { fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts); + fShmCVPool.resize(bufferSize, fInfo.cvIns+fInfo.cvOuts); fShmRtControl.writeOpcode(kPluginBridgeRtSetAudioPool); fShmRtControl.writeLong(static_cast(fShmAudioPool.size)); + + fShmRtControl.writeOpcode(kPluginBridgeRtSetCVPool); + fShmRtControl.writeLong(static_cast(fShmCVPool.size)); + fShmRtControl.commitWrite(); waitForServer(); @@ -2216,9 +2242,29 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P plugin->reload(); - if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) + bool canRun = true; + + if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) + { + if (! plugin->canRunInRack()) + { + init.engine->setLastError("Carla's rack mode can only work with Stereo Bridged plugins, sorry!"); + canRun = false; + } + else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0) + { + init.engine->setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!"); + canRun = false; + } + } + else if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)) + { + init.engine->setLastError("CV ports in patchbay mode is still TODO"); + canRun = false; + } + + if (! canRun) { - init.engine->setLastError("Carla's rack mode can only work with Stereo Bridged plugins, sorry!"); delete plugin; return nullptr; } diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index eb7126874..dc3e82913 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -1076,7 +1076,7 @@ public: } } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -1085,7 +1085,9 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return; } @@ -1196,7 +1198,7 @@ public: if (isSampleAccurate && event.time > timeOffset) { - if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset, midiEventCount)) + if (processSingle(audioIn, audioOut, cvIn, cvOut, event.time - timeOffset, timeOffset, midiEventCount)) { startTime = 0; timeOffset = event.time; @@ -1507,7 +1509,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset, midiEventCount); + processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset, midiEventCount); } // End of Event Input and Processing @@ -1516,7 +1518,7 @@ public: else { - processSingle(inBuffer, outBuffer, frames, 0, midiEventCount); + processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0, midiEventCount); } // End of Plugin processing (no events) @@ -1535,7 +1537,7 @@ public: if (pData->latency <= frames) { for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), static_cast(pData->latency)); + FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast(pData->latency)); } else { @@ -1544,7 +1546,7 @@ public: 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]; + pData->latencyBuffers[i][k] = audioIn[i][j]; } } } @@ -1578,17 +1580,25 @@ public: #endif } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const ulong midiEventCount) + bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames, const uint32_t timeOffset, const ulong midiEventCount) { CARLA_SAFE_ASSERT_RETURN(frames > 0, false); if (pData->audioIn.count > 0) { - CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); + } + if (pData->cvIn.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); + } + if (pData->cvOut.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -1603,21 +1613,37 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = 0.0f; + audioOut[i][k+timeOffset] = 0.0f; + } + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = 0.0f; } return false; } // -------------------------------------------------------------------------------------------------------- - // Reset audio buffers + // Set audio buffers for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(fAudioInBuffers[i], inBuffer[i]+timeOffset, static_cast(frames)); + FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast(frames)); for (uint32_t i=0; i < pData->audioOut.count; ++i) FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast(frames)); +#if 0 + // -------------------------------------------------------------------------------------------------------- + // Set CV buffers + + for (uint32_t i=0; i < pData->cvIn.count; ++i) + FloatVectorOperations::copy(fCvInBuffers[i], cvIn[i]+timeOffset, static_cast(frames)); + + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(fCvOutBuffers[i], static_cast(frames)); +#endif + // -------------------------------------------------------------------------------------------------------- // Run plugin @@ -1710,7 +1736,7 @@ public: // Volume (and buffer copy) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } @@ -1720,7 +1746,15 @@ public: 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]; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k]; + } +#endif + +#if 0 + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = fCvOutBuffers[i][k]; } #endif @@ -2310,9 +2344,29 @@ CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init) plugin->reload(); - if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) + bool canRun = true; + + if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) + { + if (! plugin->canRunInRack()) + { + init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo DSSI plugins, sorry!"); + canRun = false; + } + else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0) + { + init.engine->setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!"); + canRun = false; + } + } + else if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)) + { + init.engine->setLastError("CV ports in patchbay mode is still TODO"); + canRun = false; + } + + if (! canRun) { - init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo DSSI plugins, sorry!"); delete plugin; return nullptr; } diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index fc3ab6281..803426f95 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -1002,7 +1002,7 @@ public: // ------------------------------------------------------------------- // Plugin processing - void process(float** const, float** const outBuffer, const uint32_t frames) override + void process(const float** const, float** const audioOut, const float** const, float** const, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -1011,7 +1011,7 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); return; } @@ -1093,7 +1093,7 @@ public: if (time > timeOffset) { - if (processSingle(outBuffer, time - timeOffset, timeOffset)) + if (processSingle(audioOut, time - timeOffset, timeOffset)) { timeOffset = time; @@ -1330,7 +1330,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(outBuffer, frames - timeOffset, timeOffset); + processSingle(audioOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing diff --git a/source/backend/plugin/JucePlugin.cpp b/source/backend/plugin/JucePlugin.cpp index 86b2fb7e7..47baaa1e7 100644 --- a/source/backend/plugin/JucePlugin.cpp +++ b/source/backend/plugin/JucePlugin.cpp @@ -568,7 +568,7 @@ public: } catch(...) {} } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const, float** const, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -577,7 +577,7 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); return; } @@ -877,7 +877,7 @@ public: // -------------------------------------------------------------------------------------------------------- // Process - processSingle(inBuffer, outBuffer, frames); + processSingle(audioIn, audioOut, frames); // -------------------------------------------------------------------------------------------------------- // MIDI Output diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 9eaaf763b..4efbcafb1 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -946,7 +946,7 @@ public: } } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -955,7 +955,9 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return; } @@ -999,7 +1001,7 @@ public: if (isSampleAccurate && event.time > timeOffset) { - if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset)) + if (processSingle(audioIn, audioOut, cvIn, cvOut, event.time - timeOffset, timeOffset)) timeOffset = event.time; } @@ -1118,7 +1120,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset); + processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing @@ -1127,7 +1129,7 @@ public: else { - processSingle(inBuffer, outBuffer, frames, 0); + processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0); } // End of Plugin processing (no events) @@ -1146,7 +1148,7 @@ public: if (pData->latency <= frames) { for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), static_cast(pData->latency)); + FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast(pData->latency)); } else { @@ -1155,7 +1157,7 @@ public: 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]; + pData->latencyBuffers[i][k] = audioIn[i][j]; } } } @@ -1189,17 +1191,25 @@ public: #endif } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) + bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames, const uint32_t timeOffset) { CARLA_SAFE_ASSERT_RETURN(frames > 0, false); if (pData->audioIn.count > 0) { - CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); + } + if (pData->cvIn.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); + } + if (pData->cvOut.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -1214,21 +1224,37 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = 0.0f; + audioOut[i][k+timeOffset] = 0.0f; + } + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = 0.0f; } return false; } // -------------------------------------------------------------------------------------------------------- - // Reset audio buffers + // Set audio buffers for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(fAudioInBuffers[i], inBuffer[i]+timeOffset, static_cast(frames)); + FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast(frames)); for (uint32_t i=0; i < pData->audioOut.count; ++i) FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast(frames)); +#if 0 + // -------------------------------------------------------------------------------------------------------- + // Set CV buffers + + for (uint32_t i=0; i < pData->cvIn.count; ++i) + FloatVectorOperations::copy(fCvInBuffers[i], cvIn[i]+timeOffset, static_cast(frames)); + + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(fCvOutBuffers[i], static_cast(frames)); +#endif + // -------------------------------------------------------------------------------------------------------- // Run plugin @@ -1307,7 +1333,7 @@ public: // Volume (and buffer copy) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } @@ -1317,7 +1343,15 @@ public: 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]; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k]; + } +#endif + +#if 0 + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = fCvOutBuffers[i][k]; } #endif @@ -1724,9 +1758,29 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const Initializer& init, const LADSPA_RDF_De plugin->reload(); - if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) + bool canRun = true; + + if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) + { + if (! plugin->canRunInRack()) + { + init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo LADSPA plugins, sorry!"); + canRun = false; + } + else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0) + { + init.engine->setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!"); + canRun = false; + } + } + else if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)) + { + init.engine->setLastError("CV ports in patchbay mode is still TODO"); + canRun = false; + } + + if (! canRun) { - init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo LADSPA plugins, sorry!"); delete plugin; return nullptr; } diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 223c0470c..2543d4581 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -730,7 +730,7 @@ public: } #endif - void process(float** const, float** const outBuffer, const uint32_t frames) override + void process(const float** const, float** const audioOut, const float** const, float** const, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -739,7 +739,7 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); return; } @@ -812,7 +812,7 @@ public: if (event.time > timeOffset && sampleAccurate) { - if (processSingle(outBuffer, event.time - timeOffset, timeOffset)) + if (processSingle(audioOut, event.time - timeOffset, timeOffset)) { startTime = 0; timeOffset = event.time; @@ -1024,7 +1024,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(outBuffer, frames - timeOffset, timeOffset); + processSingle(audioOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing } diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 1e206052c..d8bda5a85 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -2450,7 +2450,7 @@ public: } } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -2459,7 +2459,9 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return; } @@ -2726,24 +2728,6 @@ public: carla_copyStruct(fLastTimeInfo, timeInfo); } - // -------------------------------------------------------------------------------------------------------- - // CV ports - - float* cvInBuf[pData->cvIn.count /*> 0 ? pData->cvIn.count : 1*/]; - float* cvOutBuf[pData->cvOut.count /*> 0 ? pData->cvOut.count : 1*/]; - - for (uint32_t i=0; i < pData->cvIn.count; ++i) - { - CARLA_SAFE_ASSERT_CONTINUE(pData->cvIn.ports[i].port != nullptr); - cvInBuf[i] = pData->cvIn.ports[i].port->getBuffer(); - } - - for (uint32_t i=0; i < pData->cvOut.count; ++i) - { - CARLA_SAFE_ASSERT_CONTINUE(pData->cvOut.ports[i].port != nullptr); - cvOutBuf[i] = pData->cvOut.ports[i].port->getBuffer(); - } - // -------------------------------------------------------------------------------------------------------- // Event Input and Processing @@ -2850,7 +2834,7 @@ public: if (isSampleAccurate && event.time > timeOffset) { - if (processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, event.time - timeOffset, timeOffset)) + if (processSingle(audioIn, audioOut, cvIn, cvOut, event.time - timeOffset, timeOffset)) { startTime = 0; timeOffset = event.time; @@ -3127,7 +3111,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames - timeOffset, timeOffset); + processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing @@ -3136,7 +3120,7 @@ public: else { - processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames, 0); + processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0); } // End of Plugin processing (no events) @@ -3155,7 +3139,7 @@ public: if (pData->latency <= frames) { for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(pData->latencyBuffers[i], inBuffer[i]+(frames-pData->latency), static_cast(pData->latency)); + FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast(pData->latency)); } else { @@ -3164,7 +3148,7 @@ public: 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]; + pData->latencyBuffers[i][k] = audioIn[i][j]; } } } @@ -3306,25 +3290,25 @@ public: // -------------------------------------------------------------------------------------------------------- } - bool processSingle(float** const audioInBuf, float** const audioOutBuf, float** const cvInBuf, float** const cvOutBuf, const uint32_t frames, const uint32_t timeOffset) + bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames, const uint32_t timeOffset) { CARLA_SAFE_ASSERT_RETURN(frames > 0, false); if (pData->audioIn.count > 0) { - CARLA_SAFE_ASSERT_RETURN(audioInBuf != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(audioOutBuf != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); } if (pData->cvIn.count > 0) { - CARLA_SAFE_ASSERT_RETURN(cvInBuf != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); } if (pData->cvOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(cvOutBuf != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -3339,7 +3323,12 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) { for (uint32_t k=0; k < frames; ++k) - audioOutBuf[i][k+timeOffset] = 0.0f; + audioOut[i][k+timeOffset] = 0.0f; + } + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = 0.0f; } return false; @@ -3349,7 +3338,7 @@ public: // Set audio buffers for (uint32_t i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(fAudioInBuffers[i], audioInBuf[i]+timeOffset, static_cast(frames)); + FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast(frames)); for (uint32_t i=0; i < pData->audioOut.count; ++i) FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast(frames)); @@ -3358,7 +3347,7 @@ public: // Set CV buffers for (uint32_t i=0; i < pData->cvIn.count; ++i) - FloatVectorOperations::copy(fCvInBuffers[i], cvInBuf[i]+timeOffset, static_cast(frames)); + FloatVectorOperations::copy(fCvInBuffers[i], cvIn[i]+timeOffset, static_cast(frames)); for (uint32_t i=0; i < pData->cvOut.count; ++i) FloatVectorOperations::clear(fCvOutBuffers[i], static_cast(frames)); @@ -3455,7 +3444,7 @@ public: // Volume (and buffer copy) { for (uint32_t k=0; k < frames; ++k) - audioOutBuf[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } } // End of Post-processing @@ -3464,10 +3453,16 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) { for (uint32_t k=0; k < frames; ++k) - audioOutBuf[i][k+timeOffset] = fAudioOutBuffers[i][k]; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k]; } #endif + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = fCvOutBuffers[i][k]; + } + // -------------------------------------------------------------------------------------------------------- pData->singleMutex.unlock(); @@ -5888,9 +5883,29 @@ CarlaPlugin* CarlaPlugin::newLV2(const Initializer& init) plugin->reload(); - if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) + bool canRun = true; + + if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) + { + if (! plugin->canRunInRack()) + { + init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo LV2 plugins, sorry!"); + canRun = false; + } + else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0) + { + init.engine->setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!"); + canRun = false; + } + } + else if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)) + { + init.engine->setLastError("CV ports in patchbay mode is still TODO"); + canRun = false; + } + + if (! canRun) { - init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo LV2 plugins, sorry!"); delete plugin; return nullptr; } diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index 5fcfd821c..53d8bfbf7 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -1277,7 +1277,7 @@ public: } } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override { // -------------------------------------------------------------------------------------------------------- // Check if active @@ -1286,8 +1286,9 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); - + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(cvOut[i], static_cast(frames)); return; } @@ -1419,7 +1420,7 @@ public: if (time > timeOffset && sampleAccurate) { - if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset)) + if (processSingle(audioIn, audioOut, cvIn, cvOut, time - timeOffset, timeOffset)) { startTime = 0; timeOffset = time; @@ -1670,7 +1671,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset); + processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing @@ -1679,7 +1680,7 @@ public: else { - processSingle(inBuffer, outBuffer, frames, 0); + processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0); } // End of Plugin processing (no events) @@ -1725,27 +1726,26 @@ public: } // End of Control and MIDI Output } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) + bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames, const uint32_t timeOffset) { - CARLA_ASSERT(frames > 0); - - if (frames == 0) - return false; + CARLA_SAFE_ASSERT_RETURN(frames > 0, false); if (pData->audioIn.count > 0) { - CARLA_ASSERT(inBuffer != nullptr); - if (inBuffer == nullptr) - return false; + CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_ASSERT(outBuffer != nullptr); - if (outBuffer == nullptr) - return false; + CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); + } + if (pData->cvIn.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); + } + if (pData->cvOut.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); } - - uint32_t i, k; // -------------------------------------------------------------------------------------------------------- // Try lock, silence otherwise @@ -1756,24 +1756,40 @@ public: } else if (! pData->singleMutex.tryLock()) { - for (i=0; i < pData->audioOut.count; ++i) + for (uint32_t i=0; i < pData->audioOut.count; ++i) { - for (k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = 0.0f; + for (uint32_t k=0; k < frames; ++k) + audioOut[i][k+timeOffset] = 0.0f; + } + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = 0.0f; } return false; } // -------------------------------------------------------------------------------------------------------- - // Reset audio buffers + // Set audio buffers - for (i=0; i < pData->audioIn.count; ++i) - FloatVectorOperations::copy(fAudioInBuffers[i], inBuffer[i]+timeOffset, static_cast(frames)); + for (uint32_t i=0; i < pData->audioIn.count; ++i) + FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast(frames)); - for (i=0; i < pData->audioOut.count; ++i) + for (uint32_t i=0; i < pData->audioOut.count; ++i) FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast(frames)); +#if 0 + // -------------------------------------------------------------------------------------------------------- + // Set CV buffers + + for (uint32_t i=0; i < pData->cvIn.count; ++i) + FloatVectorOperations::copy(fCvInBuffers[i], cvIn[i]+timeOffset, static_cast(frames)); + + for (uint32_t i=0; i < pData->cvOut.count; ++i) + FloatVectorOperations::clear(fCvOutBuffers[i], static_cast(frames)); +#endif + // -------------------------------------------------------------------------------------------------------- // Run plugin @@ -1810,12 +1826,12 @@ public: bool isPair; float bufValue, oldBufLeft[doBalance ? frames : 1]; - for (i=0; i < pData->audioOut.count; ++i) + for (uint32_t i=0; i < pData->audioOut.count; ++i) { // Dry/Wet if (doDryWet) { - for (k=0; k < frames; ++k) + for (uint32_t k=0; k < frames; ++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)); @@ -1836,7 +1852,7 @@ public: float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f; float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f; - for (k=0; k < frames; ++k) + for (uint32_t k=0; k < frames; ++k) { if (isPair) { @@ -1855,17 +1871,25 @@ public: // Volume (and buffer copy) { - for (k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; + for (uint32_t k=0; k < frames; ++k) + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } } // End of Post-processing #else - for (i=0; i < pData->audioOut.count; ++i) + for (uint32_t i=0; i < pData->audioOut.count; ++i) { for (k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k]; + audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k]; + } +#endif + +#if 0 + for (uint32_t i=0; i < pData->cvOut.count; ++i) + { + for (uint32_t k=0; k < frames; ++k) + cvOut[i][k+timeOffset] = fCvOutBuffers[i][k]; } #endif @@ -2434,9 +2458,29 @@ CarlaPlugin* CarlaPlugin::newNative(const Initializer& init) plugin->reload(); - if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) + bool canRun = true; + + if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) + { + if (! plugin->canRunInRack()) + { + init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!"); + canRun = false; + } + else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0) + { + init.engine->setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!"); + canRun = false; + } + } + else if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_PATCHBAY && (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)) + { + init.engine->setLastError("CV ports in patchbay mode is still TODO"); + canRun = false; + } + + if (! canRun) { - init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!"); delete plugin; return nullptr; } diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 05f6ba6fb..a557bc6d9 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -1052,7 +1052,7 @@ public: } catch(...) {} } - void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override + void process(const float** const audioIn, float** const audioOut, const float** const, float** const, const uint32_t frames) override { fProcThread = pthread_self(); @@ -1063,7 +1063,7 @@ public: { // disable any output sound for (uint32_t i=0; i < pData->audioOut.count; ++i) - FloatVectorOperations::clear(outBuffer[i], static_cast(frames)); + FloatVectorOperations::clear(audioOut[i], static_cast(frames)); return; } @@ -1228,7 +1228,7 @@ public: if (isSampleAccurate && event.time > timeOffset) { - if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset)) + if (processSingle(audioIn, audioOut, event.time - timeOffset, timeOffset)) { startTime = 0; timeOffset = event.time; @@ -1472,7 +1472,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset); + processSingle(audioIn, audioOut, frames - timeOffset, timeOffset); } // End of Event Input and Processing @@ -1481,7 +1481,7 @@ public: else { - processSingle(inBuffer, outBuffer, frames, 0); + processSingle(audioIn, audioOut, frames, 0); } // End of Plugin processing (no events) @@ -1513,7 +1513,7 @@ public: } // End of MIDI Output } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) + bool processSingle(const float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) { CARLA_SAFE_ASSERT_RETURN(frames > 0, false); @@ -1551,7 +1551,7 @@ public: float* vstOutBuffer[pData->audioOut.count]; for (uint32_t i=0; i < pData->audioIn.count; ++i) - vstInBuffer[i] = inBuffer[i]+timeOffset; + vstInBuffer[i] = const_cast(inBuffer[i]+timeOffset); for (uint32_t i=0; i < pData->audioOut.count; ++i) vstOutBuffer[i] = outBuffer[i]+timeOffset; diff --git a/source/utils/CarlaBridgeUtils.hpp b/source/utils/CarlaBridgeUtils.hpp index e77cbf188..878d36d96 100644 --- a/source/utils/CarlaBridgeUtils.hpp +++ b/source/utils/CarlaBridgeUtils.hpp @@ -55,6 +55,7 @@ enum PluginBridgeOscInfoType { enum PluginBridgeRtOpcode { kPluginBridgeRtNull = 0, kPluginBridgeRtSetAudioPool, // ulong/ptr + kPluginBridgeRtSetCVPool, // ulong/ptr kPluginBridgeRtControlEventParameter, // uint/frame, byte/chan, ushort, float kPluginBridgeRtControlEventMidiBank, // uint/frame, byte/chan, ushort kPluginBridgeRtControlEventMidiProgram, // uint/frame, byte/chan, ushort @@ -208,6 +209,8 @@ const char* PluginBridgeRtOpcode2str(const PluginBridgeRtOpcode opcode) noexcept return "kPluginBridgeRtNull"; case kPluginBridgeRtSetAudioPool: return "kPluginBridgeRtSetAudioPool"; + case kPluginBridgeRtSetCVPool: + return "kPluginBridgeRtSetCVPool"; case kPluginBridgeRtControlEventParameter: return "kPluginBridgeRtControlEventParameter"; case kPluginBridgeRtControlEventMidiBank: