Browse Source

LV2 UI<->DSP communication work, unfinished for bridges

tags/1.9.4
falkTX 11 years ago
parent
commit
7592d89d28
10 changed files with 371 additions and 301 deletions
  1. +2
    -7
      source/backend/plugin/CarlaPlugin.cpp
  2. +215
    -163
      source/backend/plugin/Lv2Plugin.cpp
  3. +3
    -3
      source/bridges/CarlaBridgeClient.cpp
  4. +1
    -1
      source/bridges/CarlaBridgeClient.hpp
  5. +10
    -7
      source/bridges/CarlaBridgeToolkitQt.cpp
  6. +109
    -107
      source/bridges/CarlaBridgeUI-LV2.cpp
  7. +8
    -2
      source/carla_control.py
  8. +13
    -0
      source/utils/CarlaLv2Utils.hpp
  9. +5
    -4
      source/utils/CarlaOscUtils.hpp
  10. +5
    -7
      source/utils/Lv2AtomQueue.hpp

+ 2
- 7
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1813,13 +1813,8 @@ void CarlaPlugin::updateOscData(const lo_address& source, const char* const url)
CARLA_ASSERT(cData.key != nullptr); CARLA_ASSERT(cData.key != nullptr);
CARLA_ASSERT(cData.value != nullptr); CARLA_ASSERT(cData.value != nullptr);


#ifdef WANT_LV2
if (type() == PLUGIN_LV2)
osc_send_lv2_transfer_event(&kData->osc.data, 0, cData.type, cData.value);
else
#endif
if (std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0)
osc_send_configure(&kData->osc.data, cData.key, cData.value);
if (std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0)
osc_send_configure(&kData->osc.data, cData.key, cData.value);
} }


if (kData->prog.current >= 0) if (kData->prog.current >= 0)


+ 215
- 163
source/backend/plugin/Lv2Plugin.cpp View File

@@ -43,17 +43,6 @@ CARLA_BACKEND_START_NAMESPACE
} }
#endif #endif


// non-void versions
#define LV2NV_ATOM_CONTENTS(type, atom) \
((uint8_t*)(atom) + sizeof(type))

#define LV2NV_ATOM_CONTENTS_CONST(type, atom) \
((const uint8_t*)(atom) + sizeof(type))

#define LV2NV_ATOM_BODY(atom) LV2NV_ATOM_CONTENTS(LV2_Atom, atom)

#define LV2NV_ATOM_BODY_CONST(atom) LV2NV_ATOM_CONTENTS_CONST(LV2_Atom, atom)

/*! /*!
* @defgroup PluginHints Plugin Hints * @defgroup PluginHints Plugin Hints
* @{ * @{
@@ -93,35 +82,36 @@ const unsigned int CARLA_EVENT_TYPE_TIME = 0x40;
* @{ * @{
*/ */
const uint32_t CARLA_URI_MAP_ID_NULL = 0; 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_FLOAT = 3;
const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 4;
const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 5;
const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 6;
const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 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_TIME_POSITION = 17; // base type
const uint32_t CARLA_URI_MAP_ID_TIME_BAR = 18; // values
const uint32_t CARLA_URI_MAP_ID_TIME_BAR_BEAT = 19;
const uint32_t CARLA_URI_MAP_ID_TIME_BEAT = 20;
const uint32_t CARLA_URI_MAP_ID_TIME_BEAT_UNIT = 21;
const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR = 22;
const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE = 23;
const uint32_t CARLA_URI_MAP_ID_TIME_FRAME = 24;
const uint32_t CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND = 25;
const uint32_t CARLA_URI_MAP_ID_TIME_SPEED = 26;
const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 27;
const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 28;
const uint32_t CARLA_URI_MAP_ID_COUNT = 29;
const uint32_t CARLA_URI_MAP_ID_ATOM_BLANK = 1;
const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 2;
const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 3;
const uint32_t CARLA_URI_MAP_ID_ATOM_FLOAT = 4;
const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 5;
const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 6;
const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 7;
const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 8;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 9;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 10;
const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 11;
const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 12;
const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 13;
const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 14;
const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 15;
const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 16;
const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 17;
const uint32_t CARLA_URI_MAP_ID_TIME_POSITION = 18; // base type
const uint32_t CARLA_URI_MAP_ID_TIME_BAR = 19; // values
const uint32_t CARLA_URI_MAP_ID_TIME_BAR_BEAT = 20;
const uint32_t CARLA_URI_MAP_ID_TIME_BEAT = 21;
const uint32_t CARLA_URI_MAP_ID_TIME_BEAT_UNIT = 22;
const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR = 23;
const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE = 24;
const uint32_t CARLA_URI_MAP_ID_TIME_FRAME = 25;
const uint32_t CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND = 26;
const uint32_t CARLA_URI_MAP_ID_TIME_SPEED = 27;
const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 28;
const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 29;
const uint32_t CARLA_URI_MAP_ID_COUNT = 30;
/**@}*/ /**@}*/


/*! /*!
@@ -395,19 +385,19 @@ public:
for (uint32_t i=0; i < CARLA_URI_MAP_ID_COUNT; ++i) for (uint32_t i=0; i < CARLA_URI_MAP_ID_COUNT; ++i)
fCustomURIDs.append(nullptr); fCustomURIDs.append(nullptr);


fAtomForge.Blank = carla_lv2_urid_map(this, LV2_ATOM__Blank);
fAtomForge.Blank = CARLA_URI_MAP_ID_ATOM_BLANK;
fAtomForge.Bool = carla_lv2_urid_map(this, LV2_ATOM__Bool); fAtomForge.Bool = carla_lv2_urid_map(this, LV2_ATOM__Bool);
fAtomForge.Chunk = carla_lv2_urid_map(this, LV2_ATOM__Chunk);
fAtomForge.Double = carla_lv2_urid_map(this, LV2_ATOM__Double);
fAtomForge.Float = carla_lv2_urid_map(this, LV2_ATOM__Float);
fAtomForge.Int = carla_lv2_urid_map(this, LV2_ATOM__Int);
fAtomForge.Chunk = CARLA_URI_MAP_ID_ATOM_CHUNK;
fAtomForge.Double = CARLA_URI_MAP_ID_ATOM_DOUBLE;
fAtomForge.Float = CARLA_URI_MAP_ID_ATOM_FLOAT;
fAtomForge.Int = CARLA_URI_MAP_ID_ATOM_INT;
fAtomForge.Long = carla_lv2_urid_map(this, LV2_ATOM__Long); fAtomForge.Long = carla_lv2_urid_map(this, LV2_ATOM__Long);
fAtomForge.Literal = carla_lv2_urid_map(this, LV2_ATOM__Literal); fAtomForge.Literal = carla_lv2_urid_map(this, LV2_ATOM__Literal);
fAtomForge.Path = carla_lv2_urid_map(this, LV2_ATOM__Path); fAtomForge.Path = carla_lv2_urid_map(this, LV2_ATOM__Path);
fAtomForge.Property = carla_lv2_urid_map(this, LV2_ATOM__Property); fAtomForge.Property = carla_lv2_urid_map(this, LV2_ATOM__Property);
fAtomForge.Resource = carla_lv2_urid_map(this, LV2_ATOM__Resource); fAtomForge.Resource = carla_lv2_urid_map(this, LV2_ATOM__Resource);
fAtomForge.Sequence = carla_lv2_urid_map(this, LV2_ATOM__Sequence);
fAtomForge.String = carla_lv2_urid_map(this, LV2_ATOM__String);
fAtomForge.Sequence = CARLA_URI_MAP_ID_ATOM_SEQUENCE;
fAtomForge.String = CARLA_URI_MAP_ID_ATOM_STRING;
fAtomForge.Tuple = carla_lv2_urid_map(this, LV2_ATOM__Tuple); fAtomForge.Tuple = carla_lv2_urid_map(this, LV2_ATOM__Tuple);
fAtomForge.URI = carla_lv2_urid_map(this, LV2_ATOM__URI); fAtomForge.URI = carla_lv2_urid_map(this, LV2_ATOM__URI);
fAtomForge.URID = carla_lv2_urid_map(this, LV2_ATOM__URID); fAtomForge.URID = carla_lv2_urid_map(this, LV2_ATOM__URID);
@@ -1243,6 +1233,50 @@ public:


void idleGui() override void idleGui() override
{ {
//if (fUi.type == PLUGIN_UI_NULL)
// return CarlaPlugin::idleGui();

if (! fAtomQueueOut.isEmpty())
{
Lv2AtomQueue tmpQueue;
tmpQueue.copyDataFrom(&fAtomQueueOut);

uint32_t portIndex;
const LV2_Atom* atom;
const bool hasPortEvent(fUi.handle != nullptr && fUi.descriptor != nullptr && fUi.descriptor->port_event != nullptr);

while (tmpQueue.get(&portIndex, &atom))
{
//carla_stdout("OUTPUT message IN GUI REMOVED FROM BUFFER");

if (fUi.type == PLUGIN_UI_OSC)
{
if (kData->osc.data.target != nullptr)
{
QByteArray chunk((const char*)atom, lv2_atom_total_size(atom));

const char* typeStr = carla_lv2_urid_unmap(this, atom->type);
const char* bodyStr = "";

if (atom->type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
const LV2_Atom_Object* const obj((const LV2_Atom_Object*)atom);

if (obj->body.otype != CARLA_URI_MAP_ID_NULL)
bodyStr = carla_lv2_urid_unmap(this, obj->body.otype);
}

osc_send_lv2_transfer_event(&kData->osc.data, portIndex, typeStr, bodyStr, chunk.toBase64().constData());
}
}
else if (fUi.type != PLUGIN_UI_NULL)
{
if (hasPortEvent)
fUi.descriptor->port_event(fUi.handle, portIndex, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
}
}
}

if (fUi.handle != nullptr && fUi.descriptor != nullptr) if (fUi.handle != nullptr && fUi.descriptor != nullptr)
{ {
if (fUi.type == PLUGIN_UI_EXTERNAL && fUi.widget != nullptr) if (fUi.type == PLUGIN_UI_EXTERNAL && fUi.widget != nullptr)
@@ -1559,34 +1593,31 @@ public:
fEventsIn.data[j].rindex = i; fEventsIn.data[j].rindex = i;


if (portTypes & LV2_PORT_DATA_MIDI_EVENT) if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;


if (evIns.count() == 1)
{
if (evIns.count() == 1)
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;

if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
needsCtrlIn = true; needsCtrlIn = true;
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
}
else
{
}
else
{
if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
fEventsIn.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true); fEventsIn.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);


if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
}
if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
} }
} }
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
}
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
}
} }
else if (LV2_IS_PORT_OUTPUT(portTypes)) else if (LV2_IS_PORT_OUTPUT(portTypes))
{ {
@@ -1600,34 +1631,31 @@ public:
fEventsOut.data[j].rindex = i; fEventsOut.data[j].rindex = i;


if (portTypes & LV2_PORT_DATA_MIDI_EVENT) if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;


if (evOuts.count() == 1)
{
if (evOuts.count() == 1)
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;

if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
needsCtrlOut = true; needsCtrlOut = true;
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
}
else
{
}
else
{
if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
fEventsOut.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false); fEventsOut.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);


if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
}
if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
} }
} }
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
}
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
}
} }
else else
carla_stderr("WARNING - Got a broken Port (Atom Sequence, but not input or output)"); carla_stderr("WARNING - Got a broken Port (Atom Sequence, but not input or output)");
@@ -1646,34 +1674,31 @@ public:
fEventsIn.data[j].rindex = i; fEventsIn.data[j].rindex = i;


if (portTypes & LV2_PORT_DATA_MIDI_EVENT) if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;


if (evIns.count() == 1)
{
if (evIns.count() == 1)
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;

if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
needsCtrlIn = true; needsCtrlIn = true;
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
}
else
{
}
else
{
if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
fEventsIn.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true); fEventsIn.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);


if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
}
if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsIn.ctrl = &fEventsIn.data[j];
fEventsIn.ctrlIndex = j;
} }
} }
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
}
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
{
fEventsIn.data[j].type |= CARLA_EVENT_TYPE_TIME;
}
} }
else if (LV2_IS_PORT_OUTPUT(portTypes)) else if (LV2_IS_PORT_OUTPUT(portTypes))
{ {
@@ -1687,34 +1712,31 @@ public:
fEventsOut.data[j].rindex = i; fEventsOut.data[j].rindex = i;


if (portTypes & LV2_PORT_DATA_MIDI_EVENT) if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;


if (evOuts.count() == 1)
{
if (evOuts.count() == 1)
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;

if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
needsCtrlOut = true; needsCtrlOut = true;
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
}
else
{
}
else
{
if (portTypes & LV2_PORT_DATA_MIDI_EVENT)
fEventsOut.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false); fEventsOut.data[j].port = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);


if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
}
if (LV2_IS_PORT_DESIGNATION_CONTROL(fRdfDescriptor->Ports[i].Designation))
{
fEventsOut.ctrl = &fEventsOut.data[j];
fEventsOut.ctrlIndex = j;
} }
} }
if (portTypes & LV2_PORT_DATA_PATCH_MESSAGE)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MESSAGE;
}
if (portTypes & LV2_PORT_DATA_TIME_POSITION)
{
fEventsOut.data[j].type |= CARLA_EVENT_TYPE_TIME;
}
} }
else else
carla_stderr("WARNING - Got a broken Port (Event, but not input or output)"); carla_stderr("WARNING - Got a broken Port (Event, but not input or output)");
@@ -1780,7 +1802,7 @@ public:
} }
} }
else else
carla_stderr("WARNING - Got a broken Port (Midi, but not input or output)");
carla_stderr("WARNING - Got a broken Port (MIDI, but not input or output)");
} }
else if (LV2_IS_PORT_CONTROL(portTypes)) else if (LV2_IS_PORT_CONTROL(portTypes))
{ {
@@ -2542,7 +2564,7 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Event Input and Processing // Event Input and Processing


if (fEventsIn.ctrl != nullptr && fEventsIn.ctrl->port != nullptr)
if (fEventsIn.ctrl != nullptr)
{ {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// Message Input // Message Input
@@ -2556,16 +2578,18 @@ public:


k = fEventsIn.ctrlIndex; k = fEventsIn.ctrlIndex;


while (lv2_atom_buffer_is_valid(&evInAtomIters[k]) && fAtomQueueIn.get(&portIndex, &atom))
while (fAtomQueueIn.get(&portIndex, &atom))
{ {
//if (atom->type == CARLA_URI_MAP_ID_ATOM_WORKER)
//{
// const LV2_Atom_Worker* const atomWorker = (const LV2_Atom_Worker*)atom;
// fExt.worker->work_response(fHandle, atomWorker->body.size, atomWorker->body.data);
// continue;
//}

lv2_atom_buffer_write(&evInAtomIters[k], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom));
carla_stdout("Event input message sent to plugin DSP, type %i:\"%s\", size:%i/%i",
atom->type, carla_lv2_urid_unmap(this, atom->type),
atom->size, lv2_atom_total_size(atom)
);

if (! lv2_atom_buffer_write(&evInAtomIters[k], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom)))
{
carla_stdout("Event input buffer full, 1 message lost");
break;
}
} }
} }


@@ -2614,7 +2638,7 @@ public:
bool allNotesOffSent = false; bool allNotesOffSent = false;
bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0; bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;


uint32_t time, nEvents = fEventsIn.ctrl->port->getEventCount();
uint32_t time, nEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
uint32_t startTime = 0; uint32_t startTime = 0;
uint32_t timeOffset = 0; uint32_t timeOffset = 0;
uint32_t nextBankId = 0; uint32_t nextBankId = 0;
@@ -2901,10 +2925,11 @@ public:
// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// MIDI Output // MIDI Output


if (fEventsOut.ctrl != nullptr && fEventsOut.ctrl->port != nullptr)
if (fEventsOut.ctrl != nullptr)
{ {
if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM) if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM)
{ {
const uint32_t rindex(fEventsOut.ctrl->rindex);
const LV2_Atom_Event* ev; const LV2_Atom_Event* ev;
LV2_Atom_Buffer_Iterator iter; LV2_Atom_Buffer_Iterator iter;


@@ -2919,13 +2944,19 @@ public:
if (ev == nullptr || data == nullptr) if (ev == nullptr || data == nullptr)
break; break;


if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT)
if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT && fEventsOut.ctrl->port != nullptr)
fEventsOut.ctrl->port->writeMidiEvent(ev->time.frames, data, ev->body.size); fEventsOut.ctrl->port->writeMidiEvent(ev->time.frames, data, ev->body.size);
else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
//carla_stdout("Event OUTPUT message TO BE SENT TO UI, type blank");

fAtomQueueOut.put(rindex, &ev->body);
}


lv2_atom_buffer_increment(&iter); lv2_atom_buffer_increment(&iter);
} }
} }
else if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_EVENT)
else if ((fEventsOut.ctrl->type & CARLA_EVENT_DATA_EVENT) != 0 && fEventsOut.ctrl->port != nullptr)
{ {
const LV2_Event* ev; const LV2_Event* ev;
LV2_Event_Iterator iter; LV2_Event_Iterator iter;
@@ -2947,7 +2978,7 @@ public:
lv2_event_increment(&iter); lv2_event_increment(&iter);
} }
} }
else if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
else if ((fEventsOut.ctrl->type & CARLA_EVENT_DATA_MIDI_LL) != 0 && fEventsOut.ctrl->port != nullptr)
{ {
LV2_MIDIState state = { fEventsOut.ctrl->midi, frames, 0 }; LV2_MIDIState state = { fEventsOut.ctrl->midi, frames, 0 };


@@ -3781,8 +3812,7 @@ protected:
if (buffer == nullptr) if (buffer == nullptr)
return; return;


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


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

const LV2_Atom* atom((const LV2_Atom*)buffer);
carla_stdout("UI WRITE DATA: %i | size:%i, realSize:%i, type:\"%s\"", rindex, atom->size, lv2_atom_total_size(atom), carla_lv2_urid_unmap(this, atom->type));
}
else
{
carla_stdout("Lv2Plugin::handleUiWrite(%i, %i, %i:\"%s\", %p) - unknown format", rindex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer);
} }
} }


@@ -4634,22 +4670,33 @@ public:
CARLA_ASSERT(portIndex >= 0); CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(atom != nullptr); CARLA_ASSERT(atom != nullptr);
CARLA_ASSERT(typeStr != nullptr); CARLA_ASSERT(typeStr != nullptr);
carla_debug("Lv2Plugin::handleTransferAtom(%i, %s, %p)", portIndex, typeStr, atom);
carla_debug("Lv2Plugin::handleTransferAtom(%i, \"%s\", %p)", portIndex, typeStr, atom);


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


fAtomQueueIn.put(portIndex, atom); fAtomQueueIn.put(portIndex, atom);
} }


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


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


if (atom->type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
LV2_Atom_Object* const obj((LV2_Atom_Object*)atom);

if (obj->body.otype != CARLA_URI_MAP_ID_NULL)
obj->body.otype = carla_lv2_urid_map(this, bodyStr);
}

carla_stdout("FROM OSC UI WRITE DATA: %i | size:%i, realSize:%i, type:\"%s\"", portIndex, atom->size, lv2_atom_total_size(atom), carla_lv2_urid_unmap(this, atom->type));

fAtomQueueIn.put(portIndex, atom); fAtomQueueIn.put(portIndex, atom);
} }


@@ -4918,6 +4965,8 @@ private:
return CARLA_URI_MAP_ID_NULL; return CARLA_URI_MAP_ID_NULL;


// Atom types // Atom types
if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
return CARLA_URI_MAP_ID_ATOM_BLANK;
if (std::strcmp(uri, LV2_ATOM__Chunk) == 0) if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
return CARLA_URI_MAP_ID_ATOM_CHUNK; return CARLA_URI_MAP_ID_ATOM_CHUNK;
if (std::strcmp(uri, LV2_ATOM__Double) == 0) if (std::strcmp(uri, LV2_ATOM__Double) == 0)
@@ -5000,6 +5049,8 @@ private:
return nullptr; return nullptr;


// Atom types // Atom types
if (urid == CARLA_URI_MAP_ID_ATOM_BLANK)
return LV2_ATOM__Blank;
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) if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
@@ -5174,6 +5225,8 @@ private:


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


#define lv2PluginPtr ((Lv2Plugin*)plugin)

int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2) int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
{ {
carla_debug("CarlaOsc::handleMsgLv2AtomTransfer()"); carla_debug("CarlaOsc::handleMsgLv2AtomTransfer()");
@@ -5187,31 +5240,30 @@ int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
chunk = QByteArray::fromBase64(atomBuf); chunk = QByteArray::fromBase64(atomBuf);


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

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

lv2PluginPtr->handleTransferAtom(portIndex, typeStr, atom);
return 0; return 0;
} }


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


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


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


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

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

lv2PluginPtr->handleTransferEvent(portIndex, typeStr, bodyStr, atom);
return 0; return 0;
} }


#undef lv2PluginPtr

CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_VST #else // WANT_VST


+ 3
- 3
source/bridges/CarlaBridgeClient.cpp View File

@@ -264,13 +264,13 @@ void CarlaBridgeClient::sendOscLv2TransferAtom(const int32_t portIndex, const ch
osc_send_lv2_transfer_atom(fOscData, portIndex, typeStr, atomBuf); osc_send_lv2_transfer_atom(fOscData, portIndex, typeStr, atomBuf);
} }


void CarlaBridgeClient::sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
void CarlaBridgeClient::sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const bodyStr, const char* const atomBuf)
{ {
carla_debug("CarlaBridgeClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
carla_debug("CarlaBridgeClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\", \"%s\")", portIndex, typeStr, bodyStr, atomBuf);
CARLA_ASSERT(fOscData != nullptr); CARLA_ASSERT(fOscData != nullptr);


if (fOscData != nullptr && fOscData->target != nullptr) if (fOscData != nullptr && fOscData->target != nullptr)
osc_send_lv2_transfer_event(fOscData, portIndex, typeStr, atomBuf);
osc_send_lv2_transfer_event(fOscData, portIndex, typeStr, bodyStr, atomBuf);
} }
#endif #endif




+ 1
- 1
source/bridges/CarlaBridgeClient.hpp View File

@@ -115,7 +115,7 @@ protected:


#ifdef BRIDGE_LV2 #ifdef BRIDGE_LV2
void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf); void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf);
void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf);
void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const bodyStr, const char* const atomBuf);
#endif #endif


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


+ 10
- 7
source/bridges/CarlaBridgeToolkitQt.cpp View File

@@ -188,7 +188,7 @@ public:
msgTimer = 0; msgTimer = 0;
} }


if (window)
if (window != nullptr)
{ {
settings.setValue(QString("%1/pos_x").arg(kUiTitle), window->x()); settings.setValue(QString("%1/pos_x").arg(kUiTitle), window->x());
settings.setValue(QString("%1/pos_y").arg(kUiTitle), window->y()); settings.setValue(QString("%1/pos_y").arg(kUiTitle), window->y());
@@ -197,13 +197,10 @@ public:
settings.sync(); settings.sync();


window->close(); window->close();

delete window;
window = nullptr;
} }


#ifdef BRIDGE_CONTAINER #ifdef BRIDGE_CONTAINER
if (embedContainer)
if (embedContainer != nullptr)
{ {
embedContainer->close(); embedContainer->close();


@@ -212,6 +209,12 @@ public:
} }
#endif #endif


if (window != nullptr)
{
delete window;
window = nullptr;
}

if (app) if (app)
{ {
if (! app->closingDown()) if (! app->closingDown())
@@ -266,9 +269,9 @@ public:
void* getContainerId() void* getContainerId()
{ {
carla_debug("CarlaBridgeToolkitQt::getContainerId()"); carla_debug("CarlaBridgeToolkitQt::getContainerId()");
CARLA_ASSERT(window);
CARLA_ASSERT(window != nullptr);


if (! embedContainer)
if (embedContainer == nullptr)
{ {
embedContainer = new QEmbedContainer(window); embedContainer = new QEmbedContainer(window);




+ 109
- 107
source/bridges/CarlaBridgeUI-LV2.cpp View File

@@ -15,8 +15,6 @@
* For a full copy of the GNU General Public License see the GPL.txt file * For a full copy of the GNU General Public License see the GPL.txt file
*/ */


#ifdef BRIDGE_LV2

#include "CarlaBridgeClient.hpp" #include "CarlaBridgeClient.hpp"
#include "CarlaLv2Utils.hpp" #include "CarlaLv2Utils.hpp"
#include "CarlaMIDI.h" #include "CarlaMIDI.h"
@@ -63,25 +61,26 @@ 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_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;
const uint32_t CARLA_URI_MAP_ID_ATOM_BLANK = 1;
const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 2;
const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 3;
const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 4;
const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 5;
const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 6;
const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 7;
const uint32_t CARLA_URI_MAP_ID_ATOM_WORKER = 8;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 9;
const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 10;
const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 11;
const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 12;
const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 13;
const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 14;
const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 15;
const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 16;
const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 17;
const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 18;
const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 19;
const uint32_t CARLA_URI_MAP_ID_COUNT = 20;


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


@@ -261,33 +260,29 @@ public:
features[lv2_feature_id_strict_bounds]->URI = LV2_PORT_PROPS__supportsStrictBounds; 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]->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 = uriMapFt;
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 = uridMapFt;
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 = uridUnmapFt;
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;
#ifdef BRIDGE_LV2_X11
features[lv2_feature_id_ui_parent]->data = getContainerId();
#else
features[lv2_feature_id_ui_parent]->data = nullptr; 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 = uiPortMapFt;
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 = uiResizeFt;
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()
@@ -389,6 +384,10 @@ public:
// ----------------------------------------------------------- // -----------------------------------------------------------
// initialize UI // initialize UI


#ifdef BRIDGE_LV2_X11
features[lv2_feature_id_ui_parent]->data = getContainerId();
#endif

handle = descriptor->instantiate(descriptor, pluginURI, 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)
@@ -562,61 +561,20 @@ public:
{ {
carla_debug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom); carla_debug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
CARLA_ASSERT(portIndex >= 0); CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(atom);
CARLA_ASSERT(atom != nullptr);


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


void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom) void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom)
{ {
carla_debug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom); carla_debug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
CARLA_ASSERT(portIndex >= 0); CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(atom);

if (atom && 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)
{
LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set);
const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body);

Sratom* sratom = sratom_new(URID_Map);
SerdChunk chunk = { nullptr, 0 };

LV2_Atom_Forge forge;
lv2_atom_forge_init(&forge, URID_Map);
lv2_atom_forge_set_sink(&forge, sratom_forge_sink, sratom_forge_deref, &chunk);
CARLA_ASSERT(atom != nullptr);


LV2_Atom_Forge_Frame refFrame, bodyFrame;
LV2_Atom_Forge_Ref ref = lv2_atom_forge_blank(&forge, &refFrame, 1, uridPatchSet);

lv2_atom_forge_property_head(&forge, uridPatchBody, CARLA_URI_MAP_ID_NULL);
lv2_atom_forge_blank(&forge, &bodyFrame, 2, CARLA_URI_MAP_ID_NULL);

//lv2_atom_forge_property_head(&forge, getCustomURID(key), CARLA_URI_MAP_ID_NULL);

if (std::strcmp(type, "string") == 0)
lv2_atom_forge_string(&forge, value, std::strlen(value));
else if (std::strcmp(type, "path") == 0)
lv2_atom_forge_path(&forge, value, std::strlen(value));
else if (std::strcmp(type, "chunk") == 0)
lv2_atom_forge_literal(&forge, value, std::strlen(value), CARLA_URI_MAP_ID_ATOM_CHUNK, CARLA_URI_MAP_ID_NULL);
//else
// lv2_atom_forge_literal(&forge, value, std::strlen(value), getCustomURID(key), CARLA_URI_MAP_ID_NULL);

lv2_atom_forge_pop(&forge, &bodyFrame);
lv2_atom_forge_pop(&forge, &refFrame);

const LV2_Atom* const atom = lv2_atom_forge_deref(&forge, ref);
descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);

free((void*)chunk.buf);
sratom_free(sratom);
}
#endif
if (atom != nullptr && handle != nullptr && descriptor != nullptr && descriptor->port_event != nullptr)
descriptor->port_event(handle, portIndex, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
} }


// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@@ -659,35 +617,69 @@ public:


void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
{ {
if (! (buffer && isOscControlRegistered()))
#ifdef DEBUG
if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
{
const LV2_Atom* const atom((const LV2_Atom*)buffer);
carla_stdout("OSC UI WRITE DATA: %i | size:%i, realSize:%i, bufferSize:%i, type:\"%s\"", portIndex, atom->size, lv2_atom_total_size(atom), bufferSize, carla_lv2_urid_unmap(this, atom->type));
}
#endif

if (buffer == nullptr || ! isOscControlRegistered())
return; return;


if (format == 0) if (format == 0)
{ {
CARLA_ASSERT(buffer);
CARLA_ASSERT(bufferSize == sizeof(float)); CARLA_ASSERT(bufferSize == sizeof(float));


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


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

sendOscControl(portIndex, value); sendOscControl(portIndex, value);
} }
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM) else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
{ {
CARLA_ASSERT(buffer);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;
CARLA_ASSERT(bufferSize != 0);

if (bufferSize == 0)
return;

const LV2_Atom* const atom((const LV2_Atom*)buffer);
const char* const typeStr(carla_lv2_urid_unmap(this, atom->type));


QByteArray chunk((const char*)buffer, bufferSize); QByteArray chunk((const char*)buffer, bufferSize);
sendOscLv2TransferAtom(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
sendOscLv2TransferAtom(portIndex, typeStr, chunk.toBase64().constData());
} }
else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
{ {
CARLA_ASSERT(buffer);
const LV2_Atom* const atom = (const LV2_Atom*)buffer;
CARLA_ASSERT(bufferSize != 0);

if (bufferSize == 0)
return;

const LV2_Atom* const atom((const LV2_Atom*)buffer);

const char* typeStr = carla_lv2_urid_unmap(this, atom->type);
const char* bodyStr = "";

if (atom->type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
const LV2_Atom_Object* const obj((const LV2_Atom_Object*)atom);
carla_stdout("OSC UI WRITE DATA: IS BLANK! %i", obj->body.otype);

carla_stdout("OSC UI WRITE DATA: TEST %i", carla_lv2_urid_map(this, "http://gareus.org/oss/lv2/balance#meteron"));

if (obj->body.otype != CARLA_URI_MAP_ID_NULL)
{
bodyStr = carla_lv2_urid_unmap(this, obj->body.otype);
carla_stdout("OSC UI WRITE DATA: IS BLANK! AND BODY STR:\"%s\"", bodyStr);
}
}


QByteArray chunk((const char*)buffer, bufferSize); QByteArray chunk((const char*)buffer, bufferSize);
sendOscLv2TransferEvent(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
sendOscLv2TransferEvent(portIndex, typeStr, bodyStr, chunk.toBase64().constData());
} }
} }


@@ -846,6 +838,8 @@ public:
return CARLA_URI_MAP_ID_NULL; return CARLA_URI_MAP_ID_NULL;


// Atom types // Atom types
if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
return CARLA_URI_MAP_ID_ATOM_BLANK;
if (std::strcmp(uri, LV2_ATOM__Chunk) == 0) if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
return CARLA_URI_MAP_ID_ATOM_CHUNK; return CARLA_URI_MAP_ID_ATOM_CHUNK;
if (std::strcmp(uri, LV2_ATOM__Double) == 0) if (std::strcmp(uri, LV2_ATOM__Double) == 0)
@@ -905,6 +899,8 @@ public:
return nullptr; return nullptr;


// Atom types // Atom types
if (urid == CARLA_URI_MAP_ID_ATOM_BLANK)
return LV2_ATOM__Blank;
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) if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
@@ -1020,7 +1016,7 @@ int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
if (! kClient) if (! kClient)
return 1; return 1;


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


@@ -1030,7 +1026,7 @@ int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient; CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient;


atom->type = lv2Client->getCustomURID(typeStr);
atom->type = CarlaLv2Client::carla_lv2_urid_map(lv2Client, typeStr);
lv2Client->handleTransferAtom(portIndex, atom); lv2Client->handleTransferAtom(portIndex, atom);


return 0; return 0;
@@ -1039,14 +1035,15 @@ int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS) int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{ {
carla_debug("CarlaBridgeOsc::handleMsgLv2TransferEvent()"); carla_debug("CarlaBridgeOsc::handleMsgLv2TransferEvent()");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(4, "isss");


if (! kClient) if (! kClient)
return 1; return 1;


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


QByteArray chunk; QByteArray chunk;
chunk = QByteArray::fromBase64(atomBuf); chunk = QByteArray::fromBase64(atomBuf);
@@ -1054,7 +1051,16 @@ int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient; CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient;


atom->type = lv2Client->getCustomURID(typeStr);
atom->type = CarlaLv2Client::carla_lv2_urid_map(lv2Client, typeStr);

if (atom->type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
LV2_Atom_Object* const obj((LV2_Atom_Object*)atom);

if (obj->body.otype != CARLA_URI_MAP_ID_NULL)
obj->body.otype = CarlaLv2Client::carla_lv2_urid_map(this, bodyStr);
}

lv2Client->handleTransferEvent(portIndex, atom); lv2Client->handleTransferEvent(portIndex, atom);


return 0; return 0;
@@ -1080,9 +1086,7 @@ int main(int argc, char* argv[])
const bool useOsc = std::strcmp(oscUrl, "null"); const bool useOsc = std::strcmp(oscUrl, "null");


// try to get sampleRate value // try to get sampleRate value
const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE");

if (sampleRateStr)
if (const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE"))
sampleRate = atof(sampleRateStr); sampleRate = atof(sampleRateStr);


// Init LV2 client // Init LV2 client
@@ -1115,5 +1119,3 @@ int main(int argc, char* argv[])


return ret; return ret;
} }

#endif // BRIDGE_LV2

+ 8
- 2
source/carla_control.py View File

@@ -1058,9 +1058,15 @@ if __name__ == '__main__':


libPrefix = None libPrefix = None


for i in range(len(app.arguments())):
argv = app.arguments()
argc = len(argv)

#print(argc)
#print(argv)

for i in range(argc):
if i == 0: continue if i == 0: continue
argument = app.arguments()[i]
argument = argv[i]


if argument.startswith("--with-libprefix="): if argument.startswith("--with-libprefix="):
libPrefix = argument.replace("--with-libprefix=", "") libPrefix = argument.replace("--with-libprefix=", "")


+ 13
- 0
source/utils/CarlaLv2Utils.hpp View File

@@ -82,6 +82,19 @@
#define LV2_UI__idle LV2_UI_PREFIX "idle" #define LV2_UI__idle LV2_UI_PREFIX "idle"
#define LV2_UI__makeResident LV2_UI_PREFIX "makeResident" #define LV2_UI__makeResident LV2_UI_PREFIX "makeResident"


// -------------------------------------------------
// Non-void versions

#define LV2NV_ATOM_CONTENTS(type, atom) \
((uint8_t*)(atom) + sizeof(type))

#define LV2NV_ATOM_CONTENTS_CONST(type, atom) \
((const uint8_t*)(atom) + sizeof(type))

#define LV2NV_ATOM_BODY(atom) LV2NV_ATOM_CONTENTS(LV2_Atom, atom)

#define LV2NV_ATOM_BODY_CONST(atom) LV2NV_ATOM_CONTENTS_CONST(LV2_Atom, atom)

// ------------------------------------------------- // -------------------------------------------------
// Custom Atom types // Custom Atom types




+ 5
- 4
source/utils/CarlaOscUtils.hpp View File

@@ -332,20 +332,21 @@ void osc_send_lv2_transfer_atom(const CarlaOscData* const oscData, const int32_t
} }


static inline static inline
void osc_send_lv2_transfer_event(const CarlaOscData* const oscData, const int32_t portIndex, const char* const typeStr, 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 bodyStr, const char* const atomBuf)
{ {
CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr); CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
CARLA_ASSERT(portIndex >= 0); CARLA_ASSERT(portIndex >= 0);
CARLA_ASSERT(typeStr != nullptr); CARLA_ASSERT(typeStr != nullptr);
CARLA_ASSERT(bodyStr != nullptr);
CARLA_ASSERT(atomBuf != nullptr); CARLA_ASSERT(atomBuf != nullptr);
carla_debug("osc_send_lv2_transfer_event(path:\"%s\", %i, \"%s\", <atomBuf:%p>)", oscData->path, portIndex, typeStr, atomBuf);
carla_debug("osc_send_lv2_transfer_event(path:\"%s\", %i, \"%s\", \"%s\", <atomBuf:%p>)", oscData->path, portIndex, typeStr, bodyStr, atomBuf);


if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && portIndex >= 0 && typeStr != nullptr && atomBuf != nullptr)
if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && portIndex >= 0 && typeStr != nullptr && bodyStr != nullptr && atomBuf != nullptr)
{ {
char targetPath[std::strlen(oscData->path)+20]; char targetPath[std::strlen(oscData->path)+20];
std::strcpy(targetPath, oscData->path); std::strcpy(targetPath, oscData->path);
std::strcat(targetPath, "/lv2_event_transfer"); std::strcat(targetPath, "/lv2_event_transfer");
lo_send(oscData->target, targetPath, "iss", portIndex, typeStr, atomBuf);
lo_send(oscData->target, targetPath, "isss", portIndex, typeStr, bodyStr, atomBuf);
} }
} }
#endif #endif


+ 5
- 7
source/utils/Lv2AtomQueue.hpp View File

@@ -18,11 +18,9 @@
#ifndef __LV2_ATOM_QUEUE_HPP__ #ifndef __LV2_ATOM_QUEUE_HPP__
#define __LV2_ATOM_QUEUE_HPP__ #define __LV2_ATOM_QUEUE_HPP__


#include "CarlaLv2Utils.hpp"
#include "CarlaMutex.hpp" #include "CarlaMutex.hpp"


#include <cstring> // memcpy, memset
#include "lv2/atom.h"

class Lv2AtomQueue class Lv2AtomQueue
{ {
public: public:
@@ -90,7 +88,7 @@ public:


void put(const uint32_t portIndex, const LV2_Atom* const atom) void put(const uint32_t portIndex, const LV2_Atom* const atom)
{ {
CARLA_ASSERT(atom && atom->size > 0);
CARLA_ASSERT(atom != nullptr && atom->size > 0);
CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow CARLA_ASSERT(indexPool + atom->size < MAX_POOL_SIZE); // overflow


if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE) if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE)
@@ -106,7 +104,7 @@ public:
data[i].size = atom->size; data[i].size = atom->size;
data[i].type = atom->type; data[i].type = atom->type;
data[i].poolOffset = indexPool; data[i].poolOffset = indexPool;
std::memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(atom), atom->size);
std::memcpy(dataPool + indexPool, LV2NV_ATOM_BODY_CONST(atom), atom->size);
empty = false; empty = false;
full = (i == MAX_SIZE-1); full = (i == MAX_SIZE-1);
indexPool += atom->size; indexPool += atom->size;
@@ -120,9 +118,9 @@ public:
// needs to be locked first! // needs to be locked first!
bool get(uint32_t* const portIndex, const LV2_Atom** const atom) bool get(uint32_t* const portIndex, const LV2_Atom** const atom)
{ {
CARLA_ASSERT(portIndex && atom);
CARLA_ASSERT(portIndex != nullptr && atom != nullptr);


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


full = false; full = false;


Loading…
Cancel
Save