Browse Source

Initial work for LV2 CV port/parameter support

tags/1.9.4
falkTX 12 years ago
parent
commit
07a698acb5
5 changed files with 144 additions and 13 deletions
  1. +1
    -2
      source/backend/CarlaEngine.hpp
  2. +2
    -2
      source/backend/engine/CarlaEngineJack.cpp
  3. +79
    -0
      source/backend/plugin/CarlaPluginInternal.hpp
  4. +61
    -8
      source/backend/plugin/Lv2Plugin.cpp
  5. +1
    -1
      source/utils/CarlaLv2Utils.hpp

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

@@ -515,8 +515,7 @@ public:
virtual void initBuffer(CarlaEngine* const engine) override;

/*!
* Write buffer.\n
* This is a handy function for the JACK engine only, where we need to write buffer to output ports.
* Write buffer back into the engine.
*/
virtual void writeBuffer(CarlaEngine* const engine);



+ 2
- 2
source/backend/engine/CarlaEngineJack.cpp View File

@@ -153,7 +153,7 @@ public:

if (kIsInput)
{
float* const jackBuffer = (float*)jackbridge_port_get_buffer(kPort, fBufferSize);
float* const jackBuffer((float*)jackbridge_port_get_buffer(kPort, fBufferSize));
carla_copyFloat(fBuffer, jackBuffer, fBufferSize);
}
else
@@ -174,7 +174,7 @@ public:

CARLA_ASSERT(engine->getBufferSize() == fBufferSize);

float* const jackBuffer = (float*)jackbridge_port_get_buffer(kPort, fBufferSize);
float* const jackBuffer((float*)jackbridge_port_get_buffer(kPort, fBufferSize));
carla_copyFloat(jackBuffer, fBuffer, fBufferSize);
}



+ 79
- 0
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -120,6 +120,85 @@ struct PluginAudioData {

// -----------------------------------------------------------------------

struct PluginCVPort {
uint32_t rindex;
uint32_t param;
CarlaEngineCVPort* port;

PluginCVPort()
: rindex(0),
param(0),
port(nullptr) {}

~PluginCVPort()
{
CARLA_ASSERT(port == nullptr);
}

CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginCVPort)
};

struct PluginCVData {
uint32_t count;
PluginCVPort* ports;

PluginCVData()
: count(0),
ports(nullptr) {}

~PluginCVData()
{
CARLA_ASSERT_INT(count == 0, count);
CARLA_ASSERT(ports == nullptr);
}

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

ports = new PluginCVPort[newCount];
count = newCount;
}

void clear()
{
if (ports != nullptr)
{
for (uint32_t i=0; i < count; ++i)
{
if (ports[i].port != nullptr)
{
delete ports[i].port;
ports[i].port = nullptr;
}
}

delete[] ports;
ports = nullptr;
}

count = 0;
}

void initBuffers(CarlaEngine* const engine)
{
for (uint32_t i=0; i < count; ++i)
{
if (ports[i].port != nullptr)
ports[i].port->initBuffer(engine);
}
}

CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginCVData)
};

// -----------------------------------------------------------------------

struct PluginEventData {
CarlaEngineEventPort* portIn;
CarlaEngineEventPort* portOut;


+ 61
- 8
source/backend/plugin/Lv2Plugin.cpp View File

@@ -17,6 +17,8 @@

#include "CarlaPluginInternal.hpp"

#define WANT_LV2

#ifdef WANT_LV2

#include "CarlaPluginGui.hpp"
@@ -1373,6 +1375,8 @@ public:
params += 1;
}

params += cvIns + cvOuts;

// check extensions
fExt.options = nullptr;
fExt.programs = nullptr;
@@ -1434,6 +1438,17 @@ public:
fAudioOutBuffers[i] = nullptr;
}

if (cvIns > 0)
{
fCvIn.createNew(aIns);
}

if (cvOuts > 0)
{
fCvOut.createNew(aOuts);
needsCtrlIn = true;
}

if (params > 0)
{
kData->param.createNew(params);
@@ -1510,7 +1525,7 @@ public:
const uint portNameSize(kData->engine->maxPortNameSize());
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);

@@ -1563,19 +1578,55 @@ public:
{
if (LV2_IS_PORT_INPUT(portTypes))
{
carla_stderr("WARNING - CV Ports are not supported yet");
j = iCvIn++;
fCvIn.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, true);
fCvIn.ports[j].rindex = i;

fDescriptor->connect_port(fHandle, i, fCvIn.ports[j].port->getBuffer());

if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, fCvIn.ports[j].port->getBuffer());

j = params + j;
kData->param.data[j].index = j;
kData->param.data[j].rindex = i;
kData->param.data[j].hints = 0x0;
kData->param.data[j].midiChannel = 0;
kData->param.data[j].midiCC = -1;
kData->param.ranges[j].min = 0.0f;
kData->param.ranges[j].max = 1.0f;
kData->param.ranges[j].def = 0.0f;
kData->param.ranges[j].step = 0.01f;
kData->param.ranges[j].stepSmall = 0.001f;
kData->param.ranges[j].stepLarge = 0.1f;

}
else if (LV2_IS_PORT_OUTPUT(portTypes))
{
carla_stderr("WARNING - CV Ports are not supported yet");
j = iCvOut++;
fCvOut.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, false);
fCvOut.ports[j].rindex = i;

fDescriptor->connect_port(fHandle, i, fCvOut.ports[j].port->getBuffer());

if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, fCvOut.ports[j].port->getBuffer());

j = params + cvIns + j;
kData->param.data[j].index = j;
kData->param.data[j].rindex = i;
kData->param.data[j].hints = 0x0;
kData->param.data[j].midiChannel = 0;
kData->param.data[j].midiCC = -1;
kData->param.ranges[j].min = 0.0f;
kData->param.ranges[j].max = 1.0f;
kData->param.ranges[j].def = 0.0f;
kData->param.ranges[j].step = 0.01f;
kData->param.ranges[j].stepSmall = 0.001f;
kData->param.ranges[j].stepLarge = 0.1f;
}
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))
{
@@ -4745,6 +4796,8 @@ private:
Lv2AtomQueue fAtomQueueOut;
LV2_Atom_Forge fAtomForge;

PluginCVData fCvIn;
PluginCVData fCvOut;
Lv2PluginEventData fEventsIn;
Lv2PluginEventData fEventsOut;
Lv2PluginOptions fLv2Options;


+ 1
- 1
source/utils/CarlaLv2Utils.hpp View File

@@ -1262,7 +1262,7 @@ bool is_lv2_port_supported(const LV2_Property types)
if (LV2_IS_PORT_ATOM_SEQUENCE(types))
return true;
if (LV2_IS_PORT_CV(types))
return false; // TODO
return true;
if (LV2_IS_PORT_EVENT(types))
return true;
if (LV2_IS_PORT_MIDI_LL(types))


Loading…
Cancel
Save