From b3d63cc99b2382eb7d972305a1eb21d4e516f02c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 18 Nov 2012 01:30:53 +0000 Subject: [PATCH] Better implementation of LV2 plugin<=>UI communication. This might use a bit more memory than it could, but it works reliably for me loading a large Ingen patch inside Ardour as an LV2 plugin, which I'm pretty sure is by far the most high volume such communication out there. git-svn-id: svn://localhost/ardour2/branches/3.0@13519 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/lv2_plugin.h | 6 +++--- libs/ardour/lv2_plugin.cc | 37 +++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index a4b89a5841..51fa5a2987 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -122,7 +122,7 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee bool has_editor () const; bool has_message_output () const; - void write_from_ui(uint32_t index, + bool write_from_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t* body); @@ -211,12 +211,12 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee uint32_t size; }; - void write_to_ui(uint32_t index, + bool write_to_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t* body); - void write_to(RingBuffer* dest, + bool write_to(RingBuffer* dest, uint32_t index, uint32_t protocol, uint32_t size, diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 71039ba845..bae59dbad0 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -72,6 +72,12 @@ #include #endif +/** The number of MIDI buffers that will fit in a UI/worker comm buffer. + This needs to be roughly the number of cycles the UI will get around to + actually processing the traffic. Lower values are flakier but save memory. +*/ +static const size_t NBUFS = 4; + using namespace std; using namespace ARDOUR; using namespace PBD; @@ -341,7 +347,8 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) if (lilv_plugin_has_feature(plugin, worker_schedule)) { LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc( sizeof(LV2_Worker_Schedule)); - _worker = new Worker(this, 4096); + size_t buf_size = _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS; + _worker = new Worker(this, buf_size); schedule->handle = this; schedule->schedule_work = work_schedule; _work_schedule_feature.data = schedule; @@ -1083,7 +1090,7 @@ LV2Plugin::has_message_output() const return false; } -void +bool LV2Plugin::write_to(RingBuffer* dest, uint32_t index, uint32_t protocol, @@ -1099,38 +1106,46 @@ LV2Plugin::write_to(RingBuffer* dest, msg->size = size; memcpy(msg + 1, body, size); - if (dest->write(buf, buf_size) != buf_size) { - error << "Error writing to UI=>Plugin RingBuffer" << endmsg; - } + return (dest->write(buf, buf_size) == buf_size); } -void +bool LV2Plugin::write_from_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t* body) { if (!_from_ui) { - _from_ui = new RingBuffer(4096); + _from_ui = new RingBuffer( + _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS); } - write_to(_from_ui, index, protocol, size, body); + if (!write_to(_from_ui, index, protocol, size, body)) { + error << "Error writing from UI to plugin" << endmsg; + return false; + } + return true; } -void +bool LV2Plugin::write_to_ui(uint32_t index, uint32_t protocol, uint32_t size, const uint8_t* body) { - write_to(_to_ui, index, protocol, size, body); + if (!write_to(_to_ui, index, protocol, size, body)) { + error << "Error writing from plugin to UI" << endmsg; + return false; + } + return true; } void LV2Plugin::enable_ui_emmission() { if (!_to_ui) { - _to_ui = new RingBuffer(4096); + _to_ui = new RingBuffer( + _session.engine().raw_buffer_size(DataType::MIDI) * NBUFS); } }