honor LV2 rsz:minimumSize for Atom Event buffers
This commit is contained in:
parent
7ab25697d2
commit
a1d0093bfa
@ -120,6 +120,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
LV2_Evbuf* get_lv2_midi(bool input, size_t i, bool old_api);
|
LV2_Evbuf* get_lv2_midi(bool input, size_t i, bool old_api);
|
||||||
|
|
||||||
|
/** ensure minimum size of LV2 Atom port buffer */
|
||||||
|
void ensure_lv2_bufsize(bool input, size_t i, size_t buffer_capacity);
|
||||||
|
|
||||||
/** Flush modified LV2 event output buffers back to Ardour buffers */
|
/** Flush modified LV2 event output buffers back to Ardour buffers */
|
||||||
void flush_lv2_midi(bool input, size_t i);
|
void flush_lv2_midi(bool input, size_t i);
|
||||||
|
|
||||||
|
@ -202,6 +202,7 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
|
|||||||
typedef unsigned PortFlags;
|
typedef unsigned PortFlags;
|
||||||
|
|
||||||
std::vector<PortFlags> _port_flags;
|
std::vector<PortFlags> _port_flags;
|
||||||
|
std::vector<size_t> _port_minimumSize;
|
||||||
std::map<std::string,uint32_t> _port_indices;
|
std::map<std::string,uint32_t> _port_indices;
|
||||||
|
|
||||||
/// Message send to/from UI via ports
|
/// Message send to/from UI via ports
|
||||||
|
@ -252,6 +252,25 @@ BufferSet::get(DataType type, size_t i) const
|
|||||||
|
|
||||||
#ifdef LV2_SUPPORT
|
#ifdef LV2_SUPPORT
|
||||||
|
|
||||||
|
void
|
||||||
|
BufferSet::ensure_lv2_bufsize(bool input, size_t i, size_t buffer_capacity)
|
||||||
|
{
|
||||||
|
assert(count().get(DataType::MIDI) > i);
|
||||||
|
|
||||||
|
LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
|
||||||
|
LV2_Evbuf* evbuf = b.second;
|
||||||
|
|
||||||
|
if (lv2_evbuf_get_capacity(evbuf) >= buffer_capacity) return;
|
||||||
|
|
||||||
|
lv2_evbuf_free(b.second);
|
||||||
|
_lv2_buffers.at(i * 2 + (input ? 0 : 1)) =
|
||||||
|
std::make_pair(false, lv2_evbuf_new(
|
||||||
|
buffer_capacity,
|
||||||
|
LV2_EVBUF_EVENT,
|
||||||
|
LV2Plugin::urids.atom_Chunk,
|
||||||
|
LV2Plugin::urids.atom_Sequence));
|
||||||
|
}
|
||||||
|
|
||||||
LV2_Evbuf*
|
LV2_Evbuf*
|
||||||
BufferSet::get_lv2_midi(bool input, size_t i, bool old_api)
|
BufferSet::get_lv2_midi(bool input, size_t i, bool old_api)
|
||||||
{
|
{
|
||||||
|
@ -115,6 +115,12 @@ lv2_evbuf_get_size(LV2_Evbuf* evbuf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
lv2_evbuf_get_capacity(LV2_Evbuf* evbuf)
|
||||||
|
{
|
||||||
|
return evbuf->capacity;
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
lv2_evbuf_get_buffer(LV2_Evbuf* evbuf)
|
lv2_evbuf_get_buffer(LV2_Evbuf* evbuf)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,12 @@ lv2_evbuf_reset(LV2_Evbuf* evbuf, bool input);
|
|||||||
uint32_t
|
uint32_t
|
||||||
lv2_evbuf_get_size(LV2_Evbuf* evbuf);
|
lv2_evbuf_get_size(LV2_Evbuf* evbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the available capacity of the buffer
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
lv2_evbuf_get_capacity(LV2_Evbuf* evbuf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the actual buffer implementation.
|
Return the actual buffer implementation.
|
||||||
The format of the buffer returned depends on the buffer type.
|
The format of the buffer returned depends on the buffer type.
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "lv2/lv2plug.in/ns/ext/state/state.h"
|
#include "lv2/lv2plug.in/ns/ext/state/state.h"
|
||||||
#include "lv2/lv2plug.in/ns/ext/time/time.h"
|
#include "lv2/lv2plug.in/ns/ext/time/time.h"
|
||||||
#include "lv2/lv2plug.in/ns/ext/worker/worker.h"
|
#include "lv2/lv2plug.in/ns/ext/worker/worker.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h"
|
||||||
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
|
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
|
||||||
#ifdef HAVE_NEW_LV2
|
#ifdef HAVE_NEW_LV2
|
||||||
#include "lv2/lv2plug.in/ns/ext/buf-size/buf-size.h"
|
#include "lv2/lv2plug.in/ns/ext/buf-size/buf-size.h"
|
||||||
@ -132,6 +133,7 @@ public:
|
|||||||
LilvNode* lv2_toggled;
|
LilvNode* lv2_toggled;
|
||||||
LilvNode* midi_MidiEvent;
|
LilvNode* midi_MidiEvent;
|
||||||
LilvNode* rdfs_comment;
|
LilvNode* rdfs_comment;
|
||||||
|
LilvNode* rsz_minimumSize;
|
||||||
LilvNode* time_Position;
|
LilvNode* time_Position;
|
||||||
LilvNode* ui_GtkUI;
|
LilvNode* ui_GtkUI;
|
||||||
LilvNode* ui_external;
|
LilvNode* ui_external;
|
||||||
@ -408,6 +410,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
|
|||||||
for (uint32_t i = 0; i < num_ports; ++i) {
|
for (uint32_t i = 0; i < num_ports; ++i) {
|
||||||
const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, i);
|
const LilvPort* port = lilv_plugin_get_port_by_index(_impl->plugin, i);
|
||||||
PortFlags flags = 0;
|
PortFlags flags = 0;
|
||||||
|
size_t minimumSize = 0;
|
||||||
|
|
||||||
if (lilv_port_is_a(_impl->plugin, port, _world.lv2_OutputPort)) {
|
if (lilv_port_is_a(_impl->plugin, port, _world.lv2_OutputPort)) {
|
||||||
flags |= PORT_OUTPUT;
|
flags |= PORT_OUTPUT;
|
||||||
@ -442,6 +445,11 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
|
|||||||
flags |= PORT_POSITION;
|
flags |= PORT_POSITION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LilvNode* min_size = lilv_port_get(_impl->plugin, port, _world.rsz_minimumSize);
|
||||||
|
if (min_size && lilv_node_is_int(min_size)) {
|
||||||
|
minimumSize = lilv_node_as_int(min_size);
|
||||||
|
}
|
||||||
|
lilv_node_free(min_size);
|
||||||
lilv_nodes_free(buffer_types);
|
lilv_nodes_free(buffer_types);
|
||||||
lilv_nodes_free(atom_supports);
|
lilv_nodes_free(atom_supports);
|
||||||
} else {
|
} else {
|
||||||
@ -452,6 +460,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_port_flags.push_back(flags);
|
_port_flags.push_back(flags);
|
||||||
|
_port_minimumSize.push_back(minimumSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
_control_data = new float[num_ports];
|
_control_data = new float[num_ports];
|
||||||
@ -1409,6 +1418,7 @@ LV2Plugin::allocate_atom_event_buffers()
|
|||||||
*/
|
*/
|
||||||
int count_atom_out = 0;
|
int count_atom_out = 0;
|
||||||
int count_atom_in = 0;
|
int count_atom_in = 0;
|
||||||
|
int minimumSize = 32768; // TODO use a per-port minimum-size
|
||||||
for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
|
for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
|
||||||
const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
|
const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
|
||||||
if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
|
if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
|
||||||
@ -1425,6 +1435,10 @@ LV2Plugin::allocate_atom_event_buffers()
|
|||||||
if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
|
if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
|
||||||
count_atom_out++;
|
count_atom_out++;
|
||||||
}
|
}
|
||||||
|
LilvNode* min_size = lilv_port_get(_impl->plugin, port, _world.rsz_minimumSize);
|
||||||
|
if (min_size && lilv_node_is_int(min_size)) {
|
||||||
|
minimumSize = std::max(minimumSize, lilv_node_as_int(min_size));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lilv_nodes_free(buffer_types);
|
lilv_nodes_free(buffer_types);
|
||||||
lilv_nodes_free(atom_supports);
|
lilv_nodes_free(atom_supports);
|
||||||
@ -1442,7 +1456,7 @@ LV2Plugin::allocate_atom_event_buffers()
|
|||||||
DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers\n", total_atom_buffers));
|
DEBUG_TRACE(DEBUG::LV2, string_compose("allocate %1 atom_ev_buffers\n", total_atom_buffers));
|
||||||
_atom_ev_buffers = (LV2_Evbuf**) malloc((total_atom_buffers + 1) * sizeof(LV2_Evbuf*));
|
_atom_ev_buffers = (LV2_Evbuf**) malloc((total_atom_buffers + 1) * sizeof(LV2_Evbuf*));
|
||||||
for (int i = 0; i < total_atom_buffers; ++i ) {
|
for (int i = 0; i < total_atom_buffers; ++i ) {
|
||||||
_atom_ev_buffers[i] = lv2_evbuf_new(32768, LV2_EVBUF_ATOM,
|
_atom_ev_buffers[i] = lv2_evbuf_new(minimumSize, LV2_EVBUF_ATOM,
|
||||||
LV2Plugin::urids.atom_Chunk, LV2Plugin::urids.atom_Sequence);
|
LV2Plugin::urids.atom_Chunk, LV2Plugin::urids.atom_Sequence);
|
||||||
}
|
}
|
||||||
_atom_ev_buffers[total_atom_buffers] = 0;
|
_atom_ev_buffers[total_atom_buffers] = 0;
|
||||||
@ -1551,6 +1565,12 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
|
|||||||
index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
|
index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
|
||||||
}
|
}
|
||||||
if (valid && bufs.count().n_midi() > index) {
|
if (valid && bufs.count().n_midi() > index) {
|
||||||
|
/* Note, ensure_lv2_bufsize() is not RT safe!
|
||||||
|
* However free()/alloc() is only called if a
|
||||||
|
* plugin requires a rsz:minimumSize buffersize
|
||||||
|
* and the existing buffer if smaller.
|
||||||
|
*/
|
||||||
|
bufs.ensure_lv2_bufsize((flags & PORT_INPUT), index, _port_minimumSize[port_index]);
|
||||||
_ev_buffers[port_index] = bufs.get_lv2_midi(
|
_ev_buffers[port_index] = bufs.get_lv2_midi(
|
||||||
(flags & PORT_INPUT), index, (flags & PORT_EVENT));
|
(flags & PORT_INPUT), index, (flags & PORT_EVENT));
|
||||||
}
|
}
|
||||||
@ -1881,6 +1901,7 @@ LV2World::LV2World()
|
|||||||
lv2_enumeration = lilv_new_uri(world, LV2_CORE__enumeration);
|
lv2_enumeration = lilv_new_uri(world, LV2_CORE__enumeration);
|
||||||
midi_MidiEvent = lilv_new_uri(world, LILV_URI_MIDI_EVENT);
|
midi_MidiEvent = lilv_new_uri(world, LILV_URI_MIDI_EVENT);
|
||||||
rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
|
rdfs_comment = lilv_new_uri(world, LILV_NS_RDFS "comment");
|
||||||
|
rsz_minimumSize = lilv_new_uri(world, LV2_RESIZE_PORT__minimumSize);
|
||||||
time_Position = lilv_new_uri(world, LV2_TIME__Position);
|
time_Position = lilv_new_uri(world, LV2_TIME__Position);
|
||||||
ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI);
|
ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI);
|
||||||
ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
|
ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
|
||||||
@ -1903,6 +1924,7 @@ LV2World::~LV2World()
|
|||||||
lilv_node_free(ext_logarithmic);
|
lilv_node_free(ext_logarithmic);
|
||||||
lilv_node_free(ext_notOnGUI);
|
lilv_node_free(ext_notOnGUI);
|
||||||
lilv_node_free(ev_EventPort);
|
lilv_node_free(ev_EventPort);
|
||||||
|
lilv_node_free(rsz_minimumSize);
|
||||||
lilv_node_free(atom_eventTransfer);
|
lilv_node_free(atom_eventTransfer);
|
||||||
lilv_node_free(atom_bufferType);
|
lilv_node_free(atom_bufferType);
|
||||||
lilv_node_free(atom_Sequence);
|
lilv_node_free(atom_Sequence);
|
||||||
|
Loading…
Reference in New Issue
Block a user