From df7860a22050930ddd818b1178e2b6944d0bf8e9 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 31 Jan 2014 01:07:20 +0000 Subject: [PATCH] Implement CV ports --- source/backend/plugin/CarlaPluginInternal.cpp | 25 +-- source/backend/plugin/Lv2Plugin.cpp | 158 +++++++++++++++--- 2 files changed, 144 insertions(+), 39 deletions(-) diff --git a/source/backend/plugin/CarlaPluginInternal.cpp b/source/backend/plugin/CarlaPluginInternal.cpp index eeb165852..7f6612709 100644 --- a/source/backend/plugin/CarlaPluginInternal.cpp +++ b/source/backend/plugin/CarlaPluginInternal.cpp @@ -64,11 +64,8 @@ PluginAudioData::~PluginAudioData() void PluginAudioData::createNew(const uint32_t newCount) { CARLA_ASSERT_INT(count == 0, count); - CARLA_ASSERT(ports == nullptr); - CARLA_ASSERT_INT(newCount > 0, newCount); - - if (ports != nullptr || newCount == 0) - return; + CARLA_SAFE_ASSERT_RETURN(ports == nullptr,); + CARLA_SAFE_ASSERT_RETURN(newCount > 0,); ports = new PluginAudioPort[newCount]; count = newCount; @@ -132,11 +129,8 @@ PluginCVData::~PluginCVData() void PluginCVData::createNew(const uint32_t newCount) { CARLA_ASSERT_INT(count == 0, count); - CARLA_ASSERT(ports == nullptr); - CARLA_ASSERT_INT(newCount > 0, newCount); - - if (ports != nullptr || newCount == 0) - return; + CARLA_SAFE_ASSERT_RETURN(ports == nullptr,); + CARLA_SAFE_ASSERT_RETURN(newCount > 0,); ports = new PluginCVPort[newCount]; count = newCount; @@ -228,13 +222,10 @@ PluginParameterData::~PluginParameterData() void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial) { CARLA_ASSERT_INT(count == 0, count); - CARLA_ASSERT(data == nullptr); - CARLA_ASSERT(ranges == nullptr); - CARLA_ASSERT(special == nullptr); - CARLA_ASSERT_INT(newCount > 0, newCount); - - if (data != nullptr || ranges != nullptr || newCount == 0) - return; + CARLA_SAFE_ASSERT_RETURN(data == nullptr,); + CARLA_SAFE_ASSERT_RETURN(ranges == nullptr,); + CARLA_SAFE_ASSERT_RETURN(special == nullptr,); + CARLA_SAFE_ASSERT_RETURN(newCount > 0,); data = new ParameterData[newCount]; ranges = new ParameterRanges[newCount]; diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 4bf4ec707..3e25a557f 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -225,9 +225,6 @@ struct Lv2PluginEventData { CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,); CARLA_SAFE_ASSERT_RETURN(newCount > 0,); - if (data != nullptr || newCount == 0) - return; - data = new Lv2EventData[newCount]; count = newCount; } @@ -342,6 +339,8 @@ public: fRdfDescriptor(nullptr), fAudioInBuffers(nullptr), fAudioOutBuffers(nullptr), + fCvInBuffers(nullptr), + fCvOutBuffers(nullptr), fParamBuffers(nullptr), fFirstActive(true) { @@ -1396,6 +1395,24 @@ public: fAudioOutBuffers[i] = nullptr; } + if (cvIns > 0) + { + fCvIn.createNew(cvIns); + fCvInBuffers = new float*[cvIns]; + + for (uint32_t i=0; i < cvIns; ++i) + fCvInBuffers[i] = nullptr; + } + + if (cvOuts > 0) + { + fCvOut.createNew(cvOuts); + fCvOutBuffers = new float*[cvOuts]; + + for (uint32_t i=0; i < cvOuts; ++i) + fCvOutBuffers[i] = nullptr; + } + if (params > 0) { pData->param.createNew(params, true); @@ -1460,7 +1477,7 @@ public: const uint portNameSize(pData->engine->getMaxPortNameSize()); CarlaString portName; - for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iEvIn=0, iEvOut=0, iCtrl=0; i < portCount; ++i) + for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCvIn=0, iCvOut=0, iEvIn=0, iEvOut=0, iCtrl=0; i < portCount; ++i) { const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types); @@ -1513,19 +1530,18 @@ public: { if (LV2_IS_PORT_INPUT(portTypes)) { - carla_stderr("WARNING - CV Ports are not supported yet"); + uint32_t j = iCvIn++; + fCvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true); + fCvIn.ports[j].rindex = i; } else if (LV2_IS_PORT_OUTPUT(portTypes)) { - carla_stderr("WARNING - CV Ports are not supported yet"); + uint32_t j = iCvOut++; + fCvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false); + fCvOut.ports[j].rindex = i; } else carla_stderr("WARNING - Got a broken Port (CV, but not input or output)"); - - fDescriptor->connect_port(fHandle, i, nullptr); - - if (fHandle2 != nullptr) - fDescriptor->connect_port(fHandle2, i, nullptr); } else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes)) { @@ -2512,6 +2528,24 @@ public: CARLA_PROCESS_CONTINUE_CHECK; } + // -------------------------------------------------------------------------------------------------------- + // CV ports + + float* cvInBuf[fCvIn.count /*> 0 ? fCvIn.count : 1*/]; + float* cvOutBuf[fCvOut.count /*> 0 ? fCvOut.count : 1*/]; + + for (uint32_t i=0; i < fCvIn.count; ++i) + { + CARLA_SAFE_ASSERT_CONTINUE(fCvIn.ports[i].port != nullptr); + cvInBuf[i] = fCvIn.ports[i].port->getBuffer(); + } + + for (uint32_t i=0; i < fCvOut.count; ++i) + { + CARLA_SAFE_ASSERT_CONTINUE(fCvOut.ports[i].port != nullptr); + cvOutBuf[i] = fCvOut.ports[i].port->getBuffer(); + } + // -------------------------------------------------------------------------------------------------------- // Event Input and Processing @@ -2618,7 +2652,7 @@ public: if (isSampleAccurate && event.time > timeOffset) { - if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset)) + if (processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, event.time - timeOffset, timeOffset)) { startTime = 0; timeOffset = event.time; @@ -2893,7 +2927,7 @@ public: pData->postRtEvents.trySplice(); if (frames > timeOffset) - processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset); + processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames - timeOffset, timeOffset); } // End of Event Input and Processing @@ -2902,7 +2936,7 @@ public: else { - processSingle(inBuffer, outBuffer, frames, 0); + processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames, 0); } // End of Plugin processing (no events) @@ -3042,17 +3076,25 @@ public: // -------------------------------------------------------------------------------------------------------- } - bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) + bool processSingle(float** const audioInBuf, float** const audioOutBuf, float** const cvInBuf, float** const cvOutBuf, 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(audioInBuf != nullptr, false); } if (pData->audioOut.count > 0) { - CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(audioOutBuf != nullptr, false); + } + if (fCvIn.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvInBuf != nullptr, false); + } + if (fCvOut.count > 0) + { + CARLA_SAFE_ASSERT_RETURN(cvOutBuf != nullptr, false); } // -------------------------------------------------------------------------------------------------------- @@ -3067,21 +3109,30 @@ 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; + audioOutBuf[i][k+timeOffset] = 0.0f; } return false; } // -------------------------------------------------------------------------------------------------------- - // Reset audio buffers + // Set audio buffers for (uint32_t i=0; i < pData->audioIn.count; ++i) - FLOAT_COPY(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames); + FLOAT_COPY(fAudioInBuffers[i], audioInBuf[i]+timeOffset, frames); for (uint32_t i=0; i < pData->audioOut.count; ++i) FLOAT_CLEAR(fAudioOutBuffers[i], frames); + // -------------------------------------------------------------------------------------------------------- + // Set CV buffers + + for (uint32_t i=0; i < fCvIn.count; ++i) + FLOAT_COPY(fCvInBuffers[i], cvInBuf[i]+timeOffset, frames); + + for (uint32_t i=0; i < fCvOut.count; ++i) + FLOAT_CLEAR(fCvOutBuffers[i], frames); + // -------------------------------------------------------------------------------------------------------- // Run plugin @@ -3173,7 +3224,7 @@ public: // Volume (and buffer copy) { for (uint32_t k=0; k < frames; ++k) - outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; + audioOutBuf[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; } } } // End of Post-processing @@ -3181,7 +3232,7 @@ 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]; + audioOutBuf[i][k+timeOffset] = fAudioOutBuffers[i][k]; } #endif @@ -3247,6 +3298,30 @@ public: } } + for (uint32_t i=0; i < fCvIn.count; ++i) + { + if (fCvInBuffers[i] != nullptr) + delete[] fCvInBuffers[i]; + fCvInBuffers[i] = new float[newBufferSize]; + + fDescriptor->connect_port(fHandle, fCvIn.ports[i].rindex, fCvInBuffers[i]); + + if (fHandle2 != nullptr) + fDescriptor->connect_port(fHandle2, fCvIn.ports[i].rindex, fCvInBuffers[i]); + } + + for (uint32_t i=0; i < fCvOut.count; ++i) + { + if (fCvOutBuffers[i] != nullptr) + delete[] fCvOutBuffers[i]; + fCvOutBuffers[i] = new float[newBufferSize]; + + fDescriptor->connect_port(fHandle, fCvOut.ports[i].rindex, fCvOutBuffers[i]); + + if (fHandle2 != nullptr) + fDescriptor->connect_port(fHandle2, fCvOut.ports[i].rindex, fCvOutBuffers[i]); + } + const int newBufferSizeInt(static_cast(newBufferSize)); if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt)) @@ -3310,6 +3385,8 @@ public: void initBuffers() override { + fCvIn.initBuffers(); + fCvOut.initBuffers(); fEventsIn.initBuffers(); fEventsOut.initBuffers(); @@ -3350,12 +3427,44 @@ public: fAudioOutBuffers = nullptr; } + if (fCvInBuffers != nullptr) + { + for (uint32_t i=0; i < fCvIn.count; ++i) + { + if (fCvInBuffers[i] != nullptr) + { + delete[] fCvInBuffers[i]; + fCvInBuffers[i] = nullptr; + } + } + + delete[] fCvInBuffers; + fCvInBuffers = nullptr; + } + + if (fCvOutBuffers != nullptr) + { + for (uint32_t i=0; i < fCvOut.count; ++i) + { + if (fCvOutBuffers[i] != nullptr) + { + delete[] fCvOutBuffers[i]; + fCvOutBuffers[i] = nullptr; + } + } + + delete[] fCvOutBuffers; + fCvOutBuffers = nullptr; + } + if (fParamBuffers != nullptr) { delete[] fParamBuffers; fParamBuffers = nullptr; } + fCvIn.clear(); + fCvOut.clear(); fEventsIn.clear(); fEventsOut.clear(); @@ -4723,12 +4832,17 @@ private: float** fAudioInBuffers; float** fAudioOutBuffers; + float** fCvInBuffers; + float** fCvOutBuffers; float* fParamBuffers; Lv2AtomQueue fAtomQueueIn; Lv2AtomQueue fAtomQueueOut; LV2_Atom_Forge fAtomForge; + PluginCVData fCvIn; + PluginCVData fCvOut; + Lv2PluginEventData fEventsIn; Lv2PluginEventData fEventsOut; Lv2PluginOptions fLv2Options;