| @@ -139,6 +139,7 @@ const uint32_t CARLA_URI_MAP_ID_COUNT = 18; | |||||
| struct Lv2EventData { | struct Lv2EventData { | ||||
| uint32_t type; | uint32_t type; | ||||
| uint32_t rindex; | |||||
| CarlaEngineMidiPort* port; | CarlaEngineMidiPort* port; | ||||
| union { | union { | ||||
| LV2_Atom_Sequence* atom; | LV2_Atom_Sequence* atom; | ||||
| @@ -148,6 +149,7 @@ struct Lv2EventData { | |||||
| Lv2EventData() | Lv2EventData() | ||||
| : type(0), | : type(0), | ||||
| rindex(0), | |||||
| port(nullptr) {} | port(nullptr) {} | ||||
| }; | }; | ||||
| @@ -206,6 +208,173 @@ LV2_Atom_Event* getLv2AtomEvent(LV2_Atom_Sequence* const atom, const uint32_t of | |||||
| return (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atom) + offset); | return (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atom) + offset); | ||||
| } | } | ||||
| class Lv2AtomQueue | |||||
| { | |||||
| public: | |||||
| Lv2AtomQueue() | |||||
| { | |||||
| index = indexPool = 0; | |||||
| empty = true; | |||||
| full = false; | |||||
| memset(dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| } | |||||
| void copyDataFrom(Lv2AtomQueue* const queue) | |||||
| { | |||||
| // lock mutexes | |||||
| queue->mutex.lock(); | |||||
| mutex.lock(); | |||||
| // copy data from queue | |||||
| memcpy(data, queue->data, sizeof(datatype)*MAX_SIZE); | |||||
| memcpy(dataPool, queue->dataPool, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| index = queue->index; | |||||
| indexPool = queue->indexPool; | |||||
| empty = queue->empty; | |||||
| full = queue->full; | |||||
| // unlock our mutex, no longer needed | |||||
| mutex.unlock(); | |||||
| // reset queque | |||||
| memset(queue->data, 0, sizeof(datatype)*MAX_SIZE); | |||||
| memset(queue->dataPool, 0, sizeof(unsigned char)*MAX_POOL_SIZE); | |||||
| queue->index = queue->indexPool = 0; | |||||
| queue->empty = true; | |||||
| queue->full = false; | |||||
| // unlock queque mutex | |||||
| queue->mutex.unlock(); | |||||
| } | |||||
| bool isEmpty() | |||||
| { | |||||
| return empty; | |||||
| } | |||||
| bool isFull() | |||||
| { | |||||
| return full; | |||||
| } | |||||
| void lock() | |||||
| { | |||||
| mutex.lock(); | |||||
| } | |||||
| void unlock() | |||||
| { | |||||
| mutex.unlock(); | |||||
| } | |||||
| void put(const uint32_t portIndex, const LV2_Atom& atom, const bool lock = true) | |||||
| { | |||||
| qDebug("Lv2AtomQueue::put(%i, size:%i, %s)", portIndex, atom.size, bool2str(lock)); | |||||
| Q_ASSERT(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].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, 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; | |||||
| } | |||||
| static struct { | |||||
| uint32_t size; | |||||
| uint32_t type; | |||||
| unsigned char* data; | |||||
| } thisAtom; | |||||
| thisAtom.size = data[index].size; | |||||
| thisAtom.type = data[index].type; | |||||
| thisAtom.data = dataPool + data[index].poolOffset; | |||||
| *portIndex = data[index].portIndex; | |||||
| *atom = (LV2_Atom*)&thisAtom; | |||||
| data[index].portIndex = 0; | |||||
| data[index].size = 0; | |||||
| data[index].type = 0; | |||||
| 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 = 32; | |||||
| static const unsigned short MAX_POOL_SIZE = 8192; | |||||
| datatype data[MAX_SIZE]; | |||||
| unsigned char dataPool[MAX_POOL_SIZE]; | |||||
| unsigned short index; | |||||
| uint32_t indexPool; | |||||
| bool empty, full; | |||||
| QMutex mutex; | |||||
| }; | |||||
| class Lv2Plugin : public CarlaPlugin | class Lv2Plugin : public CarlaPlugin | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -1018,9 +1187,36 @@ public: | |||||
| void idleGui() | void idleGui() | ||||
| { | { | ||||
| // Update external UI | |||||
| if (gui.type == GUI_EXTERNAL_LV2 && ui.handle && ui.descriptor && ui.widget) | |||||
| LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)ui.widget); | |||||
| const bool haveUI = (gui.type == GUI_EXTERNAL_OSC && osc.data.target) || (ui.handle && ui.descriptor); | |||||
| if (haveUI) | |||||
| { | |||||
| // Update event ports | |||||
| static Lv2AtomQueue queue; | |||||
| queue.copyDataFrom(&atomQueueOut); | |||||
| uint32_t portIndex; | |||||
| LV2_Atom* atom; | |||||
| while (atomQueueIn.get(&portIndex, &atom, false)) | |||||
| { | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (gui.type == GUI_EXTERNAL_OSC) | |||||
| { | |||||
| osc_send_lv2_transfer_event(&osc.data, nullptr, nullptr); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| { | |||||
| if (ui.descriptor->port_event) | |||||
| ui.descriptor->port_event(ui.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| } | |||||
| } | |||||
| // Update external UI | |||||
| if (gui.type == GUI_EXTERNAL_LV2 && ui.widget) | |||||
| LV2_EXTERNAL_UI_RUN((LV2_External_UI_Widget*)ui.widget); | |||||
| } | |||||
| CarlaPlugin::idleGui(); | CarlaPlugin::idleGui(); | ||||
| } | } | ||||
| @@ -1283,6 +1479,8 @@ public: | |||||
| descriptor->connect_port(handle, i, evIn.data[j].atom); | descriptor->connect_port(handle, i, evIn.data[j].atom); | ||||
| if (h2) descriptor->connect_port(h2, i, evIn.data[j].atom); | if (h2) descriptor->connect_port(h2, i, evIn.data[j].atom); | ||||
| evIn.data[j].rindex = i; | |||||
| if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | ||||
| { | { | ||||
| evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | ||||
| @@ -1299,6 +1497,8 @@ public: | |||||
| descriptor->connect_port(handle, i, evOut.data[j].atom); | descriptor->connect_port(handle, i, evOut.data[j].atom); | ||||
| if (h2) descriptor->connect_port(h2, i, evOut.data[j].atom); | if (h2) descriptor->connect_port(h2, i, evOut.data[j].atom); | ||||
| evOut.data[j].rindex = i; | |||||
| if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | ||||
| { | { | ||||
| evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | ||||
| @@ -1320,6 +1520,8 @@ public: | |||||
| descriptor->connect_port(handle, i, evIn.data[j].event); | descriptor->connect_port(handle, i, evIn.data[j].event); | ||||
| if (h2) descriptor->connect_port(h2, i, evIn.data[j].event); | if (h2) descriptor->connect_port(h2, i, evIn.data[j].event); | ||||
| evIn.data[j].rindex = i; | |||||
| if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | ||||
| { | { | ||||
| evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | ||||
| @@ -1332,6 +1534,8 @@ public: | |||||
| descriptor->connect_port(handle, i, evOut.data[j].event); | descriptor->connect_port(handle, i, evOut.data[j].event); | ||||
| if (h2) descriptor->connect_port(h2, i, evOut.data[j].event); | if (h2) descriptor->connect_port(h2, i, evOut.data[j].event); | ||||
| evOut.data[j].rindex = i; | |||||
| if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | if (portType & LV2_PORT_SUPPORTS_MIDI_EVENT) | ||||
| { | { | ||||
| evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | ||||
| @@ -1349,8 +1553,9 @@ public: | |||||
| descriptor->connect_port(handle, i, evIn.data[j].midi); | descriptor->connect_port(handle, i, evIn.data[j].midi); | ||||
| if (h2) descriptor->connect_port(h2, i, evIn.data[j].midi); | if (h2) descriptor->connect_port(h2, i, evIn.data[j].midi); | ||||
| evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | |||||
| evIn.data[j].port = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true); | |||||
| evIn.data[j].type |= CARLA_EVENT_TYPE_MIDI; | |||||
| evIn.data[j].port = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true); | |||||
| evIn.data[j].rindex = i; | |||||
| } | } | ||||
| else if (LV2_IS_PORT_OUTPUT(portType)) | else if (LV2_IS_PORT_OUTPUT(portType)) | ||||
| { | { | ||||
| @@ -1358,8 +1563,9 @@ public: | |||||
| descriptor->connect_port(handle, i, evOut.data[j].midi); | descriptor->connect_port(handle, i, evOut.data[j].midi); | ||||
| if (h2) descriptor->connect_port(h2, i, evOut.data[j].midi); | if (h2) descriptor->connect_port(h2, i, evOut.data[j].midi); | ||||
| evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | |||||
| evOut.data[j].port = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, false); | |||||
| evOut.data[j].type |= CARLA_EVENT_TYPE_MIDI; | |||||
| evOut.data[j].port = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, false); | |||||
| evOut.data[j].rindex = i; | |||||
| } | } | ||||
| else | else | ||||
| qWarning("WARNING - Got a broken Port (Midi, but not input or output)"); | qWarning("WARNING - Got a broken Port (Midi, but not input or output)"); | ||||
| @@ -2225,13 +2431,24 @@ public: | |||||
| } | } | ||||
| #endif | #endif | ||||
| // TODO - get messages from ringbuffer | |||||
| atomQueueIn.lock(); | |||||
| if (! atomQueueIn.isEmpty()) | |||||
| { | |||||
| uint32_t portIndex; | |||||
| LV2_Atom* atom; | |||||
| while (atomQueueIn.get(&portIndex, &atom, false)) | |||||
| { | |||||
| LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); | |||||
| aev->time.frames = framesOffset; | |||||
| aev->body.type = CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT; | |||||
| aev->body.size = atom->size; | |||||
| memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size); | |||||
| } | |||||
| } | |||||
| //LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); | |||||
| //aev->time.frames = framesOffset; | |||||
| //aev->body.type = CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT; | |||||
| //aev->body.size = 0; // message size | |||||
| //memcpy(LV2_ATOM_BODY(&aev->body), nullptr /* message data body */, 0 /* message size */); | |||||
| atomQueueIn.unlock(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -2525,12 +2742,12 @@ public: | |||||
| if (evOut.count > 0 && m_active) | if (evOut.count > 0 && m_active) | ||||
| { | { | ||||
| // ---------------------------------------------------------------------------------------------------- | |||||
| // MIDI Output | |||||
| atomQueueOut.lock(); | |||||
| for (i=0; i < evOut.count; i++) | for (i=0; i < evOut.count; i++) | ||||
| { | { | ||||
| if (! evOut.data[i].port) | |||||
| // midi events need the midi port to send events to | |||||
| if ((evOut.data[i].type & CARLA_EVENT_TYPE_MIDI) > 0 && ! evOut.data[i].port) | |||||
| continue; | continue; | ||||
| if (evOut.data[i].type & CARLA_EVENT_DATA_ATOM) | if (evOut.data[i].type & CARLA_EVENT_DATA_ATOM) | ||||
| @@ -2550,6 +2767,11 @@ public: | |||||
| const unsigned char* const data = (unsigned char*)LV2_ATOM_BODY(&aev->body); | const unsigned char* const data = (unsigned char*)LV2_ATOM_BODY(&aev->body); | ||||
| evOut.data[i].port->writeEvent(aev->time.frames, data, aev->body.size); | evOut.data[i].port->writeEvent(aev->time.frames, data, aev->body.size); | ||||
| } | } | ||||
| else if (aev->body.type == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | |||||
| { | |||||
| if (! atomQueueOut.isFull()) | |||||
| atomQueueOut.put(evOut.data[i].rindex, aev->body); | |||||
| } | |||||
| offset += lv2_atom_pad_size(sizeof(LV2_Atom_Event) + aev->body.size); | offset += lv2_atom_pad_size(sizeof(LV2_Atom_Event) + aev->body.size); | ||||
| } | } | ||||
| @@ -2588,10 +2810,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| // ---------------------------------------------------------------------------------------------------- | |||||
| // Message Output | |||||
| // TODO | |||||
| atomQueueOut.unlock(); | |||||
| } // End of Event Output | } // End of Event Output | ||||
| @@ -2856,20 +3075,18 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void handleTransferAtom(const LV2_Atom* const atom, const char* const stype) | |||||
| void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom) | |||||
| { | { | ||||
| qDebug("Lv2Plugin::handleAtomTransfer(%p, \"%s\")", atom, stype); | |||||
| qDebug("Lv2Plugin::handleAtomTransfer(%i, %p)", portIndex, atom); | |||||
| Q_ASSERT(atom); | Q_ASSERT(atom); | ||||
| Q_ASSERT(stype); | |||||
| // TODO | // TODO | ||||
| } | } | ||||
| void handleTransferEvent(const LV2_Atom* const atom, const char* const stype) | |||||
| void handleTransferEvent(const uint32_t portIndex, const LV2_Atom* const atom) | |||||
| { | { | ||||
| qDebug("Lv2Plugin::handleEventTransfer(%p, \"%s\")", atom, stype); | |||||
| qDebug("Lv2Plugin::handleEventTransfer(%i, %p)", portIndex, atom); | |||||
| Q_ASSERT(atom); | Q_ASSERT(atom); | ||||
| Q_ASSERT(stype); | |||||
| const LV2_URID uridAtomBlank = getCustomURID(LV2_ATOM__Blank); | const LV2_URID uridAtomBlank = getCustomURID(LV2_ATOM__Blank); | ||||
| const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body); | const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body); | ||||
| @@ -2877,7 +3094,7 @@ public: | |||||
| if (atom->type != uridAtomBlank) | if (atom->type != uridAtomBlank) | ||||
| { | { | ||||
| qWarning("Lv2Plugin::handleEventTransfer() - Not blank"); | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - not blank"); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -2885,7 +3102,7 @@ public: | |||||
| if (obj->body.otype != uridPatchSet) | if (obj->body.otype != uridPatchSet) | ||||
| { | { | ||||
| qWarning("Lv2Plugin::handleEventTransfer() - Not Patch Set"); | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - not Patch:Set"); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -2894,12 +3111,14 @@ public: | |||||
| if (! body) | if (! body) | ||||
| { | { | ||||
| qWarning("Lv2Plugin::handleEventTransfer() - Has no body"); | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - has no body"); | |||||
| return; | return; | ||||
| } | } | ||||
| LV2_ATOM_OBJECT_FOREACH(body, iter) | LV2_ATOM_OBJECT_FOREACH(body, iter) | ||||
| { | { | ||||
| atomQueueIn.put(portIndex, iter->value); | |||||
| #if 0 | |||||
| CustomDataType dtype = CUSTOM_DATA_INVALID; | CustomDataType dtype = CUSTOM_DATA_INVALID; | ||||
| const char* const key = getCustomURIString(iter->key); | const char* const key = getCustomURIString(iter->key); | ||||
| const char* value = nullptr; | const char* value = nullptr; | ||||
| @@ -2921,6 +3140,7 @@ public: | |||||
| setCustomData(dtype, key, value, false); | setCustomData(dtype, key, value, false); | ||||
| free((void*)value); | free((void*)value); | ||||
| #endif | |||||
| } | } | ||||
| } | } | ||||
| @@ -3155,20 +3375,20 @@ public: | |||||
| Q_ASSERT(buffer); | Q_ASSERT(buffer); | ||||
| const LV2_Atom* const atom = (const LV2_Atom*)buffer; | const LV2_Atom* const atom = (const LV2_Atom*)buffer; | ||||
| handleTransferAtom(atom, getCustomURIString(atom->type)); | |||||
| handleTransferAtom(rindex, atom); | |||||
| if (ui.handle && ui.descriptor && ui.descriptor->port_event) | |||||
| ui.descriptor->port_event(ui.handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom); | |||||
| //if (ui.handle && ui.descriptor && ui.descriptor->port_event) | |||||
| // ui.descriptor->port_event(ui.handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom); | |||||
| } | } | ||||
| else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | ||||
| { | { | ||||
| Q_ASSERT(buffer); | Q_ASSERT(buffer); | ||||
| const LV2_Atom* const atom = (const LV2_Atom*)buffer; | const LV2_Atom* const atom = (const LV2_Atom*)buffer; | ||||
| handleTransferEvent(atom, getCustomURIString(atom->type)); | |||||
| handleTransferEvent(rindex, atom); | |||||
| if (ui.handle && ui.descriptor && ui.descriptor->port_event) | |||||
| ui.descriptor->port_event(ui.handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| //if (ui.handle && ui.descriptor && ui.descriptor->port_event) | |||||
| // ui.descriptor->port_event(ui.handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| } | } | ||||
| } | } | ||||
| @@ -4343,6 +4563,8 @@ private: | |||||
| } suil; | } suil; | ||||
| #endif | #endif | ||||
| Lv2AtomQueue atomQueueIn; | |||||
| Lv2AtomQueue atomQueueOut; | |||||
| Lv2PluginEventData evIn; | Lv2PluginEventData evIn; | ||||
| Lv2PluginEventData evOut; | Lv2PluginEventData evOut; | ||||
| float* paramBuffers; | float* paramBuffers; | ||||
| @@ -4404,16 +4626,17 @@ int CarlaOsc::handle_lv2_atom_transfer(CARLA_OSC_HANDLE_ARGS2) | |||||
| qDebug("CarlaOsc::handle_lv2_atom_transfer()"); | qDebug("CarlaOsc::handle_lv2_atom_transfer()"); | ||||
| CARLA_OSC_CHECK_OSC_TYPES(2, "ss"); | 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; | |||||
| //const char* const type = (const char*)&argv[0]->s; | |||||
| //const char* const value = (const char*)&argv[1]->s; | |||||
| //QByteArray chunk; | |||||
| //chunk = QByteArray::fromBase64(value); | |||||
| QByteArray chunk; | |||||
| chunk = QByteArray::fromBase64(value); | |||||
| //const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); | |||||
| const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); | |||||
| //CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
| //lv2plugin->handleTransferAtom(atom, type); | |||||
| CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
| lv2plugin->handleTransferAtom(atom, type); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -4423,16 +4646,16 @@ int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2) | |||||
| qDebug("CarlaOsc::handle_lv2_event_transfer()"); | qDebug("CarlaOsc::handle_lv2_event_transfer()"); | ||||
| CARLA_OSC_CHECK_OSC_TYPES(2, "ss"); | CARLA_OSC_CHECK_OSC_TYPES(2, "ss"); | ||||
| const char* const type = (const char*)&argv[0]->s; | |||||
| const char* const value = (const char*)&argv[1]->s; | |||||
| //const char* const type = (const char*)&argv[0]->s; | |||||
| //const char* const value = (const char*)&argv[1]->s; | |||||
| QByteArray chunk; | |||||
| chunk = QByteArray::fromBase64(value); | |||||
| //QByteArray chunk; | |||||
| //chunk = QByteArray::fromBase64(value); | |||||
| const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); | |||||
| //const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); | |||||
| CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
| lv2plugin->handleTransferEvent(atom, type); | |||||
| //CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; | |||||
| //lv2plugin->handleTransferEvent(atom, type); | |||||
| return 0; | return 0; | ||||
| } | } | ||||