Browse Source

Implement CV ports

tags/1.9.4
falkTX 11 years ago
parent
commit
df7860a220
2 changed files with 144 additions and 39 deletions
  1. +8
    -17
      source/backend/plugin/CarlaPluginInternal.cpp
  2. +136
    -22
      source/backend/plugin/Lv2Plugin.cpp

+ 8
- 17
source/backend/plugin/CarlaPluginInternal.cpp View File

@@ -64,11 +64,8 @@ PluginAudioData::~PluginAudioData()
void PluginAudioData::createNew(const uint32_t newCount) void PluginAudioData::createNew(const uint32_t newCount)
{ {
CARLA_ASSERT_INT(count == 0, count); 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]; ports = new PluginAudioPort[newCount];
count = newCount; count = newCount;
@@ -132,11 +129,8 @@ PluginCVData::~PluginCVData()
void PluginCVData::createNew(const uint32_t newCount) void PluginCVData::createNew(const uint32_t newCount)
{ {
CARLA_ASSERT_INT(count == 0, count); 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]; ports = new PluginCVPort[newCount];
count = newCount; count = newCount;
@@ -228,13 +222,10 @@ PluginParameterData::~PluginParameterData()
void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial) void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial)
{ {
CARLA_ASSERT_INT(count == 0, count); 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]; data = new ParameterData[newCount];
ranges = new ParameterRanges[newCount]; ranges = new ParameterRanges[newCount];


+ 136
- 22
source/backend/plugin/Lv2Plugin.cpp View File

@@ -225,9 +225,6 @@ struct Lv2PluginEventData {
CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,); CARLA_SAFE_ASSERT_RETURN(ctrl == nullptr,);
CARLA_SAFE_ASSERT_RETURN(newCount > 0,); CARLA_SAFE_ASSERT_RETURN(newCount > 0,);


if (data != nullptr || newCount == 0)
return;

data = new Lv2EventData[newCount]; data = new Lv2EventData[newCount];
count = newCount; count = newCount;
} }
@@ -342,6 +339,8 @@ public:
fRdfDescriptor(nullptr), fRdfDescriptor(nullptr),
fAudioInBuffers(nullptr), fAudioInBuffers(nullptr),
fAudioOutBuffers(nullptr), fAudioOutBuffers(nullptr),
fCvInBuffers(nullptr),
fCvOutBuffers(nullptr),
fParamBuffers(nullptr), fParamBuffers(nullptr),
fFirstActive(true) fFirstActive(true)
{ {
@@ -1396,6 +1395,24 @@ public:
fAudioOutBuffers[i] = nullptr; 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) if (params > 0)
{ {
pData->param.createNew(params, true); pData->param.createNew(params, true);
@@ -1460,7 +1477,7 @@ public:
const uint portNameSize(pData->engine->getMaxPortNameSize()); const uint portNameSize(pData->engine->getMaxPortNameSize());
CarlaString portName; 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); const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);


@@ -1513,19 +1530,18 @@ public:
{ {
if (LV2_IS_PORT_INPUT(portTypes)) 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)) 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 else
carla_stderr("WARNING - Got a broken Port (CV, but not input or output)"); 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)) else if (LV2_IS_PORT_ATOM_SEQUENCE(portTypes))
{ {
@@ -2512,6 +2528,24 @@ public:
CARLA_PROCESS_CONTINUE_CHECK; 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 // Event Input and Processing


@@ -2618,7 +2652,7 @@ public:


if (isSampleAccurate && event.time > timeOffset) 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; startTime = 0;
timeOffset = event.time; timeOffset = event.time;
@@ -2893,7 +2927,7 @@ public:
pData->postRtEvents.trySplice(); pData->postRtEvents.trySplice();


if (frames > timeOffset) if (frames > timeOffset)
processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset);
processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames - timeOffset, timeOffset);


} // End of Event Input and Processing } // End of Event Input and Processing


@@ -2902,7 +2936,7 @@ public:


else else
{ {
processSingle(inBuffer, outBuffer, frames, 0);
processSingle(inBuffer, outBuffer, cvInBuf, cvOutBuf, frames, 0);


} // End of Plugin processing (no events) } // 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); CARLA_SAFE_ASSERT_RETURN(frames > 0, false);


if (pData->audioIn.count > 0) if (pData->audioIn.count > 0)
{ {
CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(audioInBuf != nullptr, false);
} }
if (pData->audioOut.count > 0) 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 i=0; i < pData->audioOut.count; ++i)
{ {
for (uint32_t k=0; k < frames; ++k) for (uint32_t k=0; k < frames; ++k)
outBuffer[i][k+timeOffset] = 0.0f;
audioOutBuf[i][k+timeOffset] = 0.0f;
} }


return false; return false;
} }


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Reset audio buffers
// Set audio buffers


for (uint32_t i=0; i < pData->audioIn.count; ++i) 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) for (uint32_t i=0; i < pData->audioOut.count; ++i)
FLOAT_CLEAR(fAudioOutBuffers[i], frames); 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 // Run plugin


@@ -3173,7 +3224,7 @@ public:
// Volume (and buffer copy) // Volume (and buffer copy)
{ {
for (uint32_t k=0; k < frames; ++k) 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 } // End of Post-processing
@@ -3181,7 +3232,7 @@ public:
for (uint32_t i=0; i < pData->audioOut.count; ++i) for (uint32_t i=0; i < pData->audioOut.count; ++i)
{ {
for (uint32_t k=0; k < frames; ++k) for (uint32_t k=0; k < frames; ++k)
outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k];
audioOutBuf[i][k+timeOffset] = fAudioOutBuffers[i][k];
} }
#endif #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<int>(newBufferSize)); const int newBufferSizeInt(static_cast<int>(newBufferSize));


if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt)) if (fLv2Options.maxBufferSize != newBufferSizeInt || (fLv2Options.minBufferSize != 1 && fLv2Options.minBufferSize != newBufferSizeInt))
@@ -3310,6 +3385,8 @@ public:


void initBuffers() override void initBuffers() override
{ {
fCvIn.initBuffers();
fCvOut.initBuffers();
fEventsIn.initBuffers(); fEventsIn.initBuffers();
fEventsOut.initBuffers(); fEventsOut.initBuffers();


@@ -3350,12 +3427,44 @@ public:
fAudioOutBuffers = nullptr; 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) if (fParamBuffers != nullptr)
{ {
delete[] fParamBuffers; delete[] fParamBuffers;
fParamBuffers = nullptr; fParamBuffers = nullptr;
} }


fCvIn.clear();
fCvOut.clear();
fEventsIn.clear(); fEventsIn.clear();
fEventsOut.clear(); fEventsOut.clear();


@@ -4723,12 +4832,17 @@ private:


float** fAudioInBuffers; float** fAudioInBuffers;
float** fAudioOutBuffers; float** fAudioOutBuffers;
float** fCvInBuffers;
float** fCvOutBuffers;
float* fParamBuffers; float* fParamBuffers;


Lv2AtomQueue fAtomQueueIn; Lv2AtomQueue fAtomQueueIn;
Lv2AtomQueue fAtomQueueOut; Lv2AtomQueue fAtomQueueOut;
LV2_Atom_Forge fAtomForge; LV2_Atom_Forge fAtomForge;


PluginCVData fCvIn;
PluginCVData fCvOut;

Lv2PluginEventData fEventsIn; Lv2PluginEventData fEventsIn;
Lv2PluginEventData fEventsOut; Lv2PluginEventData fEventsOut;
Lv2PluginOptions fLv2Options; Lv2PluginOptions fLv2Options;


Loading…
Cancel
Save