Browse Source

Carla: More work for lv2 atom messages support

tags/v0.9.0
falkTX 13 years ago
parent
commit
c2986a5aa4
9 changed files with 512 additions and 402 deletions
  1. +8
    -5
      c++/carla-backend/Makefile
  2. +7
    -4
      c++/carla-backend/Makefile.dbg
  3. +63
    -217
      c++/carla-backend/lv2.cpp
  4. +43
    -11
      c++/carla-bridge/Makefile
  5. +6
    -6
      c++/carla-bridge/carla_bridge_client.h
  6. +4
    -4
      c++/carla-bridge/carla_bridge_osc.h
  7. +358
    -149
      c++/carla-bridge/carla_bridge_ui-lv2.cpp
  8. +15
    -0
      c++/carla-includes/carla_lv2.h
  9. +8
    -6
      c++/carla-includes/carla_osc_includes.h

+ 8
- 5
c++/carla-backend/Makefile View File

@@ -16,7 +16,7 @@ HAVE_SUIL = $(shell pkg-config --exists suil-0 && echo true)


BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -mfpmath=sse -Wall -I. -I../carla-includes -I../carla-jackbridge BASE_FLAGS = -O2 -ffast-math -fomit-frame-pointer -fPIC -mtune=generic -msse -mfpmath=sse -Wall -I. -I../carla-includes -I../carla-jackbridge


CARLA_C_FLAGS = $(BASE_FLAGS) -std=c99 $(CFLAGS)
# CARLA_C_FLAGS = $(BASE_FLAGS) -std=c99 $(CFLAGS)


CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS) CARLA_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x $(CXXFLAGS)
CARLA_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtGui) CARLA_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtGui)
@@ -68,9 +68,9 @@ OBJS = \
carla_shared.o \ carla_shared.o \
carla_threads.o \ carla_threads.o \
ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \ ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \
rtmempool/rtmempool.o \
../carla-jackbridge/carla_jackbridge.o \ ../carla-jackbridge/carla_jackbridge.o \
../carla-lilv/carla_lilv.a
../carla-lilv/carla_lilv.a \
../carla-rtmempool/carla_rtmempool.a


ifeq ($(WANT_RTAUDIO),true) ifeq ($(WANT_RTAUDIO),true)
CARLA_CXX_FLAGS += -Irtaudio-4.0.11 -Irtmidi-2.0.0 -DCARLA_ENGINE_RTAUDIO -DHAVE_GETTIMEOFDAY -D_FORTIFY_SOURCE=2 CARLA_CXX_FLAGS += -Irtaudio-4.0.11 -Irtmidi-2.0.0 -DCARLA_ENGINE_RTAUDIO -DHAVE_GETTIMEOFDAY -D_FORTIFY_SOURCE=2
@@ -90,8 +90,8 @@ carla_backend.so: $(OBJS)


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


.c.o:
$(CC) -c $< $(CARLA_C_FLAGS) -o $@
# .c.o:
# $(CC) -c $< $(CARLA_C_FLAGS) -o $@


.cpp.o: .cpp.o:
$(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@ $(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@
@@ -99,5 +99,8 @@ carla_backend.so: $(OBJS)
../carla-lilv/carla_lilv.a: ../carla-lilv/carla_lilv.a:
$(MAKE) -C ../carla-lilv $(MAKE) -C ../carla-lilv


../carla-rtmempool/carla_rtmempool.a:
$(MAKE) -C ../carla-rtmempool

clean: clean:
rm -f $(OBJS) *.a *.so *.dll rm -f $(OBJS) *.a *.so *.dll

+ 7
- 4
c++/carla-backend/Makefile.dbg View File

@@ -68,9 +68,9 @@ OBJS = \
carla_shared.o \ carla_shared.o \
carla_threads.o \ carla_threads.o \
ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \ ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \
rtmempool/rtmempool.o \
../carla-jackbridge/carla_jackbridge.o \ ../carla-jackbridge/carla_jackbridge.o \
../carla-lilv/carla_lilv.a
../carla-lilv/carla_lilv.a \
../carla-rtmempool/carla_rtmempool.a


ifeq ($(WANT_RTAUDIO),true) ifeq ($(WANT_RTAUDIO),true)
CARLA_CXX_FLAGS += -Irtaudio-4.0.11 -Irtmidi-2.0.0 -DCARLA_ENGINE_RTAUDIO -DHAVE_GETTIMEOFDAY -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__ CARLA_CXX_FLAGS += -Irtaudio-4.0.11 -Irtmidi-2.0.0 -DCARLA_ENGINE_RTAUDIO -DHAVE_GETTIMEOFDAY -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__
@@ -90,8 +90,8 @@ carla_backend.so: $(OBJS)


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


.c.o:
$(CC) -c $< $(CARLA_C_FLAGS) -o $@
# .c.o:
# $(CC) -c $< $(CARLA_C_FLAGS) -o $@


.cpp.o: .cpp.o:
$(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@ $(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@
@@ -99,5 +99,8 @@ carla_backend.so: $(OBJS)
../carla-lilv/carla_lilv.a: ../carla-lilv/carla_lilv.a:
$(MAKE) -C ../carla-lilv $(MAKE) -C ../carla-lilv


../carla-rtmempool/carla_rtmempool.a:
$(MAKE) -C ../carla-rtmempool

clean: clean:
rm -f $(OBJS) *.a *.so *.dll rm -f $(OBJS) *.a *.so *.dll

+ 63
- 217
c++/carla-backend/lv2.cpp View File

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


#include "carla_plugin.h" #include "carla_plugin.h"
#include "carla_lv2.h" #include "carla_lv2.h"

#include "lv2_atom_queue.h"
#include "rtmempool/rtmempool.h" #include "rtmempool/rtmempool.h"


#include <QtCore/QDir> #include <QtCore/QDir>
@@ -66,7 +68,6 @@ const unsigned int PARAMETER_IS_TRIGGER = 0x2000; //!< LV2 Parameter is tr
* @defgroup Lv2FeatureIds LV2 Feature Ids * @defgroup Lv2FeatureIds LV2 Feature Ids
* *
* Static index list of the internal LV2 Feature Ids. * Static index list of the internal LV2 Feature Ids.
* \see CarlaPlugin::hints
* @{ * @{
*/ */
const uint32_t lv2_feature_id_bufsize_bounded = 0; const uint32_t lv2_feature_id_bufsize_bounded = 0;
@@ -98,7 +99,6 @@ const uint32_t lv2_feature_count = 22;
* @defgroup Lv2EventTypes LV2 Event Data/Types * @defgroup Lv2EventTypes LV2 Event Data/Types
* *
* Data and buffer types for LV2 EventData ports. * Data and buffer types for LV2 EventData ports.
* \see CarlaPlugin::hints
* @{ * @{
*/ */
const unsigned int CARLA_EVENT_DATA_ATOM = 0x01; const unsigned int CARLA_EVENT_DATA_ATOM = 0x01;
@@ -112,7 +112,6 @@ const unsigned int CARLA_EVENT_TYPE_MIDI = 0x20;
* @defgroup Lv2UriMapIds LV2 URI Map Ids * @defgroup Lv2UriMapIds LV2 URI Map Ids
* *
* Static index list of the internal LV2 URI Map Ids. * Static index list of the internal LV2 URI Map Ids.
* \see CarlaPlugin::hints
* @{ * @{
*/ */
const uint32_t CARLA_URI_MAP_ID_NULL = 0; const uint32_t CARLA_URI_MAP_ID_NULL = 0;
@@ -137,16 +136,6 @@ const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 18;
const uint32_t CARLA_URI_MAP_ID_COUNT = 19; const uint32_t CARLA_URI_MAP_ID_COUNT = 19;
/**@}*/ /**@}*/


struct LV2_Atom_Worker_Body {
uint32_t size;
const void* data;
};

struct LV2_Atom_Worker {
LV2_Atom atom;
LV2_Atom_Worker_Body body;
};

struct Lv2EventData { struct Lv2EventData {
uint32_t type; uint32_t type;
uint32_t rindex; uint32_t rindex;
@@ -220,173 +209,6 @@ LV2_Atom_Event* getLv2AtomEvent(LV2_Atom_Sequence* const atom, const uint32_t of
return (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atom) + offset); return (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atom) + offset);
} }


class Lv2AtomQueue
{
public:
Lv2AtomQueue()
{
index = indexPool = 0;
empty = true;
full = false;

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

void copyDataFrom(Lv2AtomQueue* const queue)
{
// lock mutexes
queue->mutex.lock();
mutex.lock();

// copy data from queue
memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE);
memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE);
index = queue->index;
indexPool = queue->indexPool;
empty = queue->empty;
full = queue->full;

// unlock our mutex, no longer needed
mutex.unlock();

// reset queque
memset(queue->data, 0, sizeof(datatype)*MAX_SIZE);
memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE);
queue->index = queue->indexPool = 0;
queue->empty = true;
queue->full = false;

// unlock queque mutex
queue->mutex.unlock();
}

bool isEmpty()
{
return empty;
}

bool isFull()
{
return full;
}

void lock()
{
mutex.lock();
}

void unlock()
{
mutex.unlock();
}

void put(const uint32_t portIndex, const LV2_Atom* const atom, const bool lock = true)
{
qDebug("Lv2AtomQueue::put(%i, size:%i, type:%i, %s)", portIndex, atom->size, atom->type, bool2str(lock));
Q_ASSERT(atom && atom->size > 0);
Q_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow

if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE)
return;

if (lock)
mutex.lock();

for (unsigned short i=0; i < MAX_SIZE; i++)
{
if (data[i].size == 0)
{
data[i].portIndex = portIndex;
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);
empty = false;
full = (i == MAX_SIZE-1);
indexPool += atom->size;
break;
}
}

if (lock)
mutex.unlock();
}

bool get(uint32_t* const portIndex, const LV2_Atom** const atom, const bool lock = true)
{
qDebug("Lv2AtomQueue::get(%p, %p, %s)", portIndex, atom, bool2str(lock));
Q_ASSERT(portIndex && atom);

if (empty || ! (portIndex && atom))
return false;

if (lock)
mutex.lock();

full = false;

if (data[index].size == 0)
{
index = indexPool = 0;
empty = true;

if (lock)
mutex.lock();

return false;
}

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

*portIndex = data[index].portIndex;
*atom = (LV2_Atom*)&retAtom;

data[index].portIndex = 0;
data[index].size = 0;
data[index].type = CARLA_URI_MAP_ID_NULL;
data[index].poolOffset = 0;
index++;
empty = false;

if (lock)
mutex.unlock();

return true;
}

private:
struct datatype {
size_t size;
LV2_URID type;
uint32_t portIndex;
uint32_t poolOffset;

datatype()
: size(0),
type(CARLA_URI_MAP_ID_NULL),
portIndex(0),
poolOffset(0) {}
};

static const unsigned short MAX_SIZE = 128;
static const unsigned short MAX_POOL_SIZE = 8192;

datatype data[MAX_SIZE];
unsigned char dataPool[MAX_POOL_SIZE];

struct {
LV2_Atom atom;
unsigned char data[MAX_POOL_SIZE];
} retAtom;

unsigned short index, indexPool;
bool empty, full;

QMutex mutex;
};

class Lv2Plugin : public CarlaPlugin class Lv2Plugin : public CarlaPlugin
{ {
public: public:
@@ -1030,7 +852,7 @@ public:
cdata.type = type; cdata.type = type;
cdata.key = key; cdata.key = key;
cdata.value = value; cdata.value = value;
uiTransferEvent(&cdata);
uiTransferCustomData(&cdata);
} }
} }


@@ -1224,7 +1046,7 @@ public:
if (gui.type == GUI_EXTERNAL_OSC) if (gui.type == GUI_EXTERNAL_OSC)
{ {
QByteArray chunk((const char*)atom, sizeof(LV2_Atom) + atom->size); QByteArray chunk((const char*)atom, sizeof(LV2_Atom) + atom->size);
osc_send_lv2_transfer_event(&osc.data, portIndex, chunk.toBase64().constData());
osc_send_lv2_transfer_event(&osc.data, portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
} }
else else
#endif #endif
@@ -2940,7 +2762,18 @@ public:
else else
#endif #endif
{ {
uiTransferAtom(); // TODO
if (ui.handle && ui.descriptor && ui.descriptor->port_event)
{
LV2_Atom_MidiEvent midiEv;
midiEv.event.time.frames = 0;
midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
midiEv.event.body.size = 3;
midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
midiEv.data[1] = note;
midiEv.data[2] = velo;

ui.descriptor->port_event(ui.handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
}
} }
} }


@@ -2963,7 +2796,18 @@ public:
else else
#endif #endif
{ {
uiTransferAtom(); // TODO
if (ui.handle && ui.descriptor && ui.descriptor->port_event)
{
LV2_Atom_MidiEvent midiEv;
midiEv.event.time.frames = 0;
midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
midiEv.event.body.size = 3;
midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
midiEv.data[1] = note;
midiEv.data[2] = 0;

ui.descriptor->port_event(ui.handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
}
} }
} }


@@ -3114,18 +2958,19 @@ public:


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


void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom)
void handleTransferAtom(const int32_t portIndex, const LV2_Atom* const atom)
{ {
qDebug("Lv2Plugin::handleAtomTransfer(%i, %p)", portIndex, atom);
qDebug("Lv2Plugin::handleTransferAtom(%i, %p)", portIndex, atom);
Q_ASSERT(portIndex >= 0);
Q_ASSERT(atom); Q_ASSERT(atom);


// FIXME - is this correct?
//atomQueueIn.put(portIndex, atom);
atomQueueIn.put(portIndex, atom);
} }


void handleTransferEvent(const uint32_t portIndex, const LV2_Atom* const atom)
void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom)
{ {
qDebug("Lv2Plugin::handleEventTransfer(%i, %p)", portIndex, atom);
qDebug("Lv2Plugin::handleTransferEvent(%i, %p)", portIndex, atom);
Q_ASSERT(portIndex >= 0);
Q_ASSERT(atom); Q_ASSERT(atom);


atomQueueIn.put(portIndex, atom); atomQueueIn.put(portIndex, atom);
@@ -3363,6 +3208,9 @@ public:
Q_ASSERT(buffer); Q_ASSERT(buffer);
Q_ASSERT(bufferSize == sizeof(float)); Q_ASSERT(bufferSize == sizeof(float));


if (bufferSize != sizeof(float))
return;

float value = *(float*)buffer; float value = *(float*)buffer;


for (uint32_t i=0; i < param.count; i++) for (uint32_t i=0; i < param.count; i++)
@@ -3446,14 +3294,9 @@ public:
} }
} }


void uiTransferAtom()
void uiTransferCustomData(const CustomData* const cdata)
{ {
// TODO
}

void uiTransferEvent(const CustomData* const cdata)
{
if (cdata->type == CUSTOM_DATA_INVALID || ! ui.descriptor->port_event)
if (cdata->type == CUSTOM_DATA_INVALID || ! (ui.handle && ui.descriptor && ui.descriptor->port_event))
return; return;


LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data; LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
@@ -4035,13 +3878,13 @@ public:
logFt->printf = carla_lv2_log_printf; logFt->printf = carla_lv2_log_printf;
logFt->vprintf = carla_lv2_log_vprintf; logFt->vprintf = carla_lv2_log_vprintf;


LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
rtmempool_allocator_init(rtMemPoolFt);

LV2_Programs_Host* const programsFt = new LV2_Programs_Host; LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
programsFt->handle = this; programsFt->handle = this;
programsFt->program_changed = carla_lv2_program_changed; programsFt->program_changed = carla_lv2_program_changed;


LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
rtmempool_allocator_init(rtMemPoolFt);

LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path; LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
stateMakePathFt->handle = this; stateMakePathFt->handle = this;
stateMakePathFt->path = carla_lv2_state_make_path; stateMakePathFt->path = carla_lv2_state_make_path;
@@ -4614,19 +4457,20 @@ CarlaPlugin* CarlaPlugin::newLV2(const initializer& init)
int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2) int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2)
{ {
qDebug("CarlaOsc::handle_lv2_atom_transfer()"); qDebug("CarlaOsc::handle_lv2_atom_transfer()");
CARLA_OSC_CHECK_OSC_TYPES(2, "ss");

//const char* const type = (const char*)&argv[0]->s;
//const char* const value = (const char*)&argv[1]->s;
CARLA_OSC_CHECK_OSC_TYPES(3, "iss");


//QByteArray chunk;
//chunk = QByteArray::fromBase64(value);
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;


//const LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf);


//CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin;
//lv2plugin->handleTransferAtom(atom, type);
LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin;


atom->type = lv2plugin->getCustomURID(typeStr);
lv2plugin->handleTransferAtom(portIndex, atom);


return 0; return 0;
} }
@@ -4634,18 +4478,20 @@ int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2)
int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2) int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2)
{ {
qDebug("CarlaOsc::handle_lv2_event_transfer()"); qDebug("CarlaOsc::handle_lv2_event_transfer()");
CARLA_OSC_CHECK_OSC_TYPES(2, "ss");
CARLA_OSC_CHECK_OSC_TYPES(3, "iss");


//const char* const type = (const char*)&argv[0]->s;
//const char* const value = (const char*)&argv[1]->s;
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(value);
QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf);


//const LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin;


//CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin;
//lv2plugin->handleTransferEvent(atom, type);
atom->type = lv2plugin->getCustomURID(typeStr);
lv2plugin->handleTransferEvent(portIndex, atom);


return 0; return 0;
} }


+ 43
- 11
c++/carla-bridge/Makefile View File

@@ -91,7 +91,9 @@ win64: carla-bridge-win64.exe
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_lv2-gtk2 # ui_lv2-gtk2


OBJS_UI_LV2_GTK2 = carla_bridge_ui-lv2__lv2-gtk2.o carla_bridge_toolkit-gtk2__lv2-gtk2.o carla_bridge_osc__lv2-gtk2.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_GTK2 = \
carla_bridge_ui-lv2__lv2-gtk2.o carla_bridge_toolkit-gtk2__lv2-gtk2.o carla_bridge_osc__lv2-gtk2.o \
../carla-lilv/carla_lilv.a ../carla-rtmempool/carla_rtmempool.a


carla-bridge-lv2-gtk2: $(OBJS_UI_LV2_GTK2) carla-bridge-lv2-gtk2: $(OBJS_UI_LV2_GTK2)
$(CXX) $^ $(LINK_UI_LV2_GTK2_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_LV2_GTK2_FLAGS) -o $@ && $(STRIP) $@
@@ -108,7 +110,9 @@ carla_bridge_osc__lv2-gtk2.o: carla_bridge_osc.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_lv2-gtk3 # ui_lv2-gtk3


OBJS_UI_LV2_GTK3 = carla_bridge_ui-lv2__lv2-gtk3.o carla_bridge_toolkit-gtk3__lv2-gtk3.o carla_bridge_osc__lv2-gtk3.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_GTK3 = \
carla_bridge_ui-lv2__lv2-gtk3.o carla_bridge_toolkit-gtk3__lv2-gtk3.o carla_bridge_osc__lv2-gtk3.o \
../carla-lilv/carla_lilv.a ../carla-rtmempool/carla_rtmempool.a


carla-bridge-lv2-gtk3: $(OBJS_UI_LV2_GTK3) carla-bridge-lv2-gtk3: $(OBJS_UI_LV2_GTK3)
$(CXX) $^ $(LINK_UI_LV2_GTK3_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_LV2_GTK3_FLAGS) -o $@ && $(STRIP) $@
@@ -125,7 +129,9 @@ carla_bridge_osc__lv2-gtk3.o: carla_bridge_osc.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_lv2-qt4 # ui_lv2-qt4


OBJS_UI_LV2_QT4 = carla_bridge_ui-lv2__lv2-qt4.o carla_bridge_toolkit-qt4__lv2-qt4.o carla_bridge_osc__lv2-qt4.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_QT4 = \
carla_bridge_ui-lv2__lv2-qt4.o carla_bridge_toolkit-qt4__lv2-qt4.o carla_bridge_osc__lv2-qt4.o \
../carla-lilv/carla_lilv.a ../carla-rtmempool/carla_rtmempool.a


carla-bridge-lv2-qt4: $(OBJS_UI_LV2_QT4) carla-bridge-lv2-qt4: $(OBJS_UI_LV2_QT4)
$(CXX) $^ $(LINK_UI_LV2_QT4_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_LV2_QT4_FLAGS) -o $@ && $(STRIP) $@
@@ -142,7 +148,9 @@ carla_bridge_osc__lv2-qt4.o: carla_bridge_osc.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_lv2-x11 # ui_lv2-x11


OBJS_UI_LV2_X11 = carla_bridge_ui-lv2__lv2-x11.o carla_bridge_toolkit-qt4__lv2-x11.o carla_bridge_osc__lv2-x11.o ../carla-lilv/carla_lilv.a
OBJS_UI_LV2_X11 = \
carla_bridge_ui-lv2__lv2-x11.o carla_bridge_toolkit-qt4__lv2-x11.o carla_bridge_osc__lv2-x11.o \
../carla-lilv/carla_lilv.a ../carla-rtmempool/carla_rtmempool.a


carla-bridge-lv2-x11: $(OBJS_UI_LV2_X11) carla-bridge-lv2-x11: $(OBJS_UI_LV2_X11)
$(CXX) $^ $(LINK_UI_LV2_X11_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_LV2_X11_FLAGS) -o $@ && $(STRIP) $@
@@ -159,7 +167,8 @@ carla_bridge_osc__lv2-x11.o: carla_bridge_osc.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_vst-hwnd # ui_vst-hwnd


OBJS_UI_VST_HWND = carla_bridge_ui-vst__vst-hwnd.o carla_bridge_toolkit-qt4__vst-hwnd.o carla_bridge_osc__vst-hwnd.o
OBJS_UI_VST_HWND = \
carla_bridge_ui-vst__vst-hwnd.o carla_bridge_toolkit-qt4__vst-hwnd.o carla_bridge_osc__vst-hwnd.o


carla-bridge-vst-hwnd.exe: $(OBJS_UI_VST_HWND) carla-bridge-vst-hwnd.exe: $(OBJS_UI_VST_HWND)
$(CXX) $^ $(LINK_UI_VST_HWND_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_VST_HWND_FLAGS) -o $@ && $(STRIP) $@
@@ -176,7 +185,8 @@ carla_bridge_osc__vst-hwnd.o: carla_bridge_osc.cpp
# -------------------------------------------------------------- # --------------------------------------------------------------
# ui_vst-x11 # ui_vst-x11


OBJS_UI_VST_X11 = carla_bridge_ui-vst__vst-x11.o carla_bridge_toolkit-qt4__vst-x11.o carla_bridge_osc__vst-x11.o
OBJS_UI_VST_X11 = \
carla_bridge_ui-vst__vst-x11.o carla_bridge_toolkit-qt4__vst-x11.o carla_bridge_osc__vst-x11.o


carla-bridge-vst-x11: $(OBJS_UI_VST_X11) carla-bridge-vst-x11: $(OBJS_UI_VST_X11)
$(CXX) $^ $(LINK_UI_VST_X11_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(LINK_UI_VST_X11_FLAGS) -o $@ && $(STRIP) $@
@@ -196,7 +206,8 @@ carla_bridge_osc__vst-x11.o: carla_bridge_osc.cpp
OBJS_POSIX32 = \ OBJS_POSIX32 = \
carla_bridge_plugin__posix32.o carla_bridge_osc__posix32.o carla_jackbridge__posix32.o \ carla_bridge_plugin__posix32.o carla_bridge_osc__posix32.o carla_jackbridge__posix32.o \
carla_engine__posix32.o carla_engine_jack__posix32.o carla_shared__posix32.o carla_threads__posix32.o \ carla_engine__posix32.o carla_engine_jack__posix32.o carla_shared__posix32.o carla_threads__posix32.o \
ladspa__posix32.o dssi__posix32.o lv2__posix32.o vst__posix32.o ../carla-lilv/carla_lilv_posix32.a
ladspa__posix32.o dssi__posix32.o lv2__posix32.o vst__posix32.o \
../carla-lilv/carla_lilv_posix32.a ../carla-rtmempool/carla_rtmempool_posix32.a


carla-bridge-posix32: $(OBJS_POSIX32) carla-bridge-posix32: $(OBJS_POSIX32)
$(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_32BIT_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_32BIT_FLAGS) -o $@ && $(STRIP) $@
@@ -240,7 +251,8 @@ vst__posix32.o: ../carla-backend/vst.cpp
OBJS_POSIX64 = \ OBJS_POSIX64 = \
carla_bridge_plugin__posix64.o carla_bridge_osc__posix64.o carla_jackbridge__posix64.o \ carla_bridge_plugin__posix64.o carla_bridge_osc__posix64.o carla_jackbridge__posix64.o \
carla_engine__posix64.o carla_engine_jack__posix64.o carla_shared__posix64.o carla_threads__posix64.o \ carla_engine__posix64.o carla_engine_jack__posix64.o carla_shared__posix64.o carla_threads__posix64.o \
ladspa__posix64.o dssi__posix64.o lv2__posix64.o vst__posix64.o ../carla-lilv/carla_lilv_posix64.a
ladspa__posix64.o dssi__posix64.o lv2__posix64.o vst__posix64.o \
../carla-lilv/carla_lilv_posix64.a ../carla-rtmempool/carla_rtmempool_posix64.a


carla-bridge-posix64: $(OBJS_POSIX64) carla-bridge-posix64: $(OBJS_POSIX64)
$(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_64BIT_FLAGS) -o $@ && $(STRIP) $@ $(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_64BIT_FLAGS) -o $@ && $(STRIP) $@
@@ -284,7 +296,8 @@ vst__posix64.o: ../carla-backend/vst.cpp
OBJS_WIN32 = \ OBJS_WIN32 = \
carla_bridge_plugin__win32.o carla_bridge_osc__win32.o \ carla_bridge_plugin__win32.o carla_bridge_osc__win32.o \
carla_engine__win32.o carla_engine_jack__win32.o carla_shared__win32.o carla_threads__win32.o \ carla_engine__win32.o carla_engine_jack__win32.o carla_shared__win32.o carla_threads__win32.o \
ladspa__win32.o dssi__win32.o lv2__win32.o vst__win32.o ../carla-lilv/carla_lilv_win32.a
ladspa__win32.o dssi__win32.o lv2__win32.o vst__win32.o \
../carla-lilv/carla_lilv_win32.a ../carla-rtmempool/carla_rtmempool_win32.a


carla-bridge-win32.exe: $(OBJS_WIN32) ../carla-jackbridge/libcarla-jackbridge-win32.dll carla-bridge-win32.exe: $(OBJS_WIN32) ../carla-jackbridge/libcarla-jackbridge-win32.dll
$(CXX) $(OBJS_WIN32) $(WIN_LINK_FLAGS) $(WIN_32BIT_FLAGS) -lcarla-jackbridge-win32 -o $@ && $(STRIP) $@ $(CXX) $(OBJS_WIN32) $(WIN_LINK_FLAGS) $(WIN_32BIT_FLAGS) -lcarla-jackbridge-win32 -o $@ && $(STRIP) $@
@@ -325,7 +338,8 @@ vst__win32.o: ../carla-backend/vst.cpp
OBJS_WIN64 = \ OBJS_WIN64 = \
carla_bridge_plugin__win64.o carla_bridge_osc__win64.o \ carla_bridge_plugin__win64.o carla_bridge_osc__win64.o \
carla_engine__win64.o carla_engine_jack__win64.o carla_shared__win64.o carla_threads__win64.o \ carla_engine__win64.o carla_engine_jack__win64.o carla_shared__win64.o carla_threads__win64.o \
ladspa__win64.o dssi__win64.o lv2__win64.o vst__win64.o ../carla-lilv/carla_lilv_win64.a
ladspa__win64.o dssi__win64.o lv2__win64.o vst__win64.o \
../carla-lilv/carla_lilv_win64.a ../carla-rtmempool/carla_rtmempool_win64.a


carla-bridge-win64.exe: $(OBJS_WIN64) ../carla-jackbridge/libcarla-jackbridge-win64.dll carla-bridge-win64.exe: $(OBJS_WIN64) ../carla-jackbridge/libcarla-jackbridge-win64.dll
$(CXX) $(OBJS_WIN64) $(WIN_LINK_FLAGS) $(WIN_64BIT_FLAGS) -lcarla-jackbridge-win64 -o $@ && $(STRIP) $@ $(CXX) $(OBJS_WIN64) $(WIN_LINK_FLAGS) $(WIN_64BIT_FLAGS) -lcarla-jackbridge-win64 -o $@ && $(STRIP) $@
@@ -362,6 +376,9 @@ vst__win64.o: ../carla-backend/vst.cpp


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


../carla-lilv/carla_lilv.a:
$(MAKE) -C ../carla-lilv

../carla-lilv/carla_lilv_posix32.a: ../carla-lilv/carla_lilv_posix32.a:
$(MAKE) -C ../carla-lilv posix32 $(MAKE) -C ../carla-lilv posix32


@@ -374,6 +391,21 @@ vst__win64.o: ../carla-backend/vst.cpp
../carla-lilv/carla_lilv_win64.a: ../carla-lilv/carla_lilv_win64.a:
$(MAKE) -C ../carla-lilv win64 $(MAKE) -C ../carla-lilv win64


../carla-rtmempool/carla_rtmempool.a:
$(MAKE) -C ../carla-rtmempool

../carla-rtmempool/carla_rtmempool_posix32.a:
$(MAKE) -C ../carla-rtmempool posix32

../carla-rtmempool/carla_rtmempool_posix64.a:
$(MAKE) -C ../carla-rtmempool posix64

../carla-rtmempool/carla_rtmempool_win32.a:
$(MAKE) -C ../carla-rtmempool win32

../carla-rtmempool/carla_rtmempool_win64.a:
$(MAKE) -C ../carla-rtmempool win64

../carla-jackbridge/libcarla-jackbridge-win32.dll: ../carla-jackbridge/libcarla-jackbridge-win32.dll:
$(MAKE) -C ../carla-jackbridge win32 $(MAKE) -C ../carla-jackbridge win32


@@ -386,6 +418,6 @@ doc: carla_bridge.doxygen
doxygen $< doxygen $<


clean: clean:
rm -f *.o *.so *.exe
rm -f *.o *.dll *.so *.exe
rm -f carla-bridge-lv2-gtk2 carla-bridge-lv2-gtk3 carla-bridge-lv2-qt4 carla-bridge-lv2-x11 carla-bridge-vst-x11 rm -f carla-bridge-lv2-gtk2 carla-bridge-lv2-gtk3 carla-bridge-lv2-qt4 carla-bridge-lv2-x11 carla-bridge-vst-x11
rm -f carla-bridge-posix32 carla-bridge-posix64 rm -f carla-bridge-posix32 carla-bridge-posix64

+ 6
- 6
c++/carla-bridge/carla_bridge_client.h View File

@@ -258,16 +258,16 @@ public:
#endif #endif


#ifdef BRIDGE_LV2 #ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const int32_t portIndex, const char* const atomBuf)
void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
qDebug("CarlaClient::sendOscLv2TransferAtom(%i, \"%s\")", portIndex, atomBuf);
m_osc.sendOscLv2TransferAtom(portIndex, atomBuf);
qDebug("CarlaClient::sendOscLv2TransferAtom(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
m_osc.sendOscLv2TransferAtom(portIndex, typeStr, atomBuf);
} }


void sendOscLv2TransferEvent(const int32_t portIndex, const char* const atomBuf)
void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
qDebug("CarlaClient::sendOscLv2TransferEvent(%i, \"%s\")", portIndex, atomBuf);
m_osc.sendOscLv2TransferEvent(portIndex, atomBuf);
qDebug("CarlaClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
m_osc.sendOscLv2TransferEvent(portIndex, typeStr, atomBuf);
} }
#endif #endif




+ 4
- 4
c++/carla-bridge/carla_bridge_osc.h View File

@@ -140,20 +140,20 @@ public:
#endif #endif


#ifdef BRIDGE_LV2 #ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const int32_t portIndex, const char* const atomBuf)
void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
Q_ASSERT(m_controlData.target); Q_ASSERT(m_controlData.target);


if (m_controlData.target) if (m_controlData.target)
osc_send_lv2_transfer_atom(&m_controlData, portIndex, atomBuf);
osc_send_lv2_transfer_atom(&m_controlData, portIndex, typeStr, atomBuf);
} }


void sendOscLv2TransferEvent(const int32_t portIndex, const char* const atomBuf)
void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
Q_ASSERT(m_controlData.target); Q_ASSERT(m_controlData.target);


if (m_controlData.target) if (m_controlData.target)
osc_send_lv2_transfer_event(&m_controlData, portIndex, atomBuf);
osc_send_lv2_transfer_event(&m_controlData, portIndex, typeStr, atomBuf);
} }
#endif #endif




+ 358
- 149
c++/carla-bridge/carla_bridge_ui-lv2.cpp View File

@@ -37,38 +37,71 @@ CARLA_BRIDGE_START_NAMESPACE
uint32_t bufferSize = 512; uint32_t bufferSize = 512;
double sampleRate = 44100.0; double sampleRate = 44100.0;


// static max values
const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000

// feature ids // feature ids
const uint32_t lv2_feature_id_event = 0;
const uint32_t lv2_feature_id_logs = 1;
const uint32_t lv2_feature_id_programs = 2;
const uint32_t lv2_feature_id_state_make_path = 3;
const uint32_t lv2_feature_id_state_map_path = 4;
const uint32_t lv2_feature_id_strict_bounds = 5;
const uint32_t lv2_feature_id_uri_map = 6;
const uint32_t lv2_feature_id_urid_map = 7;
const uint32_t lv2_feature_id_urid_unmap = 8;
const uint32_t lv2_feature_id_ui_parent = 9;
const uint32_t lv2_feature_id_ui_port_map = 10;
const uint32_t lv2_feature_id_ui_resize = 11;
const uint32_t lv2_feature_count = 12;
const uint32_t lv2_feature_id_bufsize_bounded = 0;
const uint32_t lv2_feature_id_bufsize_fixed = 1;
const uint32_t lv2_feature_id_bufsize_powerof2 = 2;
const uint32_t lv2_feature_id_event = 3;
const uint32_t lv2_feature_id_logs = 4;
const uint32_t lv2_feature_id_options = 5;
const uint32_t lv2_feature_id_programs = 6;
const uint32_t lv2_feature_id_rtmempool = 7;
const uint32_t lv2_feature_id_state_make_path = 8;
const uint32_t lv2_feature_id_state_map_path = 9;
const uint32_t lv2_feature_id_strict_bounds = 10;
const uint32_t lv2_feature_id_uri_map = 11;
const uint32_t lv2_feature_id_urid_map = 12;
const uint32_t lv2_feature_id_urid_unmap = 13;
const uint32_t lv2_feature_id_ui_parent = 14;
const uint32_t lv2_feature_id_ui_port_map = 15;
const uint32_t lv2_feature_id_ui_resize = 16;
const uint32_t lv2_feature_count = 17;


// pre-set uri[d] map ids // pre-set uri[d] map ids
const uint32_t CARLA_URI_MAP_ID_NULL = 0;
const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 1;
const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 2;
const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 3;
const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 4;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 5;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 6;
const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 7;
const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 8;
const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 9;
const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 10;
const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 11;
const uint32_t CARLA_URI_MAP_ID_COUNT = 12;
const uint32_t CARLA_URI_MAP_ID_NULL = 0;
const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 1;
const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 2;
const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 3;
const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 4;
const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 5;
const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 6;
const uint32_t CARLA_URI_MAP_ID_ATOM_WORKER = 7;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 8;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 9;
const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 10;
const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 11;
const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 12;
const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 13;
const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 14;
const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 15;
const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 16;
const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 17;
const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 18;
const uint32_t CARLA_URI_MAP_ID_COUNT = 19;


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


struct Lv2PluginOptions {
uint32_t eventSize;
uint32_t bufferSize;
double sampleRate;
LV2_Options_Option oNull;
LV2_Options_Option oMaxBlockLenth;
LV2_Options_Option oMinBlockLenth;
LV2_Options_Option oSequenceSize;
LV2_Options_Option oSampleRate;

Lv2PluginOptions()
: eventSize(MAX_EVENT_BUFFER),
bufferSize(0),
sampleRate(0.0) {}
};

Lv2PluginOptions lv2Options;

class CarlaLv2Client : public CarlaClient class CarlaLv2Client : public CarlaClient
{ {
public: public:
@@ -97,87 +130,148 @@ public:
for (uint32_t i=0; i < lv2_feature_count+1; i++) for (uint32_t i=0; i < lv2_feature_count+1; i++)
features[i] = nullptr; features[i] = nullptr;


// -----------------------------------------------------------------
// initialize options

lv2Options.bufferSize = bufferSize;
lv2Options.sampleRate = sampleRate;

lv2Options.oNull.key = CARLA_URI_MAP_ID_NULL;
lv2Options.oNull.size = 0;
lv2Options.oNull.type = CARLA_URI_MAP_ID_NULL;
lv2Options.oNull.value = nullptr;

lv2Options.oMaxBlockLenth.key = CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
lv2Options.oMaxBlockLenth.size = sizeof(uint32_t);
lv2Options.oMaxBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
lv2Options.oMaxBlockLenth.value = &lv2Options.bufferSize;

lv2Options.oMinBlockLenth.key = CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
lv2Options.oMinBlockLenth.size = sizeof(uint32_t);
lv2Options.oMinBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
lv2Options.oMinBlockLenth.value = &lv2Options.bufferSize;

lv2Options.oSequenceSize.key = CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
lv2Options.oSequenceSize.size = sizeof(uint32_t);
lv2Options.oSequenceSize.type = CARLA_URI_MAP_ID_ATOM_INT;
lv2Options.oSequenceSize.value = &lv2Options.eventSize;

lv2Options.oSampleRate.key = CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
lv2Options.oSampleRate.size = sizeof(double);
lv2Options.oSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE;
lv2Options.oSampleRate.value = &lv2Options.sampleRate;

// ----------------------------------------------------------------- // -----------------------------------------------------------------
// initialize features // initialize features


LV2_Event_Feature* Event_Feature = new LV2_Event_Feature;
Event_Feature->callback_data = this;
Event_Feature->lv2_event_ref = carla_lv2_event_ref;
Event_Feature->lv2_event_unref = carla_lv2_event_unref;
LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
eventFt->callback_data = this;
eventFt->lv2_event_ref = carla_lv2_event_ref;
eventFt->lv2_event_unref = carla_lv2_event_unref;

LV2_Log_Log* const logFt = new LV2_Log_Log;
logFt->handle = this;
logFt->printf = carla_lv2_log_printf;
logFt->vprintf = carla_lv2_log_vprintf;

LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
programsFt->handle = this;
programsFt->program_changed = carla_lv2_program_changed;

LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
rtmempool_allocator_init(rtMemPoolFt);

LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
stateMakePathFt->handle = this;
stateMakePathFt->path = carla_lv2_state_make_path;


LV2_Log_Log* Log_Feature = new LV2_Log_Log;
Log_Feature->handle = this;
Log_Feature->printf = carla_lv2_log_printf;
Log_Feature->vprintf = carla_lv2_log_vprintf;
LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
stateMapPathFt->handle = this;
stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path;
stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path;


LV2_Programs_Host* Programs_Feature = new LV2_Programs_Host;
Programs_Feature->handle = this;
Programs_Feature->program_changed = carla_lv2_program_changed;
LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
uriMapFt->callback_data = this;
uriMapFt->uri_to_id = carla_lv2_uri_to_id;


LV2_State_Make_Path* State_MakePath_Feature = new LV2_State_Make_Path;
State_MakePath_Feature->handle = this;
State_MakePath_Feature->path = carla_lv2_state_make_path;
LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
uridMapFt->handle = this;
uridMapFt->map = carla_lv2_urid_map;


LV2_State_Map_Path* State_MapPath_Feature = new LV2_State_Map_Path;
State_MapPath_Feature->handle = this;
State_MapPath_Feature->abstract_path = carla_lv2_state_map_abstract_path;
State_MapPath_Feature->absolute_path = carla_lv2_state_map_absolute_path;
LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
uridUnmapFt->handle = this;
uridUnmapFt->unmap = carla_lv2_urid_unmap;


LV2_URI_Map_Feature* URI_Map_Feature = new LV2_URI_Map_Feature;
URI_Map_Feature->callback_data = this;
URI_Map_Feature->uri_to_id = carla_lv2_uri_to_id;
LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
uiPortMapFt->handle = this;
uiPortMapFt->port_index = carla_lv2_ui_port_map;


LV2_URID_Map* URID_Map_Feature = new LV2_URID_Map;
URID_Map_Feature->handle = this;
URID_Map_Feature->map = carla_lv2_urid_map;
LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
uiResizeFt->handle = this;
uiResizeFt->ui_resize = carla_lv2_ui_resize;


LV2_URID_Unmap* URID_Unmap_Feature = new LV2_URID_Unmap;
URID_Unmap_Feature->handle = this;
URID_Unmap_Feature->unmap = carla_lv2_urid_unmap;
LV2_Options_Option* const optionsFt = new LV2_Options_Option [5];
optionsFt[0] = lv2Options.oMaxBlockLenth;
optionsFt[1] = lv2Options.oMinBlockLenth;
optionsFt[2] = lv2Options.oSequenceSize;
optionsFt[3] = lv2Options.oSampleRate;
optionsFt[4] = lv2Options.oNull;


LV2UI_Port_Map* UI_PortMap_Feature = new LV2UI_Port_Map;
UI_PortMap_Feature->handle = this;
UI_PortMap_Feature->port_index = carla_lv2_ui_port_map;
features[lv2_feature_id_bufsize_bounded] = new LV2_Feature;
features[lv2_feature_id_bufsize_bounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
features[lv2_feature_id_bufsize_bounded]->data = nullptr;


LV2UI_Resize* UI_Resize_Feature = new LV2UI_Resize;
UI_Resize_Feature->handle = this;
UI_Resize_Feature->ui_resize = carla_lv2_ui_resize;
features[lv2_feature_id_bufsize_fixed] = new LV2_Feature;
features[lv2_feature_id_bufsize_fixed]->URI = LV2_BUF_SIZE__fixedBlockLength;
features[lv2_feature_id_bufsize_fixed]->data = nullptr;


features[lv2_feature_id_event] = new LV2_Feature;
features[lv2_feature_id_event]->URI = LV2_EVENT_URI;
features[lv2_feature_id_event]->data = Event_Feature;
features[lv2_feature_id_bufsize_powerof2] = new LV2_Feature;
features[lv2_feature_id_bufsize_powerof2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
features[lv2_feature_id_bufsize_powerof2]->data = nullptr;


features[lv2_feature_id_logs] = new LV2_Feature;
features[lv2_feature_id_logs]->URI = LV2_LOG__log;
features[lv2_feature_id_logs]->data = Log_Feature;
features[lv2_feature_id_event] = new LV2_Feature;
features[lv2_feature_id_event]->URI = LV2_EVENT_URI;
features[lv2_feature_id_event]->data = eventFt;


features[lv2_feature_id_programs] = new LV2_Feature;
features[lv2_feature_id_programs]->URI = LV2_PROGRAMS__Host;
features[lv2_feature_id_programs]->data = Programs_Feature;
features[lv2_feature_id_logs] = new LV2_Feature;
features[lv2_feature_id_logs]->URI = LV2_LOG__log;
features[lv2_feature_id_logs]->data = logFt;


features[lv2_feature_id_state_make_path] = new LV2_Feature;
features[lv2_feature_id_options] = new LV2_Feature;
features[lv2_feature_id_options]->URI = LV2_OPTIONS__options;
features[lv2_feature_id_options]->data = optionsFt;

features[lv2_feature_id_programs] = new LV2_Feature;
features[lv2_feature_id_programs]->URI = LV2_PROGRAMS__Host;
features[lv2_feature_id_programs]->data = programsFt;

features[lv2_feature_id_rtmempool] = new LV2_Feature;
features[lv2_feature_id_rtmempool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
features[lv2_feature_id_rtmempool]->data = rtMemPoolFt;

features[lv2_feature_id_state_make_path] = new LV2_Feature;
features[lv2_feature_id_state_make_path]->URI = LV2_STATE__makePath; features[lv2_feature_id_state_make_path]->URI = LV2_STATE__makePath;
features[lv2_feature_id_state_make_path]->data = State_MakePath_Feature;
features[lv2_feature_id_state_make_path]->data = stateMakePathFt;


features[lv2_feature_id_state_map_path] = new LV2_Feature;
features[lv2_feature_id_state_map_path]->URI = LV2_STATE__mapPath;
features[lv2_feature_id_state_map_path]->data = State_MapPath_Feature;
features[lv2_feature_id_state_map_path] = new LV2_Feature;
features[lv2_feature_id_state_map_path]->URI = LV2_STATE__mapPath;
features[lv2_feature_id_state_map_path]->data = stateMapPathFt;


features[lv2_feature_id_strict_bounds] = new LV2_Feature;
features[lv2_feature_id_strict_bounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
features[lv2_feature_id_strict_bounds]->data = nullptr;
features[lv2_feature_id_strict_bounds] = new LV2_Feature;
features[lv2_feature_id_strict_bounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
features[lv2_feature_id_strict_bounds]->data = nullptr;


features[lv2_feature_id_uri_map] = new LV2_Feature;
features[lv2_feature_id_uri_map]->URI = LV2_URI_MAP_URI;
features[lv2_feature_id_uri_map]->data = URI_Map_Feature;
features[lv2_feature_id_uri_map] = new LV2_Feature;
features[lv2_feature_id_uri_map]->URI = LV2_URI_MAP_URI;
features[lv2_feature_id_uri_map]->data = uriMapFt;


features[lv2_feature_id_urid_map] = new LV2_Feature;
features[lv2_feature_id_urid_map]->URI = LV2_URID__map;
features[lv2_feature_id_urid_map]->data = URID_Map_Feature;
features[lv2_feature_id_urid_map] = new LV2_Feature;
features[lv2_feature_id_urid_map]->URI = LV2_URID__map;
features[lv2_feature_id_urid_map]->data = uridMapFt;


features[lv2_feature_id_urid_unmap] = new LV2_Feature;
features[lv2_feature_id_urid_unmap]->URI = LV2_URID__unmap;
features[lv2_feature_id_urid_unmap]->data = URID_Unmap_Feature;
features[lv2_feature_id_urid_unmap] = new LV2_Feature;
features[lv2_feature_id_urid_unmap]->URI = LV2_URID__unmap;
features[lv2_feature_id_urid_unmap]->data = uridUnmapFt;


features[lv2_feature_id_ui_parent] = new LV2_Feature; features[lv2_feature_id_ui_parent] = new LV2_Feature;
features[lv2_feature_id_ui_parent]->URI = LV2_UI__parent; features[lv2_feature_id_ui_parent]->URI = LV2_UI__parent;
@@ -187,13 +281,13 @@ public:
features[lv2_feature_id_ui_parent]->data = nullptr; features[lv2_feature_id_ui_parent]->data = nullptr;
#endif #endif


features[lv2_feature_id_ui_port_map] = new LV2_Feature;
features[lv2_feature_id_ui_port_map]->URI = LV2_UI__portMap;
features[lv2_feature_id_ui_port_map]->data = UI_PortMap_Feature;
features[lv2_feature_id_ui_port_map] = new LV2_Feature;
features[lv2_feature_id_ui_port_map]->URI = LV2_UI__portMap;
features[lv2_feature_id_ui_port_map]->data = uiPortMapFt;


features[lv2_feature_id_ui_resize] = new LV2_Feature;
features[lv2_feature_id_ui_resize]->URI = LV2_UI__resize;
features[lv2_feature_id_ui_resize]->data = UI_Resize_Feature;
features[lv2_feature_id_ui_resize] = new LV2_Feature;
features[lv2_feature_id_ui_resize]->URI = LV2_UI__resize;
features[lv2_feature_id_ui_resize]->data = uiResizeFt;
} }


~CarlaLv2Client() ~CarlaLv2Client()
@@ -201,9 +295,13 @@ public:
if (rdf_descriptor) if (rdf_descriptor)
lv2_rdf_free(rdf_descriptor); lv2_rdf_free(rdf_descriptor);


const LV2_Options_Option* const options = (const LV2_Options_Option*)features[lv2_feature_id_options]->data;
delete[] options;

delete (LV2_Event_Feature*)features[lv2_feature_id_event]->data; delete (LV2_Event_Feature*)features[lv2_feature_id_event]->data;
delete (LV2_Log_Log*)features[lv2_feature_id_logs]->data; delete (LV2_Log_Log*)features[lv2_feature_id_logs]->data;
delete (LV2_Programs_Host*)features[lv2_feature_id_programs]->data; delete (LV2_Programs_Host*)features[lv2_feature_id_programs]->data;
delete (LV2_RtMemPool_Pool*)features[lv2_feature_id_rtmempool]->data;
delete (LV2_State_Make_Path*)features[lv2_feature_id_state_make_path]->data; delete (LV2_State_Make_Path*)features[lv2_feature_id_state_make_path]->data;
delete (LV2_State_Map_Path*)features[lv2_feature_id_state_map_path]->data; delete (LV2_State_Map_Path*)features[lv2_feature_id_state_map_path]->data;
delete (LV2_URI_Map_Feature*)features[lv2_feature_id_uri_map]->data; delete (LV2_URI_Map_Feature*)features[lv2_feature_id_uri_map]->data;
@@ -230,13 +328,13 @@ public:
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// ui initialization // ui initialization


bool init(const char* plugin_uri, const char* ui_uri)
bool init(const char* pluginURI, const char* uiURI)
{ {
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// get plugin from lv2_rdf (lilv) // get plugin from lv2_rdf (lilv)


Lv2World.init(); Lv2World.init();
rdf_descriptor = lv2_rdf_new(plugin_uri);
rdf_descriptor = lv2_rdf_new(pluginURI);


if (! rdf_descriptor) if (! rdf_descriptor)
return false; return false;
@@ -246,7 +344,7 @@ public:


for (uint32_t i=0; i < rdf_descriptor->UICount; i++) for (uint32_t i=0; i < rdf_descriptor->UICount; i++)
{ {
if (strcmp(rdf_descriptor->UIs[i].URI, ui_uri) == 0)
if (strcmp(rdf_descriptor->UIs[i].URI, uiURI) == 0)
{ {
rdf_ui_descriptor = &rdf_descriptor->UIs[i]; rdf_ui_descriptor = &rdf_descriptor->UIs[i];
break; break;
@@ -265,18 +363,18 @@ public:
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// get DLL main entry // get DLL main entry


LV2UI_DescriptorFunction const ui_descfn = (LV2UI_DescriptorFunction)libSymbol("lv2ui_descriptor");
const LV2UI_DescriptorFunction ui_descFn = (LV2UI_DescriptorFunction)libSymbol("lv2ui_descriptor");


if (! ui_descfn)
if (! ui_descFn)
return false; return false;


// ----------------------------------------------------------- // -----------------------------------------------------------
// get descriptor that matches URI // get descriptor that matches URI


uint32_t i = 0; uint32_t i = 0;
while ((descriptor = ui_descfn(i++)))
while ((descriptor = ui_descFn(i++)))
{ {
if (strcmp(descriptor->URI, ui_uri) == 0)
if (strcmp(descriptor->URI, uiURI) == 0)
break; break;
} }


@@ -286,7 +384,7 @@ public:
// ----------------------------------------------------------- // -----------------------------------------------------------
// initialize UI // initialize UI


handle = descriptor->instantiate(descriptor, plugin_uri, rdf_ui_descriptor->Bundle, carla_lv2_ui_write_function, this, &widget, features);
handle = descriptor->instantiate(descriptor, pluginURI, rdf_ui_descriptor->Bundle, carla_lv2_ui_write_function, this, &widget, features);


if (! handle) if (! handle)
return false; return false;
@@ -313,6 +411,11 @@ public:
if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0) if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
{ {
programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface); programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);

if (programs && ! programs->select_program)
// invalid
programs = nullptr;

break; break;
} }
} }
@@ -386,8 +489,15 @@ public:


if (handle && descriptor && descriptor->port_event) if (handle && descriptor && descriptor->port_event)
{ {
uint8_t buf[3] = { uint8_t(0x90 + channel), note, velo };
descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_MIDI_EVENT, buf);
LV2_Atom_MidiEvent midiEv;
midiEv.event.time.frames = 0;
midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
midiEv.event.body.size = 3;
midiEv.data[0] = MIDI_STATUS_NOTE_ON + channel;
midiEv.data[1] = note;
midiEv.data[2] = velo;

descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
} }
} }


@@ -397,8 +507,15 @@ public:


if (handle && descriptor && descriptor->port_event) if (handle && descriptor && descriptor->port_event)
{ {
uint8_t buf[3] = { uint8_t(0x80 + channel), note, 0 };
descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_MIDI_EVENT, buf);
LV2_Atom_MidiEvent midiEv;
midiEv.event.time.frames = 0;
midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
midiEv.event.body.size = 3;
midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
midiEv.data[1] = note;
midiEv.data[2] = 0;

descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
} }
} }


@@ -409,6 +526,9 @@ public:
qDebug("CarlaLv2Client::getCustomURID(%s)", uri); qDebug("CarlaLv2Client::getCustomURID(%s)", uri);
Q_ASSERT(uri); Q_ASSERT(uri);


if (! uri)
return CARLA_URI_MAP_ID_NULL;

for (size_t i=0; i < customURIDs.size(); i++) for (size_t i=0; i < customURIDs.size(); i++)
{ {
if (customURIDs[i] && strcmp(customURIDs[i], uri) == 0) if (customURIDs[i] && strcmp(customURIDs[i], uri) == 0)
@@ -416,33 +536,43 @@ public:
} }


customURIDs.push_back(strdup(uri)); customURIDs.push_back(strdup(uri));

return customURIDs.size()-1; return customURIDs.size()-1;
} }


const char* getCustomURIString(LV2_URID urid)
const char* getCustomURIString(const LV2_URID urid) const
{ {
qDebug("CarlaLv2Client::getCustomURIString(%i)", urid); qDebug("CarlaLv2Client::getCustomURIString(%i)", urid);
Q_ASSERT(urid != 0);
Q_ASSERT(urid > CARLA_URI_MAP_ID_NULL);


if (urid == CARLA_URI_MAP_ID_NULL)
return nullptr;
if (urid < customURIDs.size()) if (urid < customURIDs.size())
return customURIDs[urid]; return customURIDs[urid];


return nullptr; return nullptr;
} }


void handleTransferAtom(const int32_t portIndex, const char* const atomBuf)
// ---------------------------------------------------------------------

void handleTransferAtom(const int32_t portIndex, const LV2_Atom* const atom)
{ {
qDebug("CarlaLv2Client::handleTransferEvent(%i, \"%s\")", portIndex, atomBuf);
qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
Q_ASSERT(portIndex >= 0); Q_ASSERT(portIndex >= 0);
Q_ASSERT(atomBuf);
Q_ASSERT(atom);

if (handle && descriptor && descriptor->port_event)
descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom);
} }


void handleTransferEvent(const int32_t portIndex, const char* const atomBuf)
void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom)
{ {
qDebug("CarlaLv2Client::handleTransferEvent(%i, \"%s\")", portIndex, atomBuf);
qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
Q_ASSERT(portIndex >= 0); Q_ASSERT(portIndex >= 0);
Q_ASSERT(atomBuf);
Q_ASSERT(atom);


if (handle && descriptor && descriptor->port_event)
descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
#if 0 #if 0
if (handle && descriptor && descriptor->port_event) if (handle && descriptor && descriptor->port_event)
{ {
@@ -486,6 +616,8 @@ public:
#endif #endif
} }


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

void handleProgramChanged(int32_t /*index*/) void handleProgramChanged(int32_t /*index*/)
{ {
sendOscConfigure("reloadprograms", ""); sendOscConfigure("reloadprograms", "");
@@ -495,6 +627,9 @@ public:
{ {
Q_ASSERT(symbol); Q_ASSERT(symbol);


if (! symbol)
return LV2UI_INVALID_PORT_INDEX;

for (uint32_t i=0; i < rdf_descriptor->PortCount; i++) for (uint32_t i=0; i < rdf_descriptor->PortCount; i++)
{ {
if (strcmp(rdf_descriptor->Ports[i].Symbol, symbol) == 0) if (strcmp(rdf_descriptor->Ports[i].Symbol, symbol) == 0)
@@ -510,6 +645,9 @@ public:
Q_ASSERT(width > 0); Q_ASSERT(width > 0);
Q_ASSERT(height > 0); Q_ASSERT(height > 0);


if (width <= 0 || height <= 0)
return 1;

quequeMessage(MESSAGE_RESIZE_GUI, width, height, 0.0); quequeMessage(MESSAGE_RESIZE_GUI, width, height, 0.0);


return 0; return 0;
@@ -520,40 +658,36 @@ public:
{ {
if (format == 0) if (format == 0)
{ {
Q_ASSERT(buffer);
Q_ASSERT(bufferSize == sizeof(float)); Q_ASSERT(bufferSize == sizeof(float));


if (bufferSize == sizeof(float))
{
float value = *(float*)buffer;
sendOscControl(portIndex, value);
}
if (bufferSize != sizeof(float))
return;
float value = *(float*)buffer;
sendOscControl(portIndex, value);
} }
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM) else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
{ {
//const LV2_Atom* const atom = (const LV2_Atom*)buffer;
Q_ASSERT(buffer);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;


QByteArray chunk((const char*)buffer, bufferSize); QByteArray chunk((const char*)buffer, bufferSize);
sendOscLv2TransferAtom(portIndex, chunk.toBase64().constData());

//if (descriptor && descriptor->port_event)
// descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom);
sendOscLv2TransferAtom(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
} }
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
{ {
//const LV2_Atom* const atom = (const LV2_Atom*)buffer;
Q_ASSERT(buffer);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;


QByteArray chunk((const char*)buffer, bufferSize); QByteArray chunk((const char*)buffer, bufferSize);
sendOscLv2TransferEvent(portIndex, chunk.toBase64().constData());

//if (descriptor && descriptor->port_event)
// descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);

sendOscLv2TransferEvent(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
} }
} }


// ----------------- Event Feature --------------------------------------------------- // ----------------- Event Feature ---------------------------------------------------


static uint32_t carla_lv2_event_ref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
static uint32_t carla_lv2_event_ref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
{ {
qDebug("CarlaLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event); qDebug("CarlaLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event);
Q_ASSERT(callback_data); Q_ASSERT(callback_data);
@@ -562,7 +696,7 @@ public:
return 0; return 0;
} }


static uint32_t carla_lv2_event_unref(LV2_Event_Callback_Data callback_data, LV2_Event* event)
static uint32_t carla_lv2_event_unref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
{ {
qDebug("CarlaLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event); qDebug("CarlaLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event);
Q_ASSERT(callback_data); Q_ASSERT(callback_data);
@@ -573,7 +707,7 @@ public:


// ----------------- Logs Feature ---------------------------------------------------- // ----------------- Logs Feature ----------------------------------------------------


static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
static int carla_lv2_log_printf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, ...)
{ {
qDebug("CarlaLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt); qDebug("CarlaLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt);
Q_ASSERT(handle); Q_ASSERT(handle);
@@ -592,7 +726,7 @@ public:
return ret; return ret;
} }


static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
static int carla_lv2_log_vprintf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, va_list ap)
{ {
qDebug("CarlaLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt); qDebug("CarlaLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt);
Q_ASSERT(handle); Q_ASSERT(handle);
@@ -632,67 +766,86 @@ public:


// ----------------- Programs Feature ------------------------------------------------ // ----------------- Programs Feature ------------------------------------------------


static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
static void carla_lv2_program_changed(const LV2_Programs_Handle handle, const int32_t index)
{ {
qDebug("CarlaLv2Client::carla_lv2_program_changed(%p, %i)", handle, index); qDebug("CarlaLv2Client::carla_lv2_program_changed(%p, %i)", handle, index);
Q_ASSERT(handle); Q_ASSERT(handle);


if (! handle)
return;

CarlaLv2Client* const client = (CarlaLv2Client*)handle; CarlaLv2Client* const client = (CarlaLv2Client*)handle;
client->handleProgramChanged(index); client->handleProgramChanged(index);
} }


// ----------------- State Feature --------------------------------------------------- // ----------------- State Feature ---------------------------------------------------


static char* carla_lv2_state_make_path(LV2_State_Make_Path_Handle handle, const char* path)
static char* carla_lv2_state_make_path(const LV2_State_Make_Path_Handle handle, const char* const path)
{ {
qDebug("CarlaLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path); qDebug("CarlaLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path);
Q_ASSERT(handle); Q_ASSERT(handle);
Q_ASSERT(path); Q_ASSERT(path);


if (! path)
return nullptr;

QDir dir; QDir dir;
dir.mkpath(path); dir.mkpath(path);
return strdup(path); return strdup(path);
} }


static char* carla_lv2_state_map_abstract_path(LV2_State_Map_Path_Handle handle, const char* absolute_path)
static char* carla_lv2_state_map_abstract_path(const LV2_State_Map_Path_Handle handle, const char* const absolute_path)
{ {
qDebug("CarlaLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path); qDebug("CarlaLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path);
Q_ASSERT(handle); Q_ASSERT(handle);
Q_ASSERT(absolute_path); Q_ASSERT(absolute_path);


if (! absolute_path)
return nullptr;

QDir dir(absolute_path); QDir dir(absolute_path);
return strdup(dir.canonicalPath().toUtf8().constData()); return strdup(dir.canonicalPath().toUtf8().constData());
} }


static char* carla_lv2_state_map_absolute_path(LV2_State_Map_Path_Handle handle, const char* abstract_path)
static char* carla_lv2_state_map_absolute_path(const LV2_State_Map_Path_Handle handle, const char* const abstract_path)
{ {
qDebug("CarlaLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path); qDebug("CarlaLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path);
Q_ASSERT(handle); Q_ASSERT(handle);
Q_ASSERT(abstract_path); Q_ASSERT(abstract_path);


if (! abstract_path)
return nullptr;

QDir dir(abstract_path); QDir dir(abstract_path);
return strdup(dir.absolutePath().toUtf8().constData()); return strdup(dir.absolutePath().toUtf8().constData());
} }


// ----------------- URI-Map Feature --------------------------------------- // ----------------- URI-Map Feature ---------------------------------------


static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
static uint32_t carla_lv2_uri_to_id(const LV2_URI_Map_Callback_Data data, const char* const map, const char* const uri)
{ {
qDebug("CarlaLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri); qDebug("CarlaLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri);
return carla_lv2_urid_map(data, uri);
return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
} }


// ----------------- URID Feature ------------------------------------------ // ----------------- URID Feature ------------------------------------------


static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
static LV2_URID carla_lv2_urid_map(const LV2_URID_Map_Handle handle, const char* const uri)
{ {
qDebug("CarlaLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri); qDebug("CarlaLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri);
Q_ASSERT(handle); Q_ASSERT(handle);
Q_ASSERT(uri); Q_ASSERT(uri);


if (! uri)
return CARLA_URI_MAP_ID_NULL;

// Atom types // Atom types
if (strcmp(uri, LV2_ATOM__Chunk) == 0) if (strcmp(uri, LV2_ATOM__Chunk) == 0)
return CARLA_URI_MAP_ID_ATOM_CHUNK; return CARLA_URI_MAP_ID_ATOM_CHUNK;
if (strcmp(uri, LV2_ATOM__Double) == 0)
return CARLA_URI_MAP_ID_ATOM_DOUBLE;
if (strcmp(uri, LV2_ATOM__Int) == 0)
return CARLA_URI_MAP_ID_ATOM_INT;
if (strcmp(uri, LV2_ATOM__Path) == 0) if (strcmp(uri, LV2_ATOM__Path) == 0)
return CARLA_URI_MAP_ID_ATOM_PATH; return CARLA_URI_MAP_ID_ATOM_PATH;
if (strcmp(uri, LV2_ATOM__Sequence) == 0) if (strcmp(uri, LV2_ATOM__Sequence) == 0)
@@ -704,6 +857,14 @@ public:
if (strcmp(uri, LV2_ATOM__eventTransfer) == 0) if (strcmp(uri, LV2_ATOM__eventTransfer) == 0)
return CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT; return CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT;


// BufSize types
if (strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
return CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
if (strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
return CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
if (strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
return CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;

// Log types // Log types
if (strcmp(uri, LV2_LOG__Error) == 0) if (strcmp(uri, LV2_LOG__Error) == 0)
return CARLA_URI_MAP_ID_LOG_ERROR; return CARLA_URI_MAP_ID_LOG_ERROR;
@@ -717,21 +878,33 @@ public:
// Others // Others
if (strcmp(uri, LV2_MIDI__MidiEvent) == 0) if (strcmp(uri, LV2_MIDI__MidiEvent) == 0)
return CARLA_URI_MAP_ID_MIDI_EVENT; return CARLA_URI_MAP_ID_MIDI_EVENT;
if (strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
return CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;

if (! handle)
return CARLA_URI_MAP_ID_NULL;


// Custom types // Custom types
CarlaLv2Client* const client = (CarlaLv2Client*)handle; CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->getCustomURID(uri); return client->getCustomURID(uri);
} }


static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
static const char* carla_lv2_urid_unmap(const LV2_URID_Map_Handle handle, const LV2_URID urid)
{ {
qDebug("CarlaLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid); qDebug("CarlaLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid);
Q_ASSERT(handle); Q_ASSERT(handle);
Q_ASSERT(urid > 0);
Q_ASSERT(urid > CARLA_URI_MAP_ID_NULL);

if (urid == CARLA_URI_MAP_ID_NULL)
return nullptr;


// Atom types // Atom types
if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK) if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK)
return LV2_ATOM__Chunk; return LV2_ATOM__Chunk;
if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
return LV2_ATOM__Double;
if (urid == CARLA_URI_MAP_ID_ATOM_INT)
return LV2_ATOM__Int;
if (urid == CARLA_URI_MAP_ID_ATOM_PATH) if (urid == CARLA_URI_MAP_ID_ATOM_PATH)
return LV2_ATOM__Path; return LV2_ATOM__Path;
if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE) if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE)
@@ -743,6 +916,14 @@ public:
if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
return LV2_ATOM__eventTransfer; return LV2_ATOM__eventTransfer;


// BufSize types
if (urid == CARLA_URI_MAP_ID_BUF_MAX_LENGTH)
return LV2_BUF_SIZE__maxBlockLength;
if (urid == CARLA_URI_MAP_ID_BUF_MIN_LENGTH)
return LV2_BUF_SIZE__minBlockLength;
if (urid == CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE)
return LV2_BUF_SIZE__sequenceSize;

// Log types // Log types
if (urid == CARLA_URI_MAP_ID_LOG_ERROR) if (urid == CARLA_URI_MAP_ID_LOG_ERROR)
return LV2_LOG__Error; return LV2_LOG__Error;
@@ -756,6 +937,11 @@ public:
// Others // Others
if (urid == CARLA_URI_MAP_ID_MIDI_EVENT) if (urid == CARLA_URI_MAP_ID_MIDI_EVENT)
return LV2_MIDI__MidiEvent; return LV2_MIDI__MidiEvent;
if (urid == CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE)
return LV2_PARAMETERS__sampleRate;

if (! handle)
return nullptr;


// Custom types // Custom types
CarlaLv2Client* const client = (CarlaLv2Client*)handle; CarlaLv2Client* const client = (CarlaLv2Client*)handle;
@@ -764,11 +950,14 @@ public:


// ----------------- UI Port-Map Feature --------------------------------------------- // ----------------- UI Port-Map Feature ---------------------------------------------


static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
static uint32_t carla_lv2_ui_port_map(const LV2UI_Feature_Handle handle, const char* const symbol)
{ {
qDebug("CarlaLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol); qDebug("CarlaLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol);
Q_ASSERT(handle); Q_ASSERT(handle);


if (! handle)
return LV2UI_INVALID_PORT_INDEX;

CarlaLv2Client* const client = (CarlaLv2Client*)handle; CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->handleUiPortMap(symbol); return client->handleUiPortMap(symbol);
} }
@@ -776,22 +965,28 @@ public:


// ----------------- UI Resize Feature ------------------------------------- // ----------------- UI Resize Feature -------------------------------------


static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
static int carla_lv2_ui_resize(const LV2UI_Feature_Handle handle, const int width, const int height)
{ {
qDebug("CarlaLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height); qDebug("CarlaLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
Q_ASSERT(handle); Q_ASSERT(handle);


if (! handle)
return 1;

CarlaLv2Client* const client = (CarlaLv2Client*)handle; CarlaLv2Client* const client = (CarlaLv2Client*)handle;
return client->handleUiResize(width, height); return client->handleUiResize(width, height);
} }


// ----------------- UI Extension ------------------------------------------ // ----------------- UI Extension ------------------------------------------


static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
static void carla_lv2_ui_write_function(const LV2UI_Controller controller, const uint32_t port_index, const uint32_t buffer_size, const uint32_t format, const void* const buffer)
{ {
qDebug("CarlaLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer); qDebug("CarlaLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
Q_ASSERT(controller); Q_ASSERT(controller);


if (! controller)
return;

CarlaLv2Client* const client = (CarlaLv2Client*)controller; CarlaLv2Client* const client = (CarlaLv2Client*)controller;
client->handleUiWrite(port_index, buffer_size, format, buffer); client->handleUiWrite(port_index, buffer_size, format, buffer);
} }
@@ -818,16 +1013,23 @@ private:
int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS) int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{ {
qDebug("CarlaBridgeOsc::handleMsgLv2TransferAtom()"); qDebug("CarlaBridgeOsc::handleMsgLv2TransferAtom()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "is");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");


if (! client) if (! client)
return 1; return 1;


const int32_t portIndex = argv[0]->i; const int32_t portIndex = argv[0]->i;
const char* const atomBuf = (const char*)&argv[1]->s;
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.constData();
CarlaLv2Client* const lv2client = (CarlaLv2Client*)client; CarlaLv2Client* const lv2client = (CarlaLv2Client*)client;
lv2client->handleTransferAtom(portIndex, atomBuf);

atom->type = lv2client->getCustomURID(typeStr);
lv2client->handleTransferAtom(portIndex, atom);


return 0; return 0;
} }
@@ -835,16 +1037,23 @@ int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS) int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{ {
qDebug("CarlaBridgeOsc::handleMsgLv2TransferEvent()"); qDebug("CarlaBridgeOsc::handleMsgLv2TransferEvent()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "is");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");


if (! client) if (! client)
return 1; return 1;


const int32_t portIndex = argv[0]->i; const int32_t portIndex = argv[0]->i;
const char* const atomBuf = (const char*)&argv[1]->s;
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.constData();
CarlaLv2Client* const lv2client = (CarlaLv2Client*)client; CarlaLv2Client* const lv2client = (CarlaLv2Client*)client;
lv2client->handleTransferEvent(portIndex, atomBuf);

atom->type = lv2client->getCustomURID(typeStr);
lv2client->handleTransferEvent(portIndex, atom);


return 0; return 0;
} }


+ 15
- 0
c++/carla-includes/carla_lv2.h View File

@@ -77,6 +77,21 @@


#define LV2_UI__makeResident LV2_UI_PREFIX "makeResident" #define LV2_UI__makeResident LV2_UI_PREFIX "makeResident"


struct LV2_Atom_MidiEvent {
LV2_Atom_Event event;
uint8_t data[3];
};

struct LV2_Atom_Worker_Body {
uint32_t size;
const void* data;
};

struct LV2_Atom_Worker {
LV2_Atom atom;
LV2_Atom_Worker_Body body;
};

class Lv2WorldClass : public Lilv::World class Lv2WorldClass : public Lilv::World
{ {
public: public:


+ 8
- 6
c++/carla-includes/carla_osc_includes.h View File

@@ -282,36 +282,38 @@ void osc_send_bridge_update(const CarlaOscData* const oscData, const char* const
#endif #endif


static inline static inline
void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const int32_t portIndex, const char* const atomBuf)
void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
Q_ASSERT(oscData && oscData->path); Q_ASSERT(oscData && oscData->path);
Q_ASSERT(portIndex >= 0); Q_ASSERT(portIndex >= 0);
Q_ASSERT(typeStr);
Q_ASSERT(atomBuf); Q_ASSERT(atomBuf);
qDebug("osc_send_lv2_transfer_atom(path:\"%s\", %i, \"%s\")", oscData->path, portIndex, atomBuf);
qDebug("osc_send_lv2_transfer_atom(path:\"%s\", %i, \"%s\", \"%s\")", oscData->path, portIndex, typeStr, atomBuf);


if (oscData->target) if (oscData->target)
{ {
char targetPath[strlen(oscData->path)+19]; char targetPath[strlen(oscData->path)+19];
strcpy(targetPath, oscData->path); strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_atom_transfer"); strcat(targetPath, "/lv2_atom_transfer");
lo_send(oscData->target, targetPath, "is", portIndex, atomBuf);
lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf);
} }
} }


static inline static inline
void osc_send_lv2_transfer_event(const CarlaOscData* const oscData, const int32_t portIndex, const char* const atomBuf)
void osc_send_lv2_transfer_event(const CarlaOscData* const oscData, const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
{ {
Q_ASSERT(oscData && oscData->path); Q_ASSERT(oscData && oscData->path);
Q_ASSERT(portIndex >= 0); Q_ASSERT(portIndex >= 0);
Q_ASSERT(typeStr);
Q_ASSERT(atomBuf); Q_ASSERT(atomBuf);
qDebug("osc_send_lv2_transfer_event(path:\"%s\", %i, \"%s\")", oscData->path, portIndex, atomBuf);
qDebug("osc_send_lv2_transfer_event(path:\"%s\", %i, \"%s\", \"%s\")", oscData->path, portIndex, typeStr, atomBuf);


if (oscData->target) if (oscData->target)
{ {
char targetPath[strlen(oscData->path)+20]; char targetPath[strlen(oscData->path)+20];
strcpy(targetPath, oscData->path); strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_event_transfer"); strcat(targetPath, "/lv2_event_transfer");
lo_send(oscData->target, targetPath, "is", portIndex, atomBuf);
lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf);
} }
} }




Loading…
Cancel
Save