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
This commit is contained in:
David Robillard 2012-11-18 01:30:53 +00:00
parent d7d47052e8
commit b3d63cc99b
2 changed files with 29 additions and 14 deletions

View file

@ -122,7 +122,7 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
bool has_editor () const; bool has_editor () const;
bool has_message_output () 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 protocol,
uint32_t size, uint32_t size,
const uint8_t* body); const uint8_t* body);
@ -211,12 +211,12 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
uint32_t size; uint32_t size;
}; };
void write_to_ui(uint32_t index, bool write_to_ui(uint32_t index,
uint32_t protocol, uint32_t protocol,
uint32_t size, uint32_t size,
const uint8_t* body); const uint8_t* body);
void write_to(RingBuffer<uint8_t>* dest, bool write_to(RingBuffer<uint8_t>* dest,
uint32_t index, uint32_t index,
uint32_t protocol, uint32_t protocol,
uint32_t size, uint32_t size,

View file

@ -72,6 +72,12 @@
#include <suil/suil.h> #include <suil/suil.h>
#endif #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 std;
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD; using namespace PBD;
@ -341,7 +347,8 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
if (lilv_plugin_has_feature(plugin, worker_schedule)) { if (lilv_plugin_has_feature(plugin, worker_schedule)) {
LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc( LV2_Worker_Schedule* schedule = (LV2_Worker_Schedule*)malloc(
sizeof(LV2_Worker_Schedule)); 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->handle = this;
schedule->schedule_work = work_schedule; schedule->schedule_work = work_schedule;
_work_schedule_feature.data = schedule; _work_schedule_feature.data = schedule;
@ -1083,7 +1090,7 @@ LV2Plugin::has_message_output() const
return false; return false;
} }
void bool
LV2Plugin::write_to(RingBuffer<uint8_t>* dest, LV2Plugin::write_to(RingBuffer<uint8_t>* dest,
uint32_t index, uint32_t index,
uint32_t protocol, uint32_t protocol,
@ -1099,38 +1106,46 @@ LV2Plugin::write_to(RingBuffer<uint8_t>* dest,
msg->size = size; msg->size = size;
memcpy(msg + 1, body, size); memcpy(msg + 1, body, size);
if (dest->write(buf, buf_size) != buf_size) { return (dest->write(buf, buf_size) == buf_size);
error << "Error writing to UI=>Plugin RingBuffer" << endmsg;
}
} }
void bool
LV2Plugin::write_from_ui(uint32_t index, LV2Plugin::write_from_ui(uint32_t index,
uint32_t protocol, uint32_t protocol,
uint32_t size, uint32_t size,
const uint8_t* body) const uint8_t* body)
{ {
if (!_from_ui) { if (!_from_ui) {
_from_ui = new RingBuffer<uint8_t>(4096); _from_ui = new RingBuffer<uint8_t>(
_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, LV2Plugin::write_to_ui(uint32_t index,
uint32_t protocol, uint32_t protocol,
uint32_t size, uint32_t size,
const uint8_t* body) 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 void
LV2Plugin::enable_ui_emmission() LV2Plugin::enable_ui_emmission()
{ {
if (!_to_ui) { if (!_to_ui) {
_to_ui = new RingBuffer<uint8_t>(4096); _to_ui = new RingBuffer<uint8_t>(
_session.engine().raw_buffer_size(DataType::MIDI) * NBUFS);
} }
} }