Browse Source

Pass CV buffers directly in plugin process function

tags/1.9.5
falkTX 11 years ago
parent
commit
dac744cd0c
13 changed files with 403 additions and 168 deletions
  1. +2
    -1
      source/backend/CarlaPlugin.hpp
  2. +6
    -4
      source/backend/engine/CarlaEngineGraph.cpp
  3. +32
    -16
      source/backend/engine/CarlaEngineJack.cpp
  4. +69
    -23
      source/backend/plugin/BridgePlugin.cpp
  5. +71
    -17
      source/backend/plugin/DssiPlugin.cpp
  6. +4
    -4
      source/backend/plugin/FluidSynthPlugin.cpp
  7. +3
    -3
      source/backend/plugin/JucePlugin.cpp
  8. +71
    -17
      source/backend/plugin/LadspaPlugin.cpp
  9. +4
    -4
      source/backend/plugin/LinuxSamplerPlugin.cpp
  10. +52
    -37
      source/backend/plugin/Lv2Plugin.cpp
  11. +79
    -35
      source/backend/plugin/NativePlugin.cpp
  12. +7
    -7
      source/backend/plugin/VstPlugin.cpp
  13. +3
    -0
      source/utils/CarlaBridgeUtils.hpp

+ 2
- 1
source/backend/CarlaPlugin.hpp View File

@@ -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.


+ 6
- 4
source/backend/engine/CarlaEngineGraph.cpp View File

@@ -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<uint32_t>(audio.getNumSamples()));

if (const int numChan = audio.getNumChannels())
@@ -1011,7 +1013,7 @@ public:
}
}

fPlugin->process(audioBuffers, audioBuffers, bufferSize);
fPlugin->process(const_cast<const float**>(audioBuffers), audioBuffers, nullptr, nullptr, bufferSize);

for (int i=0; i<numChan; ++i)
{
@@ -1028,7 +1030,7 @@ public:
}
else
{
fPlugin->process(nullptr, nullptr, bufferSize);
fPlugin->process(nullptr, nullptr, nullptr, nullptr, bufferSize);
}

midi.clear();


+ 32
- 16
source/backend/engine/CarlaEngineJack.cpp View File

@@ -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;


+ 69
- 23
source/backend/plugin/BridgePlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(fShmAudioPool.data + (i * frames), audioIn[i], static_cast<int>(frames));

for (uint32_t i=0; i < fInfo.cvIns; ++i)
FloatVectorOperations::copy(fShmCVPool.data + (i * frames), cvIn[i], static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(audioOut[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), static_cast<int>(frames));

for (uint32_t i=0; i < fInfo.cvOuts; ++i)
FloatVectorOperations::copy(cvOut[i], fShmCVPool.data + ((i + fInfo.cvIns) * frames), static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(oldBufLeft, audioOut[i], static_cast<int>(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<int64_t>(fShmAudioPool.size));

fShmRtControl.writeOpcode(kPluginBridgeRtSetCVPool);
fShmRtControl.writeLong(static_cast<int64_t>(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;
}


+ 71
- 17
source/backend/plugin/DssiPlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(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<int>(pData->latency));
FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast<int>(frames));

for (uint32_t i=0; i < pData->audioOut.count; ++i)
FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast<int>(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<int>(frames));

for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(fCvOutBuffers[i], static_cast<int>(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;
}


+ 4
- 4
source/backend/plugin/FluidSynthPlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(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



+ 3
- 3
source/backend/plugin/JucePlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
return;
}

@@ -877,7 +877,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// Process

processSingle(inBuffer, outBuffer, frames);
processSingle(audioIn, audioOut, frames);

// --------------------------------------------------------------------------------------------------------
// MIDI Output


+ 71
- 17
source/backend/plugin/LadspaPlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(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<int>(pData->latency));
FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast<int>(frames));

for (uint32_t i=0; i < pData->audioOut.count; ++i)
FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast<int>(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<int>(frames));

for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(fCvOutBuffers[i], static_cast<int>(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;
}


+ 4
- 4
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(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
}


+ 52
- 37
source/backend/plugin/Lv2Plugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(frames));
return;
}

@@ -2726,24 +2728,6 @@ public:
carla_copyStruct<EngineTimeInfo>(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<int>(pData->latency));
FloatVectorOperations::copy(pData->latencyBuffers[i], audioIn[i]+(frames-pData->latency), static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast<int>(frames));

for (uint32_t i=0; i < pData->audioOut.count; ++i)
FloatVectorOperations::clear(fAudioOutBuffers[i], static_cast<int>(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<int>(frames));
FloatVectorOperations::copy(fCvInBuffers[i], cvIn[i]+timeOffset, static_cast<int>(frames));

for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(fCvOutBuffers[i], static_cast<int>(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;
}


+ 79
- 35
source/backend/plugin/NativePlugin.cpp View File

@@ -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<int>(frames));

FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(cvOut[i], static_cast<int>(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<int>(frames));
for (uint32_t i=0; i < pData->audioIn.count; ++i)
FloatVectorOperations::copy(fAudioInBuffers[i], audioIn[i]+timeOffset, static_cast<int>(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<int>(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<int>(frames));

for (uint32_t i=0; i < pData->cvOut.count; ++i)
FloatVectorOperations::clear(fCvOutBuffers[i], static_cast<int>(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;
}


+ 7
- 7
source/backend/plugin/VstPlugin.cpp View File

@@ -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<int>(frames));
FloatVectorOperations::clear(audioOut[i], static_cast<int>(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<float*>(inBuffer[i]+timeOffset);
for (uint32_t i=0; i < pData->audioOut.count; ++i)
vstOutBuffer[i] = outBuffer[i]+timeOffset;



+ 3
- 0
source/utils/CarlaBridgeUtils.hpp View File

@@ -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:


Loading…
Cancel
Save