Browse Source

LV2 CV ports working

tags/1.9.4
falkTX 11 years ago
parent
commit
4e221ce546
9 changed files with 112 additions and 64 deletions
  1. +9
    -8
      source/backend/CarlaBackend.hpp
  2. +1
    -1
      source/backend/CarlaEngine.hpp
  3. +2
    -11
      source/backend/engine/CarlaEngine.cpp
  4. +2
    -7
      source/backend/engine/CarlaEngineJack.cpp
  5. +2
    -3
      source/backend/plugin/DssiPlugin.cpp
  6. +2
    -3
      source/backend/plugin/LadspaPlugin.cpp
  7. +82
    -23
      source/backend/plugin/Lv2Plugin.cpp
  8. +9
    -8
      source/carla_backend.py
  9. +3
    -0
      source/carla_shared.py

+ 9
- 8
source/backend/CarlaBackend.hpp View File

@@ -92,14 +92,15 @@ const unsigned int PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100; //!< Send MIDI a
* \see CarlaPlugin::parameterData() * \see CarlaPlugin::parameterData()
* @{ * @{
*/ */
const unsigned int PARAMETER_IS_BOOLEAN = 0x01; //!< Parameter value is a boolean (always at minimum or maximum values).
const unsigned int PARAMETER_IS_INTEGER = 0x02; //!< Parameter value is an integer.
const unsigned int PARAMETER_IS_LOGARITHMIC = 0x04; //!< Parameter is logarithmic.
const unsigned int PARAMETER_IS_ENABLED = 0x08; //!< Parameter is enabled and will be shown in the host built-in editor.
const unsigned int PARAMETER_IS_AUTOMABLE = 0x10; //!< Parameter is automable (realtime safe)
const unsigned int PARAMETER_USES_SAMPLERATE = 0x20; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and must be divided by SR on save).
const unsigned int PARAMETER_USES_SCALEPOINTS = 0x40; //!< Parameter uses scalepoints to define internal values in a meaningful way.
const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText()
const unsigned int PARAMETER_IS_BOOLEAN = 0x001; //!< Parameter value is a boolean (always at minimum or maximum values).
const unsigned int PARAMETER_IS_INTEGER = 0x002; //!< Parameter value is an integer.
const unsigned int PARAMETER_IS_LOGARITHMIC = 0x004; //!< Parameter is logarithmic.
const unsigned int PARAMETER_IS_ENABLED = 0x008; //!< Parameter is enabled and will be shown in the host built-in editor.
const unsigned int PARAMETER_IS_AUTOMABLE = 0x010; //!< Parameter is automable (realtime safe)
const unsigned int PARAMETER_IS_READ_ONLY = 0x020; //!< Parameter is read-only
const unsigned int PARAMETER_USES_SAMPLERATE = 0x040; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and must be divided by SR on save).
const unsigned int PARAMETER_USES_SCALEPOINTS = 0x080; //!< Parameter uses scalepoints to define internal values in a meaningful way.
const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x100; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText()
/**@}*/ /**@}*/


/*! /*!


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

@@ -517,7 +517,7 @@ public:
/*! /*!
* Write buffer back into the engine. * Write buffer back into the engine.
*/ */
virtual void writeBuffer(CarlaEngine* const engine);
virtual void writeBuffer(const uint32_t frames, const uint32_t timeOffset);


/*! /*!
* Set a new buffer size. * Set a new buffer size.


+ 2
- 11
source/backend/engine/CarlaEngine.cpp View File

@@ -142,21 +142,12 @@ void CarlaEngineCVPort::initBuffer(CarlaEngine* const engine)
{ {
CARLA_ASSERT(engine != nullptr && engine->getBufferSize() == fBufferSize); CARLA_ASSERT(engine != nullptr && engine->getBufferSize() == fBufferSize);


if (! kIsInput)
carla_zeroFloat(fBuffer, fBufferSize);
carla_zeroFloat(fBuffer, fBufferSize);
} }


void CarlaEngineCVPort::writeBuffer(CarlaEngine* const engine)
void CarlaEngineCVPort::writeBuffer(const uint32_t, const uint32_t)
{ {
CARLA_ASSERT(! kIsInput); CARLA_ASSERT(! kIsInput);
CARLA_ASSERT(engine != nullptr);

if (kIsInput)
return;
if (engine == nullptr)
return;

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


void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize)


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

@@ -162,20 +162,15 @@ public:
} }
} }


void writeBuffer(CarlaEngine* const engine) override
void writeBuffer(const uint32_t frames, const uint32_t timeOffset) override
{ {
CARLA_ASSERT(! kIsInput); CARLA_ASSERT(! kIsInput);
CARLA_ASSERT(engine != nullptr);


if (kIsInput) if (kIsInput)
return; return;
if (engine == nullptr)
return;

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);
carla_copyFloat(jackBuffer+timeOffset, fBuffer, frames);
} }


private: private:


+ 2
- 3
source/backend/plugin/DssiPlugin.cpp View File

@@ -510,10 +510,9 @@ public:
if (params > 0) if (params > 0)
{ {
kData->param.createNew(params); kData->param.createNew(params);
fParamBuffers = new float[params];


for (uint32_t i=0; i < params; ++i)
fParamBuffers[i] = 0.0f;
fParamBuffers = new float[params];
carla_zeroFloat(fParamBuffers, params);
} }


const uint portNameSize(kData->engine->maxPortNameSize()); const uint portNameSize(kData->engine->maxPortNameSize());


+ 2
- 3
source/backend/plugin/LadspaPlugin.cpp View File

@@ -491,10 +491,9 @@ public:
if (params > 0) if (params > 0)
{ {
kData->param.createNew(params); kData->param.createNew(params);
fParamBuffers = new float[params];


for (uint32_t i=0; i < params; ++i)
fParamBuffers[i] = 0.0f;
fParamBuffers = new float[params];
carla_zeroFloat(fParamBuffers, params);
} }


const uint portNameSize(kData->engine->maxPortNameSize()); const uint portNameSize(kData->engine->maxPortNameSize());


+ 82
- 23
source/backend/plugin/Lv2Plugin.cpp View File

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


#include "CarlaPluginInternal.hpp" #include "CarlaPluginInternal.hpp"


#define WANT_LV2

#ifdef WANT_LV2 #ifdef WANT_LV2


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


params += cvIns + cvOuts;

// check extensions // check extensions
fExt.options = nullptr; fExt.options = nullptr;
fExt.programs = nullptr; fExt.programs = nullptr;
@@ -1440,22 +1436,22 @@ public:


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


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


if (params > 0) if (params > 0)
{ {
kData->param.createNew(params);
fParamBuffers = new float[params];
kData->param.createNew(params+cvIns+cvOuts);


for (uint32_t i=0; i < params; ++i)
fParamBuffers[i] = 0.0f;
fParamBuffers = new float[params+cvIns+cvOuts];
carla_zeroFloat(fParamBuffers, params+cvIns+cvOuts);
} }


if (evIns.count() > 0) if (evIns.count() > 0)
@@ -1579,51 +1575,57 @@ public:
if (LV2_IS_PORT_INPUT(portTypes)) if (LV2_IS_PORT_INPUT(portTypes))
{ {
j = iCvIn++; j = iCvIn++;
fCvIn.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, true);
fCvIn.ports[j].rindex = i;
fCvIn.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, true);
fCvIn.ports[j].rindex = i;
fCvIn.ports[j].param = params + j;


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


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


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


} }
else if (LV2_IS_PORT_OUTPUT(portTypes)) else if (LV2_IS_PORT_OUTPUT(portTypes))
{ {
j = iCvOut++; j = iCvOut++;
fCvOut.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, false);
fCvOut.ports[j].rindex = i;
fCvOut.ports[j].port = (CarlaEngineCVPort*)kData->client->addPort(kEnginePortTypeCV, portName, false);
fCvOut.ports[j].rindex = i;
fCvOut.ports[j].param = params + cvIns + j;


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


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


j = params + cvIns + j;
j = fCvOut.ports[j].param;
kData->param.data[j].type = PARAMETER_OUTPUT;
kData->param.data[j].index = j; kData->param.data[j].index = j;
kData->param.data[j].rindex = i; kData->param.data[j].rindex = i;
kData->param.data[j].hints = 0x0;
kData->param.data[j].hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
kData->param.data[j].midiChannel = 0; kData->param.data[j].midiChannel = 0;
kData->param.data[j].midiCC = -1; kData->param.data[j].midiCC = -1;
kData->param.ranges[j].min = 0.0f;
kData->param.ranges[j].min = -1.0f;
kData->param.ranges[j].max = 1.0f; kData->param.ranges[j].max = 1.0f;
kData->param.ranges[j].def = 0.0f; kData->param.ranges[j].def = 0.0f;
kData->param.ranges[j].step = 0.01f; kData->param.ranges[j].step = 0.01f;
kData->param.ranges[j].stepSmall = 0.001f; kData->param.ranges[j].stepSmall = 0.001f;
kData->param.ranges[j].stepLarge = 0.1f; kData->param.ranges[j].stepLarge = 0.1f;
fParamBuffers[j] = 0.0f;
} }
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)");
@@ -3155,6 +3157,21 @@ public:
for (i=0; i < kData->audioOut.count; ++i) for (i=0; i < kData->audioOut.count; ++i)
carla_zeroFloat(fAudioOutBuffers[i], frames); carla_zeroFloat(fAudioOutBuffers[i], frames);


// --------------------------------------------------------------------------------------------------------
// Set CV input buffers

for (i=0; i < fCvIn.count; ++i)
{
const uint32_t cvIndex(fCvIn.ports[i].param);
const float cvValue((fCvIn.ports[i].port->getBuffer()+timeOffset)[0]);

if (fParamBuffers[cvIndex] != cvValue)
{
fParamBuffers[cvIndex] = cvValue;
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(cvIndex), 0, cvValue);
}
}

// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Run plugin // Run plugin


@@ -3267,6 +3284,18 @@ public:
} }
#endif #endif


// --------------------------------------------------------------------------------------------------------
// Set CV output buffers

for (i=0; i < fCvOut.count; ++i)
{
const uint32_t cvIndex(fCvOut.ports[i].param);
const float cvValue(fCvOut.ports[i].port->getBuffer()[0]);

fCvOut.ports[i].port->writeBuffer(frames, timeOffset);
fParamBuffers[cvIndex] = cvValue;
}

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


kData->singleMutex.unlock(); kData->singleMutex.unlock();
@@ -3292,6 +3321,32 @@ public:
fAudioOutBuffers[i] = new float[newBufferSize]; fAudioOutBuffers[i] = new float[newBufferSize];
} }


for (uint32_t i=0; i < fCvIn.count; ++i)
{
if (CarlaEngineCVPort* const port = fCvIn.ports[i].port)
{
port->setBufferSize(newBufferSize);

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

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

for (uint32_t i=0; i < fCvOut.count; ++i)
{
if (CarlaEngineCVPort* const port = fCvOut.ports[i].port)
{
port->setBufferSize(newBufferSize);

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

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

if (fHandle2 == nullptr) if (fHandle2 == nullptr)
{ {
for (uint32_t i=0; i < kData->audioIn.count; ++i) for (uint32_t i=0; i < kData->audioIn.count; ++i)
@@ -3390,6 +3445,8 @@ public:
{ {
fEventsIn.initBuffers(kData->engine); fEventsIn.initBuffers(kData->engine);
fEventsOut.initBuffers(kData->engine); fEventsOut.initBuffers(kData->engine);
fCvIn.initBuffers(kData->engine);
fCvOut.initBuffers(kData->engine);


CarlaPlugin::initBuffers(); CarlaPlugin::initBuffers();
} }
@@ -3436,6 +3493,8 @@ public:


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


CarlaPlugin::clearBuffers(); CarlaPlugin::clearBuffers();


@@ -4303,7 +4362,7 @@ public:
{ {
const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types); const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);


if (! (LV2_IS_PORT_AUDIO(portTypes) || LV2_IS_PORT_CONTROL(portTypes) || LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes)))
if (! is_lv2_port_supported(portTypes))
{ {
if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor->Ports[i].Properties)) if (! LV2_IS_PORT_OPTIONAL(fRdfDescriptor->Ports[i].Properties))
{ {
@@ -5326,7 +5385,7 @@ private:
static void carla_lilv_set_port_value(const char* port_symbol, void* user_data, const void* value, uint32_t size, uint32_t type) static void carla_lilv_set_port_value(const char* port_symbol, void* user_data, const void* value, uint32_t size, uint32_t type)
{ {
CARLA_ASSERT(user_data != nullptr); CARLA_ASSERT(user_data != nullptr);
carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i", port_symbol, user_data, value, size, type);
carla_debug("carla_lilv_set_port_value(\"%s\", %p, %p, %i, %i)", port_symbol, user_data, value, size, type);


if (user_data == nullptr) if (user_data == nullptr)
return; return;


+ 9
- 8
source/carla_backend.py View File

@@ -116,14 +116,15 @@ PLUGIN_OPTION_SEND_PITCHBEND = 0x080
PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100 PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100


# Parameter Hints # Parameter Hints
PARAMETER_IS_BOOLEAN = 0x01
PARAMETER_IS_INTEGER = 0x02
PARAMETER_IS_LOGARITHMIC = 0x04
PARAMETER_IS_ENABLED = 0x08
PARAMETER_IS_AUTOMABLE = 0x10
PARAMETER_USES_SAMPLERATE = 0x20
PARAMETER_USES_SCALEPOINTS = 0x40
PARAMETER_USES_CUSTOM_TEXT = 0x80
PARAMETER_IS_BOOLEAN = 0x001
PARAMETER_IS_INTEGER = 0x002
PARAMETER_IS_LOGARITHMIC = 0x004
PARAMETER_IS_ENABLED = 0x008
PARAMETER_IS_AUTOMABLE = 0x010
PARAMETER_IS_READ_ONLY = 0x020
PARAMETER_USES_SAMPLERATE = 0x040
PARAMETER_USES_SCALEPOINTS = 0x080
PARAMETER_USES_CUSTOM_TEXT = 0x100


# Custom Data types # Custom Data types
CUSTOM_DATA_INVALID = None CUSTOM_DATA_INVALID = None


+ 3
- 0
source/carla_shared.py View File

@@ -943,6 +943,9 @@ class PluginParameter(QWidget):
self.ui.sb_control.setEnabled(False) self.ui.sb_control.setEnabled(False)
self.ui.sb_channel.setEnabled(False) self.ui.sb_channel.setEnabled(False)


if pHints & PARAMETER_IS_READ_ONLY:
self.ui.widget.setReadOnly(True)

elif pType == PARAMETER_OUTPUT: elif pType == PARAMETER_OUTPUT:
self.ui.widget.setMinimum(pInfo['minimum']) self.ui.widget.setMinimum(pInfo['minimum'])
self.ui.widget.setMaximum(pInfo['maximum']) self.ui.widget.setMaximum(pInfo['maximum'])


Loading…
Cancel
Save