| @@ -268,13 +268,13 @@ public: | |||||
| mutex.unlock(); | mutex.unlock(); | ||||
| } | } | ||||
| void put(const uint32_t portIndex, const LV2_Atom& atom, const bool lock = true) | |||||
| void put(const uint32_t portIndex, const LV2_Atom* const 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 | |||||
| qDebug("Lv2AtomQueue::put(%i, %p, %s)", portIndex, atom, 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) | |||||
| if (full || atom->size == 0 || indexPool + atom->size >= MAX_POOL_SIZE) | |||||
| return; | return; | ||||
| if (lock) | if (lock) | ||||
| @@ -285,12 +285,13 @@ public: | |||||
| if (data[i].size == 0) | if (data[i].size == 0) | ||||
| { | { | ||||
| data[i].portIndex = portIndex; | data[i].portIndex = portIndex; | ||||
| data[i].size = atom.size; | |||||
| data[i].size = atom->size; | |||||
| data[i].type = atom->type; | |||||
| data[i].poolOffset = indexPool; | data[i].poolOffset = indexPool; | ||||
| memcpy(dataPool + indexPool, (const unsigned char*)LV2_ATOM_BODY_CONST(&atom), atom.size); | |||||
| memcpy(dataPool + indexPool, (const unsigned char*)LV2_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; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -299,7 +300,7 @@ public: | |||||
| mutex.unlock(); | mutex.unlock(); | ||||
| } | } | ||||
| bool get(uint32_t* const portIndex, LV2_Atom** const atom, const bool lock = true) | |||||
| 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)); | qDebug("Lv2AtomQueue::get(%p, %p, %s)", portIndex, atom, bool2str(lock)); | ||||
| Q_ASSERT(portIndex && atom); | Q_ASSERT(portIndex && atom); | ||||
| @@ -323,21 +324,16 @@ public: | |||||
| return false; | 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; | |||||
| 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; | *portIndex = data[index].portIndex; | ||||
| *atom = (LV2_Atom*)&thisAtom; | |||||
| *atom = (LV2_Atom*)&retAtom; | |||||
| data[index].portIndex = 0; | data[index].portIndex = 0; | ||||
| data[index].size = 0; | data[index].size = 0; | ||||
| data[index].type = 0; | |||||
| data[index].type = CARLA_URI_MAP_ID_NULL; | |||||
| data[index].poolOffset = 0; | data[index].poolOffset = 0; | ||||
| index++; | index++; | ||||
| empty = false; | empty = false; | ||||
| @@ -362,12 +358,17 @@ private: | |||||
| poolOffset(0) {} | poolOffset(0) {} | ||||
| }; | }; | ||||
| static const unsigned short MAX_SIZE = 32; | |||||
| static const unsigned short MAX_SIZE = 128; | |||||
| static const unsigned short MAX_POOL_SIZE = 8192; | static const unsigned short MAX_POOL_SIZE = 8192; | ||||
| datatype data[MAX_SIZE]; | datatype data[MAX_SIZE]; | ||||
| unsigned char dataPool[MAX_POOL_SIZE]; | unsigned char dataPool[MAX_POOL_SIZE]; | ||||
| struct { | |||||
| LV2_Atom atom; | |||||
| unsigned char data[MAX_POOL_SIZE]; | |||||
| } retAtom; | |||||
| unsigned short index; | unsigned short index; | ||||
| uint32_t indexPool; | uint32_t indexPool; | ||||
| bool empty, full; | bool empty, full; | ||||
| @@ -1194,24 +1195,28 @@ public: | |||||
| if (haveUI) | if (haveUI) | ||||
| { | { | ||||
| // Update event ports | // Update event ports | ||||
| static Lv2AtomQueue queue; | |||||
| queue.copyDataFrom(&atomQueueOut); | |||||
| if (! atomQueueIn.isEmpty()) | |||||
| { | |||||
| static Lv2AtomQueue queue; | |||||
| queue.copyDataFrom(&atomQueueOut); | |||||
| uint32_t portIndex; | |||||
| LV2_Atom* atom; | |||||
| uint32_t portIndex; | |||||
| const LV2_Atom* atom; | |||||
| while (atomQueueIn.get(&portIndex, &atom, false)) | |||||
| { | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (gui.type == GUI_EXTERNAL_OSC) | |||||
| while (queue.get(&portIndex, &atom, false)) | |||||
| { | { | ||||
| qDebug("idle Got atom, size: %i, content: %s", atom->size, (char*)LV2_ATOM_BODY(atom)); | |||||
| #ifndef BUILD_BRIDGE | |||||
| if (gui.type == GUI_EXTERNAL_OSC) | |||||
| { | |||||
| osc_send_lv2_transfer_event(&osc.data, nullptr, nullptr); | osc_send_lv2_transfer_event(&osc.data, nullptr, nullptr); | ||||
| } | |||||
| else | |||||
| } | |||||
| else | |||||
| #endif | #endif | ||||
| { | |||||
| if (ui.descriptor->port_event) | |||||
| ui.descriptor->port_event(ui.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| { | |||||
| if (ui.descriptor->port_event) | |||||
| ui.descriptor->port_event(ui.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -2438,15 +2443,21 @@ public: | |||||
| if (! atomQueueIn.isEmpty()) | if (! atomQueueIn.isEmpty()) | ||||
| { | { | ||||
| uint32_t portIndex; | uint32_t portIndex; | ||||
| LV2_Atom* atom; | |||||
| const LV2_Atom* atom; | |||||
| while (atomQueueIn.get(&portIndex, &atom, false)) | while (atomQueueIn.get(&portIndex, &atom, false)) | ||||
| { | { | ||||
| qDebug("proc, in, send, Got atom, size: %i, content: %s", atom->size, (unsigned char*)LV2_ATOM_BODY(atom)); | |||||
| LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); | LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); | ||||
| aev->time.frames = framesOffset; | aev->time.frames = framesOffset; | ||||
| aev->body.type = CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT; | |||||
| aev->body.type = atom->type; | |||||
| aev->body.size = atom->size; | aev->body.size = atom->size; | ||||
| memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size); | memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size); | ||||
| const uint32_t evInPadSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + atom->size); | |||||
| evInAtomOffsets[i] += evInPadSize; | |||||
| evIn.data[i].atom->atom.size += evInPadSize; | |||||
| } | } | ||||
| } | } | ||||
| @@ -2551,7 +2562,7 @@ public: | |||||
| if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) | if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) | ||||
| { | { | ||||
| // all sound off | // all sound off | ||||
| LV2_Atom_Event* const aev1 = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evInAtomOffsets[k]); | |||||
| LV2_Atom_Event* const aev1 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||||
| aev1->time.frames = 0; | aev1->time.frames = 0; | ||||
| aev1->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | aev1->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | ||||
| aev1->body.size = 2; | aev1->body.size = 2; | ||||
| @@ -2562,7 +2573,7 @@ public: | |||||
| evIn.data[k].atom->atom.size += padSize; | evIn.data[k].atom->atom.size += padSize; | ||||
| // all notes off | // all notes off | ||||
| LV2_Atom_Event* const aev2 = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evInAtomOffsets[k]); | |||||
| LV2_Atom_Event* const aev2 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||||
| aev2->time.frames = 0; | aev2->time.frames = 0; | ||||
| aev2->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | aev2->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | ||||
| aev2->body.size = 2; | aev2->body.size = 2; | ||||
| @@ -2772,7 +2783,7 @@ public: | |||||
| else if (aev->body.type == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | else if (aev->body.type == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT) | ||||
| { | { | ||||
| if (! atomQueueOut.isFull()) | if (! atomQueueOut.isFull()) | ||||
| atomQueueOut.put(evOut.data[i].rindex, aev->body); | |||||
| 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); | ||||
| @@ -3082,7 +3093,8 @@ public: | |||||
| qDebug("Lv2Plugin::handleAtomTransfer(%i, %p)", portIndex, atom); | qDebug("Lv2Plugin::handleAtomTransfer(%i, %p)", portIndex, atom); | ||||
| Q_ASSERT(atom); | Q_ASSERT(atom); | ||||
| // TODO | |||||
| // FIXME - is this correct? | |||||
| //atomQueueIn.put(portIndex, atom->type, atom); | |||||
| } | } | ||||
| void handleTransferEvent(const uint32_t portIndex, const LV2_Atom* const atom) | void handleTransferEvent(const uint32_t portIndex, const LV2_Atom* const atom) | ||||
| @@ -3090,60 +3102,7 @@ public: | |||||
| qDebug("Lv2Plugin::handleEventTransfer(%i, %p)", portIndex, atom); | qDebug("Lv2Plugin::handleEventTransfer(%i, %p)", portIndex, atom); | ||||
| Q_ASSERT(atom); | Q_ASSERT(atom); | ||||
| const LV2_URID uridAtomBlank = getCustomURID(LV2_ATOM__Blank); | |||||
| const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body); | |||||
| const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set); | |||||
| if (atom->type != uridAtomBlank) | |||||
| { | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - not blank"); | |||||
| return; | |||||
| } | |||||
| const LV2_Atom_Object* const obj = (LV2_Atom_Object*)atom; | |||||
| if (obj->body.otype != uridPatchSet) | |||||
| { | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - not Patch:Set"); | |||||
| return; | |||||
| } | |||||
| const LV2_Atom_Object* body = nullptr; | |||||
| lv2_atom_object_get(obj, uridPatchBody, &body, 0); | |||||
| if (! body) | |||||
| { | |||||
| qWarning("Lv2Plugin::handleEventTransfer() - has no body"); | |||||
| return; | |||||
| } | |||||
| LV2_ATOM_OBJECT_FOREACH(body, iter) | |||||
| { | |||||
| atomQueueIn.put(portIndex, iter->value); | |||||
| #if 0 | |||||
| CustomDataType dtype = CUSTOM_DATA_INVALID; | |||||
| const char* const key = getCustomURIString(iter->key); | |||||
| const char* value = nullptr; | |||||
| if (iter->value.type == CARLA_URI_MAP_ID_ATOM_STRING || iter->value.type == CARLA_URI_MAP_ID_ATOM_PATH) | |||||
| { | |||||
| value = strdup((const char*)LV2_ATOM_BODY(&iter->value)); | |||||
| dtype = (iter->value.type == CARLA_URI_MAP_ID_ATOM_STRING) ? CUSTOM_DATA_STRING : CUSTOM_DATA_PATH; | |||||
| } | |||||
| else if (iter->value.type == CARLA_URI_MAP_ID_ATOM_CHUNK || iter->value.type >= CARLA_URI_MAP_ID_COUNT) | |||||
| { | |||||
| QByteArray chunk((const char*)LV2_ATOM_BODY(&iter->value), iter->value.size); | |||||
| value = strdup(chunk.toBase64().constData()); | |||||
| dtype = (iter->value.type == CARLA_URI_MAP_ID_ATOM_CHUNK) ? CUSTOM_DATA_CHUNK : CUSTOM_DATA_BINARY; // FIXME - binary should be custom stype | |||||
| } | |||||
| else | |||||
| value = strdup(""); | |||||
| setCustomData(dtype, key, value, false); | |||||
| free((void*)value); | |||||
| #endif | |||||
| } | |||||
| atomQueueIn.put(portIndex, atom); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -3494,8 +3453,10 @@ public: | |||||
| lv2_atom_forge_pop(&forge, &bodyFrame); | lv2_atom_forge_pop(&forge, &bodyFrame); | ||||
| lv2_atom_forge_pop(&forge, &refFrame); | lv2_atom_forge_pop(&forge, &refFrame); | ||||
| uint32_t portIndex = evIn.count > 0 ? evIn.data[0].rindex : 0; | |||||
| const LV2_Atom* const atom = lv2_atom_forge_deref(&forge, ref); | const LV2_Atom* const atom = lv2_atom_forge_deref(&forge, ref); | ||||
| ui.descriptor->port_event(ui.handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| ui.descriptor->port_event(ui.handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom); | |||||
| free((void*)chunk.buf); | free((void*)chunk.buf); | ||||
| sratom_free(sratom); | sratom_free(sratom); | ||||
| @@ -3524,11 +3485,11 @@ public: | |||||
| if (ui.descriptor->port_event) | if (ui.descriptor->port_event) | ||||
| { | { | ||||
| // get&store custom data to be sent to the UI | // get&store custom data to be sent to the UI | ||||
| prepareForSave(); | |||||
| //prepareForSave(); | |||||
| // update state (custom data) | // update state (custom data) | ||||
| for (size_t i=0; i < custom.size(); i++) | |||||
| uiTransferEvent(&custom[i]); | |||||
| //for (size_t i=0; i < custom.size(); i++) | |||||
| // uiTransferEvent(&custom[i]); | |||||
| // update control ports | // update control ports | ||||
| float valueF; | float valueF; | ||||
| @@ -4192,6 +4153,8 @@ public: | |||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // gui stuff | // gui stuff | ||||
| qDebug("LV2 UI ----------------------------------------------------- 001"); | |||||
| if (rdf_descriptor->UICount == 0) | if (rdf_descriptor->UICount == 0) | ||||
| return true; | return true; | ||||
| @@ -4201,6 +4164,7 @@ public: | |||||
| int eQt4, eCocoa, eHWND, eX11, eGtk2, eGtk3, iCocoa, iHWND, iX11, iQt4, iExt, iSuil, iFinal; | int eQt4, eCocoa, eHWND, eX11, eGtk2, eGtk3, iCocoa, iHWND, iX11, iQt4, iExt, iSuil, iFinal; | ||||
| eQt4 = eCocoa = eHWND = eX11 = eGtk2 = eGtk3 = iQt4 = iCocoa = iHWND = iX11 = iExt = iSuil = iFinal = -1; | eQt4 = eCocoa = eHWND = eX11 = eGtk2 = eGtk3 = iQt4 = iCocoa = iHWND = iX11 = iExt = iSuil = iFinal = -1; | ||||
| qDebug("LV2 UI ----------------------------------------------------- 002"); | |||||
| for (i=0; i < rdf_descriptor->UICount; i++) | for (i=0; i < rdf_descriptor->UICount; i++) | ||||
| { | { | ||||
| switch (rdf_descriptor->UIs[i].Type) | switch (rdf_descriptor->UIs[i].Type) | ||||
| @@ -4307,6 +4271,7 @@ public: | |||||
| qWarning("Failed to find an appropriate LV2 UI for this plugin"); | qWarning("Failed to find an appropriate LV2 UI for this plugin"); | ||||
| return true; | return true; | ||||
| } | } | ||||
| qDebug("LV2 UI ----------------------------------------------------- 003"); | |||||
| ui.rdf_descriptor = &rdf_descriptor->UIs[iFinal]; | ui.rdf_descriptor = &rdf_descriptor->UIs[iFinal]; | ||||
| @@ -4330,12 +4295,14 @@ public: | |||||
| ui.rdf_descriptor = nullptr; | ui.rdf_descriptor = nullptr; | ||||
| return true; | return true; | ||||
| } | } | ||||
| qDebug("LV2 UI ----------------------------------------------------- 004"); | |||||
| #ifdef HAVE_SUIL | #ifdef HAVE_SUIL | ||||
| if (isSuil) | if (isSuil) | ||||
| { | { | ||||
| // ------------------------------------------------------- | // ------------------------------------------------------- | ||||
| // init suil host | // init suil host | ||||
| qDebug("LV2 UI ----------------------------------------------------- 005a"); | |||||
| suil.host = suil_host_new(carla_lv2_ui_write_function, carla_lv2_ui_port_map, nullptr, nullptr); | suil.host = suil_host_new(carla_lv2_ui_write_function, carla_lv2_ui_port_map, nullptr, nullptr); | ||||
| } | } | ||||
| @@ -4344,6 +4311,7 @@ public: | |||||
| { | { | ||||
| // ------------------------------------------------------- | // ------------------------------------------------------- | ||||
| // open DLL | // open DLL | ||||
| qDebug("LV2 UI ----------------------------------------------------- 005b"); | |||||
| if (! uiLibOpen(ui.rdf_descriptor->Binary)) | if (! uiLibOpen(ui.rdf_descriptor->Binary)) | ||||
| { | { | ||||
| @@ -4386,6 +4354,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| qDebug("LV2 UI ----------------------------------------------------- 006"); | |||||
| // ----------------------------------------------------------- | // ----------------------------------------------------------- | ||||
| // initialize ui according to type | // initialize ui according to type | ||||
| @@ -4407,6 +4376,7 @@ public: | |||||
| else | else | ||||
| #endif | #endif | ||||
| { | { | ||||
| qDebug("LV2 UI ----------------------------------------------------- 007b"); | |||||
| // ------------------------------------------------------- | // ------------------------------------------------------- | ||||
| // initialize ui features | // initialize ui features | ||||