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()
* @{
*/
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.
*/
virtual void writeBuffer(CarlaEngine* const engine);
virtual void writeBuffer(const uint32_t frames, const uint32_t timeOffset);

/*!
* 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);

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(engine != nullptr);

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

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

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(engine != nullptr);

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

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

float* const jackBuffer((float*)jackbridge_port_get_buffer(kPort, fBufferSize));
carla_copyFloat(jackBuffer, fBuffer, fBufferSize);
carla_copyFloat(jackBuffer+timeOffset, fBuffer, frames);
}

private:


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

@@ -510,10 +510,9 @@ public:
if (params > 0)
{
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());


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

@@ -491,10 +491,9 @@ public:
if (params > 0)
{
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());


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

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

#include "CarlaPluginInternal.hpp"

#define WANT_LV2

#ifdef WANT_LV2

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

params += cvIns + cvOuts;

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

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

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

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)
@@ -1579,51 +1575,57 @@ public:
if (LV2_IS_PORT_INPUT(portTypes))
{
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());

if (fHandle2 != nullptr)
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].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].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].def = 0.0f;
kData->param.ranges[j].step = 0.01f;
kData->param.ranges[j].stepSmall = 0.001f;
kData->param.ranges[j].stepLarge = 0.1f;
fParamBuffers[j] = 0.0f;

}
else if (LV2_IS_PORT_OUTPUT(portTypes))
{
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());

if (fHandle2 != nullptr)
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].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].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].def = 0.0f;
kData->param.ranges[j].step = 0.01f;
kData->param.ranges[j].stepSmall = 0.001f;
kData->param.ranges[j].stepLarge = 0.1f;
fParamBuffers[j] = 0.0f;
}
else
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)
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

@@ -3267,6 +3284,18 @@ public:
}
#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();
@@ -3292,6 +3321,32 @@ public:
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)
{
for (uint32_t i=0; i < kData->audioIn.count; ++i)
@@ -3390,6 +3445,8 @@ public:
{
fEventsIn.initBuffers(kData->engine);
fEventsOut.initBuffers(kData->engine);
fCvIn.initBuffers(kData->engine);
fCvOut.initBuffers(kData->engine);

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

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

CarlaPlugin::clearBuffers();

@@ -4303,7 +4362,7 @@ public:
{
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))
{
@@ -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)
{
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)
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

# 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_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_channel.setEnabled(False)

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

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


Loading…
Cancel
Save