From 1fa2cb920677b77c459cf4f2ecebd9b0bb9a4bf2 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 31 Aug 2012 14:32:54 +0100 Subject: [PATCH] Carla cleanup, fix lv2 plugin close --- c++/carla-backend/carla_bridge.cpp | 2 +- c++/carla-backend/carla_engine.cpp | 2 +- c++/carla-backend/carla_engine.h | 2 +- c++/carla-backend/dssi.cpp | 2 +- c++/carla-backend/fluidsynth.cpp | 2 +- c++/carla-backend/ladspa.cpp | 2 +- c++/carla-backend/linuxsampler.cpp | 2 +- c++/carla-backend/lv2.cpp | 173 ++++++++++++++++++----------- c++/carla-backend/vst.cpp | 3 +- 9 files changed, 117 insertions(+), 73 deletions(-) diff --git a/c++/carla-backend/carla_bridge.cpp b/c++/carla-backend/carla_bridge.cpp index 9bb3187..4e2a804 100644 --- a/c++/carla-backend/carla_bridge.cpp +++ b/c++/carla-backend/carla_bridge.cpp @@ -705,7 +705,7 @@ CarlaPlugin* CarlaPlugin::newBridge(const initializer& init, BinaryType btype, P short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; diff --git a/c++/carla-backend/carla_engine.cpp b/c++/carla-backend/carla_engine.cpp index d171204..32c0608 100644 --- a/c++/carla-backend/carla_engine.cpp +++ b/c++/carla-backend/carla_engine.cpp @@ -1042,7 +1042,7 @@ const CarlaEngineMidiEvent* CarlaEngineMidiPort::getEvent(uint32_t index) return nullptr; } -void CarlaEngineMidiPort::writeEvent(uint32_t time, uint8_t* data, uint8_t size) +void CarlaEngineMidiPort::writeEvent(uint32_t time, const uint8_t* data, uint8_t size) { if (isInput) return; diff --git a/c++/carla-backend/carla_engine.h b/c++/carla-backend/carla_engine.h index bc4ff95..4b30fda 100644 --- a/c++/carla-backend/carla_engine.h +++ b/c++/carla-backend/carla_engine.h @@ -437,7 +437,7 @@ public: uint32_t getEventCount(); const CarlaEngineMidiEvent* getEvent(uint32_t index); - void writeEvent(uint32_t time, uint8_t* data, uint8_t size); + void writeEvent(uint32_t time, const uint8_t* data, uint8_t size); }; // ----------------------------------------------------------------------- diff --git a/c++/carla-backend/dssi.cpp b/c++/carla-backend/dssi.cpp index f9dbbf1..adbfe4b 100644 --- a/c++/carla-backend/dssi.cpp +++ b/c++/carla-backend/dssi.cpp @@ -1505,7 +1505,7 @@ CarlaPlugin* CarlaPlugin::newDSSI(const initializer& init, const void* const ext short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; diff --git a/c++/carla-backend/fluidsynth.cpp b/c++/carla-backend/fluidsynth.cpp index 616dda6..5194295 100644 --- a/c++/carla-backend/fluidsynth.cpp +++ b/c++/carla-backend/fluidsynth.cpp @@ -1286,7 +1286,7 @@ CarlaPlugin* CarlaPlugin::newSF2(const initializer& init) #ifdef WANT_FLUIDSYNTH short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; diff --git a/c++/carla-backend/ladspa.cpp b/c++/carla-backend/ladspa.cpp index c723a7b..575231b 100644 --- a/c++/carla-backend/ladspa.cpp +++ b/c++/carla-backend/ladspa.cpp @@ -1126,7 +1126,7 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const initializer& init, const void* const e short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; diff --git a/c++/carla-backend/linuxsampler.cpp b/c++/carla-backend/linuxsampler.cpp index c0fba49..38e055d 100644 --- a/c++/carla-backend/linuxsampler.cpp +++ b/c++/carla-backend/linuxsampler.cpp @@ -579,7 +579,7 @@ CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const initializer& init, bool i short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; diff --git a/c++/carla-backend/lv2.cpp b/c++/carla-backend/lv2.cpp index 2536bde..1f20380 100644 --- a/c++/carla-backend/lv2.cpp +++ b/c++/carla-backend/lv2.cpp @@ -359,17 +359,14 @@ public: if (features[lv2_feature_id_ui_resize] && features[lv2_feature_id_ui_resize]->data) delete (LV2UI_Resize*)features[lv2_feature_id_ui_resize]->data; - if (features[lv2_feature_id_external_ui]) + if (features[lv2_feature_id_external_ui] && features[lv2_feature_id_external_ui]->data) { const lv2_external_ui_host* const uiHost = (const lv2_external_ui_host*)features[lv2_feature_id_external_ui]->data; - if (uiHost) - { - if (uiHost->plugin_human_id) - free((void*)uiHost->plugin_human_id); + if (uiHost->plugin_human_id) + free((void*)uiHost->plugin_human_id); - delete uiHost; - } + delete uiHost; } uiLibClose(); @@ -430,6 +427,14 @@ public: if (features[lv2_feature_id_worker] && features[lv2_feature_id_worker]->data) delete (LV2_Worker_Schedule*)features[lv2_feature_id_worker]->data; +#ifndef BUILD_BRIDGE + if (! carlaOptions.processHighPrecision) +#endif + { + features[lv2_feature_id_bufsize_fixed] = nullptr; + features[lv2_feature_id_bufsize_powerof2] = nullptr; + } + for (uint32_t i=0; i < lv2_feature_count; i++) { if (features[i]) @@ -1765,15 +1770,15 @@ public: double aOutsPeak[2] = { 0.0 }; // handle midi from different APIs - uint32_t evinAtomOffsets[evIn.count]; - LV2_Event_Iterator evinEventIters[evIn.count]; - LV2_MIDIState evinMidiStates[evIn.count]; + uint32_t evInAtomOffsets[evIn.count]; + LV2_Event_Iterator evInEventIters[evIn.count]; + LV2_MIDIState evInMidiStates[evIn.count]; for (i=0; i < evIn.count; i++) { if (evIn.data[i].type & CARLA_EVENT_DATA_ATOM) { - evinAtomOffsets[i] = 0; + evInAtomOffsets[i] = 0; evIn.data[i].atom->atom.size = 0; evIn.data[i].atom->atom.type = CARLA_URI_MAP_ID_ATOM_SEQUENCE; evIn.data[i].atom->body.unit = CARLA_URI_MAP_ID_NULL; @@ -1782,15 +1787,15 @@ public: else if (evIn.data[i].type & CARLA_EVENT_DATA_EVENT) { lv2_event_buffer_reset(evIn.data[i].event, LV2_EVENT_AUDIO_STAMP, (uint8_t*)(evIn.data[i].event + 1)); - lv2_event_begin(&evinEventIters[i], evIn.data[i].event); + lv2_event_begin(&evInEventIters[i], evIn.data[i].event); } else if (evIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) { - evinMidiStates[i].midi = evIn.data[i].midi; - evinMidiStates[i].frame_count = frames; - evinMidiStates[i].position = 0; - evinMidiStates[i].midi->event_count = 0; - evinMidiStates[i].midi->size = 0; + evInMidiStates[i].midi = evIn.data[i].midi; + evInMidiStates[i].frame_count = frames; + evInMidiStates[i].position = 0; + evInMidiStates[i].midi->event_count = 0; + evInMidiStates[i].midi->size = 0; } } @@ -2049,23 +2054,23 @@ public: { if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) { - LV2_Atom_Event* const aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evinAtomOffsets[k]); + LV2_Atom_Event* const aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evInAtomOffsets[k]); aev->time.frames = 0; aev->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; aev->body.size = 3; memcpy(LV2_ATOM_BODY(&aev->body), midiEvent, 3); const uint32_t padSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + 3); - evinAtomOffsets[k] += padSize; + evInAtomOffsets[k] += padSize; evIn.data[k].atom->atom.size += padSize; } else if (evIn.data[k].type & CARLA_EVENT_DATA_EVENT) { - lv2_event_write(&evinEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiEvent); + lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiEvent); } else if (evIn.data[k].type & CARLA_EVENT_DATA_MIDI_LL) { - lv2midi_put_event(&evinMidiStates[k], 0, 3, midiEvent); + lv2midi_put_event(&evInMidiStates[k], 0, 3, midiEvent); } } } @@ -2116,23 +2121,23 @@ public: { if (evIn.data[i].type & CARLA_EVENT_DATA_ATOM) { - LV2_Atom_Event* const aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[i].atom) + evinAtomOffsets[i]); + LV2_Atom_Event* const aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[i].atom) + evInAtomOffsets[i]); aev->time.frames = time; aev->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; aev->body.size = minEvent->size; memcpy(LV2_ATOM_BODY(&aev->body), minEvent->data, minEvent->size); const uint32_t padSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + minEvent->size); - evinAtomOffsets[i] += padSize; + evInAtomOffsets[i] += padSize; evIn.data[i].atom->atom.size += padSize; } else if (evIn.data[i].type & CARLA_EVENT_DATA_EVENT) { - lv2_event_write(&evinEventIters[i], time, 0, CARLA_URI_MAP_ID_MIDI_EVENT, minEvent->size, minEvent->data); + lv2_event_write(&evInEventIters[i], time, 0, CARLA_URI_MAP_ID_MIDI_EVENT, minEvent->size, minEvent->data); } else if (evIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) { - lv2midi_put_event(&evinMidiStates[i], time, minEvent->size, minEvent->data); + lv2midi_put_event(&evInMidiStates[i], time, minEvent->size, minEvent->data); } if (MIDI_IS_STATUS_NOTE_OFF(status)) @@ -2242,35 +2247,35 @@ public: if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) { // 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 = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evInAtomOffsets[k]); aev1->time.frames = 0; aev1->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; aev1->body.size = 2; memcpy(LV2_ATOM_BODY(&aev1->body), midiEvent1, 2); const uint32_t padSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + 2); - evinAtomOffsets[k] += padSize; + evInAtomOffsets[k] += padSize; evIn.data[k].atom->atom.size += padSize; // 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 = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evIn.data[k].atom) + evInAtomOffsets[k]); aev2->time.frames = 0; aev2->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; aev2->body.size = 2; memcpy(LV2_ATOM_BODY(&aev2->body), midiEvent2, 2); - evinAtomOffsets[k] += padSize; + evInAtomOffsets[k] += padSize; evIn.data[k].atom->atom.size += padSize; } else if (evIn.data[k].type & CARLA_EVENT_DATA_EVENT) { - lv2_event_write(&evinEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent1); - lv2_event_write(&evinEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent2); + lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent1); + lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent2); } else if (evIn.data[k].type & CARLA_EVENT_DATA_MIDI_LL) { - lv2midi_put_event(&evinMidiStates[k], 0, 2, midiEvent1); - lv2midi_put_event(&evinMidiStates[k], 0, 2, midiEvent2); + lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent1); + lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent2); } } } @@ -2299,6 +2304,18 @@ public: descriptor->run(handle, frames); if (h2) descriptor->run(h2, frames); + + if (ext.worker) + { + // TODO + //ext.worker->work_response(); + + if (ext.worker->end_run) + { + ext.worker->end_run(handle); + if (h2) ext.worker->end_run(h2); + } + } } else { @@ -2430,11 +2447,28 @@ public: if (! evOut.data[i].port) continue; - if (evIn.data[i].type & CARLA_EVENT_DATA_ATOM) + if (evOut.data[i].type & CARLA_EVENT_DATA_ATOM) { - // TODO + uint32_t size = evOut.data[i].atom->atom.size - sizeof(LV2_Atom_Sequence_Body); + uint32_t offset = 0; + + while (offset < size) + { + const LV2_Atom_Event* const aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, evOut.data[i].atom) + offset); + + if ((! aev) || aev->body.type == CARLA_URI_MAP_ID_NULL) + break; + + if (aev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT) + { + const unsigned char* const data = (unsigned char*)LV2_ATOM_BODY(&aev->body); + evOut.data[i].port->writeEvent(aev->time.frames, data, aev->body.size); + } + + offset += lv2_atom_pad_size(sizeof(LV2_Atom_Event) + aev->body.size); + } } - else if (evIn.data[i].type & CARLA_EVENT_DATA_EVENT) + else if (evOut.data[i].type & CARLA_EVENT_DATA_EVENT) { const LV2_Event* ev; LV2_Event_Iterator iter; @@ -2446,13 +2480,13 @@ public: { ev = lv2_event_get(&iter, &data); - if (ev && data) + if (ev && ev->type == CARLA_URI_MAP_ID_MIDI_EVENT && data) evOut.data[i].port->writeEvent(ev->frames, data, ev->size); lv2_event_increment(&iter); } } - else if (evIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) + else if (evOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL) { LV2_MIDIState state = { evOut.data[i].midi, frames, 0 }; @@ -2730,22 +2764,21 @@ public: // ------------------------------------------------------------------- - void handleTransferAtom() + void handleTransferAtom(const LV2_Atom* const atom, const char* const stype) { + qDebug("Lv2Plugin::handleAtomTransfer(%p, \"%s\")", atom, stype); + Q_ASSERT(atom); + Q_ASSERT(stype); + // TODO } - void handleTransferEvent(const char* const type, const char* const key, const char* const stringData) + void handleTransferEvent(const LV2_Atom* const atom, const char* const stype) { - qDebug("Lv2Plugin::handleEventTransfer(%s, %s, %s)", type, key, stringData); - Q_ASSERT(type); - Q_ASSERT(key); - Q_ASSERT(stringData); + qDebug("Lv2Plugin::handleEventTransfer(%p, \"%s\")", atom, stype); + Q_ASSERT(atom); + Q_ASSERT(stype); - QByteArray chunk; - chunk = QByteArray::fromBase64(stringData); - - const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); const LV2_URID uridAtomBlank = getCustomURID(LV2_ATOM__Blank); const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body); const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set); @@ -2788,7 +2821,7 @@ public: { 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 a custom type + 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(""); @@ -3029,7 +3062,8 @@ public: { Q_ASSERT(buffer); - const LV2_Atom* const atom = (LV2_Atom*)buffer; + const LV2_Atom* const atom = (const LV2_Atom*)buffer; + handleTransferAtom(atom, getCustomURIString(atom->type)); 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); @@ -3038,7 +3072,8 @@ public: { Q_ASSERT(buffer); - const LV2_Atom* const atom = (LV2_Atom*)buffer; + const LV2_Atom* const atom = (const LV2_Atom*)buffer; + handleTransferEvent(atom, getCustomURIString(atom->type)); 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); @@ -3118,8 +3153,8 @@ public: 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 }; + Sratom* const sratom = sratom_new(URID_Map); + SerdChunk chunk = { nullptr, 0 }; LV2_Atom_Forge forge; lv2_atom_forge_init(&forge, URID_Map); @@ -3738,6 +3773,7 @@ public: features[lv2_feature_id_bufsize_bounded]->URI = LV2_BUF_SIZE__boundedBlockLength; features[lv2_feature_id_bufsize_bounded]->data = nullptr; +#ifndef BUILD_BRIDGE if (carlaOptions.processHighPrecision) { features[lv2_feature_id_bufsize_fixed] = new LV2_Feature; @@ -3749,6 +3785,7 @@ public: features[lv2_feature_id_bufsize_powerof2]->data = nullptr; } else +#endif { // fake, used to keep a valid array features[lv2_feature_id_bufsize_fixed] = features[lv2_feature_id_bufsize_bounded]; @@ -4185,7 +4222,6 @@ private: } ext; struct { - void* lib; LV2UI_Handle handle; LV2UI_Widget widget; @@ -4220,7 +4256,7 @@ CarlaPlugin* CarlaPlugin::newLV2(const initializer& init) short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; @@ -4264,28 +4300,37 @@ 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, "ii"); + 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; + + QByteArray chunk; + chunk = QByteArray::fromBase64(value); + + const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; - lv2plugin->handleTransferAtom(); + lv2plugin->handleTransferAtom(atom, type); return 0; - Q_UNUSED(argc); - Q_UNUSED(argv); - Q_UNUSED(types); } int CarlaOsc::handle_lv2_event_transfer(CARLA_OSC_HANDLE_ARGS2) { qDebug("CarlaOsc::handle_lv2_event_transfer()"); - CARLA_OSC_CHECK_OSC_TYPES(3, "sss"); + CARLA_OSC_CHECK_OSC_TYPES(2, "ss"); const char* const type = (const char*)&argv[0]->s; - const char* const key = (const char*)&argv[1]->s; - const char* const value = (const char*)&argv[2]->s; + const char* const value = (const char*)&argv[1]->s; + + QByteArray chunk; + chunk = QByteArray::fromBase64(value); + + const LV2_Atom* const atom = (LV2_Atom*)chunk.constData(); CarlaBackend::Lv2Plugin* const lv2plugin = (CarlaBackend::Lv2Plugin*)plugin; - lv2plugin->handleTransferEvent(type, key, value); + lv2plugin->handleTransferEvent(atom, type); return 0; } diff --git a/c++/carla-backend/vst.cpp b/c++/carla-backend/vst.cpp index 70a00e6..54bb23c 100644 --- a/c++/carla-backend/vst.cpp +++ b/c++/carla-backend/vst.cpp @@ -1792,7 +1792,7 @@ CarlaPlugin* CarlaPlugin::newVST(const initializer& init) short id = init.engine->getNewPluginId(); - if (id < 0) + if (id < 0 || id > MAX_PLUGINS) { setLastError("Maximum number of plugins reached"); return nullptr; @@ -1823,7 +1823,6 @@ CarlaPlugin* CarlaPlugin::newVST(const initializer& init) delete plugin; return nullptr; } - } #endif