Browse Source

Carla: More work for lv2 atom messages support

tags/v0.9.0
falkTX 12 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

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 += $(shell pkg-config --cflags liblo QtCore QtGui)
@@ -68,9 +68,9 @@ OBJS = \
carla_shared.o \
carla_threads.o \
ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \
rtmempool/rtmempool.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)
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:
$(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@
@@ -99,5 +99,8 @@ carla_backend.so: $(OBJS)
../carla-lilv/carla_lilv.a:
$(MAKE) -C ../carla-lilv

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

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

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

@@ -68,9 +68,9 @@ OBJS = \
carla_shared.o \
carla_threads.o \
ladspa.o dssi.o lv2.o vst.o fluidsynth.o linuxsampler.o \
rtmempool/rtmempool.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)
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:
$(CXX) -c $< $(CARLA_CXX_FLAGS) -o $@
@@ -99,5 +99,8 @@ carla_backend.so: $(OBJS)
../carla-lilv/carla_lilv.a:
$(MAKE) -C ../carla-lilv

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

clean:
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_lv2.h"

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

#include <QtCore/QDir>
@@ -66,7 +68,6 @@ const unsigned int PARAMETER_IS_TRIGGER = 0x2000; //!< LV2 Parameter is tr
* @defgroup Lv2FeatureIds LV2 Feature Ids
*
* Static index list of the internal LV2 Feature Ids.
* \see CarlaPlugin::hints
* @{
*/
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
*
* Data and buffer types for LV2 EventData ports.
* \see CarlaPlugin::hints
* @{
*/
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
*
* Static index list of the internal LV2 URI Map Ids.
* \see CarlaPlugin::hints
* @{
*/
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;
/**@}*/

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 {
uint32_t type;
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);
}

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
{
public:
@@ -1030,7 +852,7 @@ public:
cdata.type = type;
cdata.key = key;
cdata.value = value;
uiTransferEvent(&cdata);
uiTransferCustomData(&cdata);
}
}

@@ -1224,7 +1046,7 @@ public:
if (gui.type == GUI_EXTERNAL_OSC)
{
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
#endif
@@ -2940,7 +2762,18 @@ public:
else
#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
#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);

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

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

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

float value = *(float*)buffer;

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;

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->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;
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;
@@ -4614,19 +4457,20 @@ CarlaPlugin* CarlaPlugin::newLV2(const initializer& init)
int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2)
{
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;
}
@@ -4634,18 +4478,20 @@ int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2)
int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2)
{
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;
}


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

@@ -91,7 +91,9 @@ win64: carla-bridge-win64.exe
# --------------------------------------------------------------
# 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)
$(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

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)
$(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

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)
$(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

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)
$(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

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)
$(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

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)
$(CXX) $^ $(LINK_UI_VST_X11_FLAGS) -o $@ && $(STRIP) $@
@@ -196,7 +206,8 @@ carla_bridge_osc__vst-x11.o: carla_bridge_osc.cpp
OBJS_POSIX32 = \
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 \
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)
$(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_32BIT_FLAGS) -o $@ && $(STRIP) $@
@@ -240,7 +251,8 @@ vst__posix32.o: ../carla-backend/vst.cpp
OBJS_POSIX64 = \
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 \
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)
$(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_64BIT_FLAGS) -o $@ && $(STRIP) $@
@@ -284,7 +296,8 @@ vst__posix64.o: ../carla-backend/vst.cpp
OBJS_WIN32 = \
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 \
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
$(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 = \
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 \
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
$(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:
$(MAKE) -C ../carla-lilv posix32

@@ -374,6 +391,21 @@ vst__win64.o: ../carla-backend/vst.cpp
../carla-lilv/carla_lilv_win64.a:
$(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:
$(MAKE) -C ../carla-jackbridge win32

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

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-posix32 carla-bridge-posix64

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

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

#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



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

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

#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);

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

if (m_controlData.target)
osc_send_lv2_transfer_event(&m_controlData, portIndex, atomBuf);
osc_send_lv2_transfer_event(&m_controlData, portIndex, typeStr, atomBuf);
}
#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;
double sampleRate = 44100.0;

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

// 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
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
{
public:
@@ -97,87 +130,148 @@ public:
for (uint32_t i=0; i < lv2_feature_count+1; i++)
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

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]->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]->URI = LV2_UI__parent;
@@ -187,13 +281,13 @@ public:
features[lv2_feature_id_ui_parent]->data = nullptr;
#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()
@@ -201,9 +295,13 @@ public:
if (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_Log_Log*)features[lv2_feature_id_logs]->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_Map_Path*)features[lv2_feature_id_state_map_path]->data;
delete (LV2_URI_Map_Feature*)features[lv2_feature_id_uri_map]->data;
@@ -230,13 +328,13 @@ public:
// ---------------------------------------------------------------------
// 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)

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

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

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];
break;
@@ -265,18 +363,18 @@ public:
// -----------------------------------------------------------------
// 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;

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

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

@@ -286,7 +384,7 @@ public:
// -----------------------------------------------------------
// 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)
return false;
@@ -313,6 +411,11 @@ public:
if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
{
programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);

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

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

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)
{
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);
Q_ASSERT(uri);

if (! uri)
return CARLA_URI_MAP_ID_NULL;

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

customURIDs.push_back(strdup(uri));

return customURIDs.size()-1;
}

const char* getCustomURIString(LV2_URID urid)
const char* getCustomURIString(const LV2_URID urid) const
{
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())
return customURIDs[urid];

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(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(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 (handle && descriptor && descriptor->port_event)
{
@@ -486,6 +616,8 @@ public:
#endif
}

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

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

if (! symbol)
return LV2UI_INVALID_PORT_INDEX;

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

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

quequeMessage(MESSAGE_RESIZE_GUI, width, height, 0.0);

return 0;
@@ -520,40 +658,36 @@ public:
{
if (format == 0)
{
Q_ASSERT(buffer);
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)
{
//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);
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)
{
//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);
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 ---------------------------------------------------

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);
Q_ASSERT(callback_data);
@@ -562,7 +696,7 @@ public:
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);
Q_ASSERT(callback_data);
@@ -573,7 +707,7 @@ public:

// ----------------- 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);
Q_ASSERT(handle);
@@ -592,7 +726,7 @@ public:
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);
Q_ASSERT(handle);
@@ -632,67 +766,86 @@ public:

// ----------------- 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);
Q_ASSERT(handle);

if (! handle)
return;

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

// ----------------- 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);
Q_ASSERT(handle);
Q_ASSERT(path);

if (! path)
return nullptr;

QDir dir;
dir.mkpath(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);
Q_ASSERT(handle);
Q_ASSERT(absolute_path);

if (! absolute_path)
return nullptr;

QDir dir(absolute_path);
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);
Q_ASSERT(handle);
Q_ASSERT(abstract_path);

if (! abstract_path)
return nullptr;

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

// ----------------- 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);
return carla_lv2_urid_map(data, uri);
return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
}

// ----------------- 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);
Q_ASSERT(handle);
Q_ASSERT(uri);

if (! uri)
return CARLA_URI_MAP_ID_NULL;

// Atom types
if (strcmp(uri, LV2_ATOM__Chunk) == 0)
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)
return CARLA_URI_MAP_ID_ATOM_PATH;
if (strcmp(uri, LV2_ATOM__Sequence) == 0)
@@ -704,6 +857,14 @@ public:
if (strcmp(uri, LV2_ATOM__eventTransfer) == 0)
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
if (strcmp(uri, LV2_LOG__Error) == 0)
return CARLA_URI_MAP_ID_LOG_ERROR;
@@ -717,21 +878,33 @@ public:
// Others
if (strcmp(uri, LV2_MIDI__MidiEvent) == 0)
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
CarlaLv2Client* const client = (CarlaLv2Client*)handle;
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);
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
if (urid == CARLA_URI_MAP_ID_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)
return LV2_ATOM__Path;
if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE)
@@ -743,6 +916,14 @@ public:
if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
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
if (urid == CARLA_URI_MAP_ID_LOG_ERROR)
return LV2_LOG__Error;
@@ -756,6 +937,11 @@ public:
// Others
if (urid == CARLA_URI_MAP_ID_MIDI_EVENT)
return LV2_MIDI__MidiEvent;
if (urid == CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE)
return LV2_PARAMETERS__sampleRate;

if (! handle)
return nullptr;

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

// ----------------- 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);
Q_ASSERT(handle);

if (! handle)
return LV2UI_INVALID_PORT_INDEX;

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

// ----------------- 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);
Q_ASSERT(handle);

if (! handle)
return 1;

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

// ----------------- 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);
Q_ASSERT(controller);

if (! controller)
return;

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

if (! client)
return 1;

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;
lv2client->handleTransferAtom(portIndex, atomBuf);

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

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

if (! client)
return 1;

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;
lv2client->handleTransferEvent(portIndex, atomBuf);

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

return 0;
}


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

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

#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
{
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

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(portIndex >= 0);
Q_ASSERT(typeStr);
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)
{
char targetPath[strlen(oscData->path)+19];
strcpy(targetPath, oscData->path);
strcat(targetPath, "/lv2_atom_transfer");
lo_send(oscData->target, targetPath, "is", portIndex, atomBuf);
lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf);
}
}

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(portIndex >= 0);
Q_ASSERT(typeStr);
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)
{
char targetPath[strlen(oscData->path)+20];
strcpy(targetPath, oscData->path);
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