Browse Source

Initial LV2 worker code, still incomplete

tags/1.9.4
falkTX 11 years ago
parent
commit
692dff2ee7
5 changed files with 142 additions and 49 deletions
  1. +2
    -2
      source/backend/engine/CarlaEngineOsc.cpp
  2. +1
    -0
      source/backend/plugin/CarlaPlugin.pro
  3. +129
    -34
      source/backend/plugin/Lv2Plugin.cpp
  4. +1
    -1
      source/backend/plugin/Makefile
  5. +9
    -12
      source/utils/Lv2AtomQueue.hpp

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

@@ -370,8 +370,8 @@ int CarlaEngineOsc::handleMessage(const bool isTCP, const char* const path, cons
}
#endif

// Plugin-specific methods, FIXME
#if 0 //def WANT_LV2
// Plugin-specific methods
#ifdef WANT_LV2
if (std::strcmp(method, "lv2_atom_transfer") == 0)
return handleMsgLv2AtomTransfer(plugin, argc, argv, types);
if (std::strcmp(method, "lv2_event_transfer") == 0)


+ 1
- 0
source/backend/plugin/CarlaPlugin.pro View File

@@ -78,6 +78,7 @@ HEADERS += \
../../utils/CarlaString.hpp

INCLUDEPATH = . .. \
../engine \
../../includes \
../../libs \
../../utils


+ 129
- 34
source/backend/plugin/Lv2Plugin.cpp View File

@@ -22,6 +22,9 @@
#include "CarlaPluginGui.hpp"
#include "CarlaLv2Utils.hpp"

#include "CarlaEngineOsc.hpp"
#include "Lv2AtomQueue.hpp"

#include <QtCore/QDir>

extern "C" {
@@ -121,7 +124,6 @@ const uint32_t kFeatureIdStrictBounds = 10;
const uint32_t kFeatureIdUriMap = 11;
const uint32_t kFeatureIdUridMap = 12;
const uint32_t kFeatureIdUridUnmap = 13;
#if 0
const uint32_t kFeatureIdWorker = 14;
const uint32_t kFeatureIdUiDataAccess = 15;
const uint32_t kFeatureIdUiInstanceAccess = 16;
@@ -131,16 +133,6 @@ const uint32_t kFeatureIdUiResize = 19;
const uint32_t kFeatureIdExternalUi = 20;
const uint32_t kFeatureIdExternalUiOld = 21;
const uint32_t kFeatureCount = 22;
#else
const uint32_t kFeatureIdUiDataAccess = 14;
const uint32_t kFeatureIdUiInstanceAccess = 15;
const uint32_t kFeatureIdUiParent = 16;
const uint32_t kFeatureIdUiPortMap = 17;
const uint32_t kFeatureIdUiResize = 18;
const uint32_t kFeatureIdExternalUi = 19;
const uint32_t kFeatureIdExternalUiOld = 20;
const uint32_t kFeatureCount = 21;
#endif
/**@}*/

const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000
@@ -485,10 +477,8 @@ public:
if (fFeatures[kFeatureIdUridUnmap] != nullptr && fFeatures[kFeatureIdUridUnmap]->data != nullptr)
delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data;

#if 0
if (fFeatures[kFeatureIdWorker] != nullptr && fFeatures[kFeatureIdWorker]->data != nullptr)
delete (LV2_Worker_Schedule*)fFeatures[kFeatureIdWorker]->data;
#endif

for (uint32_t i=0; i < kFeatureCount; ++i)
{
@@ -2314,6 +2304,46 @@ public:

if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port != nullptr)
{
// ----------------------------------------------------------------------------------------------------
// Message Input

if (fAtomQueueIn.tryLock())
{
if (! fAtomQueueIn.isEmpty())
{
uint32_t portIndex;
const LV2_Atom* atom;

k = fEventsIn.ctrlIndex;

while (fAtomQueueIn.get(&portIndex, &atom))
{
const uint32_t evInPadSize(lv2_atom_pad_size(sizeof(LV2_Atom_Event) + atom->size));

if (evInAtomOffsets[k] + evInPadSize >= MAX_EVENT_BUFFER)
break;

//if (atom->type == CARLA_URI_MAP_ID_ATOM_WORKER)
//{
// const LV2_Atom_Worker* const atomWorker = (const LV2_Atom_Worker*)atom;
// fExt.worker->work_response(fHandle, atomWorker->body.size, atomWorker->body.data);
// continue;
//}

LV2_Atom_Event* const aev(getLv2AtomEvent(fEventsIn.ctrl->atom, evInAtomOffsets[k]));
aev->time.frames = 0;
aev->body.type = atom->type;
aev->body.size = atom->size;
std::memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size);

evInAtomOffsets[k] += evInPadSize;
fEventsIn.ctrl->atom->atom.size = evInAtomOffsets[k];
}
}

fAtomQueueIn.unlock();
}

// ----------------------------------------------------------------------------------------------------
// MIDI Input (External)

@@ -2340,7 +2370,7 @@ public:
const uint32_t evInPadSize(lv2_atom_pad_size(sizeof(LV2_Atom_Event) + 3));

if (evInAtomOffsets[k] + evInPadSize >= MAX_EVENT_BUFFER)
continue;
break;

LV2_Atom_Event* const aev = getLv2AtomEvent(fEventsIn.ctrl->atom, evInAtomOffsets[k]);
aev->time.frames = 0;
@@ -3334,23 +3364,22 @@ protected:
}
}

#if 0
// -------------------------------------------------------------------

LV2_Worker_Status handleWorkerSchedule(const uint32_t size, const void* const data)
{
carla_stdout("Lv2Plugin::handleWorkerSchedule(%i, %p)", size, data);

if (! ext.worker)
if (fExt.worker == nullptr || fExt.worker->work == nullptr)
{
carla_stderr("Lv2Plugin::handleWorkerSchedule(%i, %p) - plugin has no worker", size, data);
return LV2_WORKER_ERR_UNKNOWN;
}

if (x_engine->isOffline())
ext.worker->work(handle, carla_lv2_worker_respond, this, size, data);
else
postponeEvent(PluginPostEventCustom, size, 0, 0.0, data);
//if (kData->engine->isOffline())
fExt.worker->work(fHandle, carla_lv2_worker_respond, this, size, data);
//else
// postponeEvent(PluginPostEventCustom, size, 0, 0.0, data);

return LV2_WORKER_SUCCESS;
}
@@ -3359,6 +3388,7 @@ protected:
{
carla_stdout("Lv2Plugin::handleWorkerRespond(%i, %p)", size, data);

#if 0
LV2_Atom_Worker workerAtom;
workerAtom.atom.type = CARLA_URI_MAP_ID_ATOM_WORKER;
workerAtom.atom.size = sizeof(LV2_Atom_Worker_Body);
@@ -3366,10 +3396,10 @@ protected:
workerAtom.body.data = data;

atomQueueIn.put(0, (const LV2_Atom*)&workerAtom);
#endif

return LV2_WORKER_SUCCESS;
}
#endif

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

@@ -3381,7 +3411,7 @@ protected:
fUi.descriptor->cleanup(fUi.handle);

fUi.handle = nullptr;
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0, nullptr);
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
}

uint32_t handleUiPortMap(const char* const symbol)
@@ -3444,8 +3474,8 @@ protected:
if (buffer == nullptr)
return;

//const LV2_Atom* const atom = (const LV2_Atom*)buffer;
//handleTransferAtom(rindex, atom);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;
fAtomQueueIn.put(rindex, atom);
}
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
{
@@ -3454,8 +3484,8 @@ protected:
if (buffer == nullptr)
return;

//const LV2_Atom* const atom = (const LV2_Atom*)buffer;
//handleTransferEvent(rindex, atom);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;
fAtomQueueIn.put(rindex, atom);
}
}

@@ -3666,11 +3696,9 @@ public:
uridUnmapFt->handle = this;
uridUnmapFt->unmap = carla_lv2_urid_unmap;

#if 0
LV2_Worker_Schedule* const workerFt = new LV2_Worker_Schedule;
workerFt->handle = this;
workerFt->schedule_work = carla_lv2_worker_schedule;
#endif

// ---------------------------------------------------------------
// initialize features (part 2)
@@ -3731,11 +3759,9 @@ public:
fFeatures[kFeatureIdUridUnmap]->URI = LV2_URID__unmap;
fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;

#if 0
fFeatures[kFeatureIdWorker] = new LV2_Feature;
fFeatures[kFeatureIdWorker]->URI = LV2_WORKER__schedule;
fFeatures[kFeatureIdWorker]->data = workerFt;
#endif

if (! needsFixedBuffer())
fFeatures[kFeatureIdBufSizeFixed]->URI = LV2_BUF_SIZE__boundedBlockLength;
@@ -4244,6 +4270,34 @@ public:
return true;
}

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

void handleTransferAtom(const int32_t portIndex, const char* const typeStr, LV2_Atom* const atom)
{
CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(atom != nullptr);
CARLA_ASSERT(typeStr != nullptr);
carla_debug("Lv2Plugin::handleTransferAtom(%i, %s, %p)", portIndex, typeStr, atom);

atom->type = carla_lv2_urid_map(this, typeStr);

fAtomQueueIn.put(portIndex, atom);
}

void handleTransferEvent(const int32_t portIndex, const char* const typeStr, LV2_Atom* const atom)
{
CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(atom != nullptr);
CARLA_ASSERT(typeStr != nullptr);
carla_debug("Lv2Plugin::handleTransferEvent(%i, %s, %p)", portIndex, typeStr, atom);

atom->type = carla_lv2_urid_map(this, typeStr);

fAtomQueueIn.put(portIndex, atom);
}

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

private:
LV2_Handle fHandle;
LV2_Handle fHandle2;
@@ -4255,6 +4309,9 @@ private:
float** fAudioOutBuffers;
float* fParamBuffers;

Lv2AtomQueue fAtomQueueIn;
Lv2AtomQueue fAtomQueueOut;

Lv2PluginEventData fEventsIn;
Lv2PluginEventData fEventsOut;
Lv2PluginOptions fLv2Options;
@@ -4609,14 +4666,13 @@ private:
return ((Lv2Plugin*)handle)->getCustomURIString(urid);
}

#if 0
// -------------------------------------------------------------------
// Worker Feature

static LV2_Worker_Status carla_lv2_worker_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void* data)
{
carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle, size, data);
CARLA_ASSERT(handle != nullptr);
carla_debug("carla_lv2_worker_schedule(%p, %i, %p)", handle, size, data);

if (handle == nullptr)
return LV2_WORKER_ERR_UNKNOWN;
@@ -4626,15 +4682,14 @@ private:

static LV2_Worker_Status carla_lv2_worker_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void* data)
{
carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle, size, data);
CARLA_ASSERT(handle != nullptr);
carla_debug("carla_lv2_worker_respond(%p, %i, %p)", handle, size, data);

if (handle == nullptr)
return LV2_WORKER_ERR_UNKNOWN;

return ((Lv2Plugin*)handle)->handleWorkerRespond(size, data);
}
#endif

// -------------------------------------------------------------------
// UI Port-Map Feature
@@ -4697,6 +4752,46 @@ private:
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Lv2Plugin)
};

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

int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
{
carla_debug("CarlaOsc::handleMsgLv2AtomTransfer()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iss");

const int32_t portIndex = argv[0]->i;
const char* const typeStr = (const char*)&argv[1]->s;
const char* const atomBuf = (const char*)&argv[2]->s;

QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf);

LV2_Atom* const atom = (LV2_Atom*)chunk.data();

((Lv2Plugin*)plugin)->handleTransferAtom(portIndex, typeStr, atom);

return 0;
}

int CarlaEngineOsc::handleMsgLv2EventTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
{
carla_debug("CarlaOsc::handleMsgLv2EventTransfer()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iss");

const int32_t portIndex = argv[0]->i;
const char* const typeStr = (const char*)&argv[1]->s;
const char* const atomBuf = (const char*)&argv[2]->s;

QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf);

LV2_Atom* const atom = (LV2_Atom*)chunk.data();

((Lv2Plugin*)plugin)->handleTransferEvent(portIndex, typeStr, atom);

return 0;
}

CARLA_BACKEND_END_NAMESPACE

#else // WANT_VST


+ 1
- 1
source/backend/plugin/Makefile View File

@@ -8,7 +8,7 @@ include ../Makefile.mk

# --------------------------------------------------------------

BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo) -I../engine

ifeq ($(HAVE_QT5),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Xml Qt5Widgets)


+ 9
- 12
source/utils/Lv2AtomQueue.hpp View File

@@ -18,7 +18,7 @@
#ifndef __LV2_ATOM_QUEUE_HPP__
#define __LV2_ATOM_QUEUE_HPP__

#include "CarlaUtils.hpp"
#include "CarlaMutex.hpp"

#include <cstring> // memcpy, memset
#include "lv2/atom.h"
@@ -32,7 +32,7 @@ public:
empty = true;
full = false;

::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
std::memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
}

void copyDataFrom(Lv2AtomQueue* const queue)
@@ -42,8 +42,8 @@ public:
lock();

// copy data from queue
::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
std::memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
std::memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
index = queue->index;
indexPool = queue->indexPool;
empty = queue->empty;
@@ -53,8 +53,8 @@ public:
unlock();

// reset queque
::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
std::memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
std::memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
queue->index = queue->indexPool = 0;
queue->empty = true;
queue->full = false;
@@ -106,7 +106,7 @@ public:
data[i].size = atom->size;
data[i].type = atom->type;
data[i].poolOffset = indexPool;
::memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(atom), atom->size);
std::memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(atom), atom->size);
empty = false;
full = (i == MAX_SIZE-1);
indexPool += atom->size;
@@ -117,6 +117,7 @@ public:
unlock();
}

// needs to be locked first!
bool get(uint32_t* const portIndex, const LV2_Atom** const atom)
{
CARLA_ASSERT(portIndex && atom);
@@ -124,9 +125,6 @@ public:
if (empty || ! (portIndex && atom))
return false;

if (! tryLock())
return false;

full = false;

if (data[index].size == 0)
@@ -140,7 +138,7 @@ public:

retAtom.atom.size = data[index].size;
retAtom.atom.type = data[index].type;
::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size);
std::memcpy(retAtom.data, dataPool + data[index].poolOffset, data[index].size);

*portIndex = data[index].portIndex;
*atom = (LV2_Atom*)&retAtom;
@@ -152,7 +150,6 @@ public:
index++;
empty = false;

unlock();
return true;
}



Loading…
Cancel
Save