summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2012-08-27 04:08:45 +0000
committerRobin Gareus <robin@gareus.org>2012-08-27 04:08:45 +0000
commit0a834da466ccb9c9223e5584915429f2d78f662c (patch)
treef8e1d78fd12a840e1e4106288e7af7a602a97f84 /libs/ardour
parent7b7140f5ed2ad2fdb58bebb70302628fd3172663 (diff)
dedicated LV2 non-MIDI atom-event-port handling
git-svn-id: svn://localhost/ardour2/branches/3.0@13144 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/lv2_plugin.h3
-rw-r--r--libs/ardour/lv2_evbuf.c2
-rw-r--r--libs/ardour/lv2_plugin.cc62
3 files changed, 56 insertions, 11 deletions
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index 8dacd8600e..5aaeb68327 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -183,7 +183,8 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
PORT_AUDIO = 1 << 2,
PORT_CONTROL = 1 << 3,
PORT_EVENT = 1 << 4,
- PORT_MESSAGE = 1 << 5
+ PORT_MESSAGE = 1 << 5,
+ PORT_ATOM = 1 << 6
} PortFlag;
typedef unsigned PortFlags;
diff --git a/libs/ardour/lv2_evbuf.c b/libs/ardour/lv2_evbuf.c
index 3037e8275c..1cce8730a9 100644
--- a/libs/ardour/lv2_evbuf.c
+++ b/libs/ardour/lv2_evbuf.c
@@ -270,6 +270,8 @@ lv2_evbuf_write(LV2_Evbuf_Iterator* iter,
aseq->atom.size += size;
iter->offset += size;
break;
+ default:
+ return false;
}
return true;
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 7d5c88402e..4c2202f230 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -101,6 +101,7 @@ public:
LilvNode* atom_Chunk;
LilvNode* atom_Sequence;
LilvNode* atom_bufferType;
+ LilvNode* atom_supports;
LilvNode* atom_eventTransfer;
LilvNode* ev_EventPort;
LilvNode* ext_logarithmic;
@@ -419,10 +420,18 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
} else if (lilv_port_is_a(_impl->plugin, port, _world.atom_AtomPort)) {
LilvNodes* buffer_types = lilv_port_get_value(
_impl->plugin, port, _world.atom_bufferType);
- if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
+ LilvNodes* atom_supports = lilv_port_get_value(
+ _impl->plugin, port, _world.atom_supports);
+
+ if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)
+ && lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)
+ ) {
flags |= PORT_MESSAGE;
+ } else {
+ flags |= PORT_ATOM;
}
lilv_nodes_free(buffer_types);
+ lilv_nodes_free(atom_supports);
} else {
error << string_compose(
"LV2: \"%1\" port %2 has no known data type",
@@ -1072,7 +1081,7 @@ bool
LV2Plugin::has_message_output() const
{
for (uint32_t i = 0; i < num_ports(); ++i) {
- if ((_port_flags[i] & PORT_MESSAGE) && _port_flags[i] & PORT_OUTPUT) {
+ if ((_port_flags[i] & (PORT_MESSAGE|PORT_ATOM)) && _port_flags[i] & PORT_OUTPUT) {
return true;
}
}
@@ -1397,7 +1406,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
bufs_count.set(DataType::AUDIO, 1);
bufs_count.set(DataType::MIDI, 1);
BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
- BufferSet& scratch_bufs = _session.get_silent_buffers(bufs_count);
+ BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
uint32_t const num_ports = parameter_count();
uint32_t audio_in_index = 0;
@@ -1439,6 +1448,14 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
: scratch_bufs.get_lv2_midi(false, 0, flags & PORT_EVENT);
buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
}
+ } else if (flags & (PORT_ATOM)) {
+ if (flags & PORT_INPUT) {
+ _ev_buffers[port_index] = silent_bufs.get_lv2_midi(true, 0, false);
+ buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
+ } else {
+ _ev_buffers[port_index] = scratch_bufs.get_lv2_midi(false, 0, false);
+ buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
+ }
} else {
continue; // Control port, leave buffer alone
}
@@ -1463,8 +1480,10 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
LV2_Evbuf* buf = _ev_buffers[msg.index];
LV2_Evbuf_Iterator i = lv2_evbuf_end(buf);
const LV2_Atom* const atom = (const LV2_Atom*)body;
- lv2_evbuf_write(&i, nframes, 0, atom->type, atom->size,
- (const uint8_t*)(atom + 1));
+ if (!lv2_evbuf_write(&i, nframes, 0, atom->type, atom->size,
+ (const uint8_t*)(atom + 1))) {
+ cerr << "LV2: failed to write data to event buffer\n";
+ }
} else {
error << "Received unknown message type from UI" << endmsg;
}
@@ -1488,7 +1507,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
}
// Write messages to UI
- if (_to_ui && (flags & PORT_OUTPUT) && (flags & PORT_MESSAGE)) {
+ if (_to_ui && (flags & PORT_OUTPUT) && (flags & (PORT_MESSAGE|PORT_ATOM))) {
LV2_Evbuf* buf = _ev_buffers[port_index];
for (LV2_Evbuf_Iterator i = lv2_evbuf_begin(buf);
lv2_evbuf_is_valid(i);
@@ -1666,6 +1685,7 @@ LV2World::LV2World()
atom_Chunk = lilv_new_uri(world, LV2_ATOM__Chunk);
atom_Sequence = lilv_new_uri(world, LV2_ATOM__Sequence);
atom_bufferType = lilv_new_uri(world, LV2_ATOM__bufferType);
+ atom_supports = lilv_new_uri(world, LV2_ATOM__supports);
atom_eventTransfer = lilv_new_uri(world, LV2_ATOM__eventTransfer);
ev_EventPort = lilv_new_uri(world, LILV_URI_EVENT_PORT);
ext_logarithmic = lilv_new_uri(world, LV2_PORT_PROPS__logarithmic);
@@ -1767,14 +1787,37 @@ LV2PluginInfo::discover()
info->path = "/NOPATH"; // Meaningless for LV2
+ int count_midi_out = 0;
+ int count_midi_in = 0;
+ for (uint32_t i = 0; i < lilv_plugin_get_num_ports(p); ++i) {
+ const LilvPort* port = lilv_plugin_get_port_by_index(p, i);
+ if (lilv_port_is_a(p, port, _world.atom_AtomPort)) {
+ LilvNodes* buffer_types = lilv_port_get_value(
+ p, port, _world.atom_bufferType);
+ LilvNodes* atom_supports = lilv_port_get_value(
+ p, port, _world.atom_supports);
+
+ if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)
+ && lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
+ if (lilv_port_is_a(p, port, _world.lv2_InputPort)) {
+ count_midi_in++;
+ }
+ if (lilv_port_is_a(p, port, _world.lv2_OutputPort)) {
+ count_midi_out++;
+ }
+ }
+ lilv_nodes_free(buffer_types);
+ lilv_nodes_free(atom_supports);
+ }
+ }
+
info->n_inputs.set_audio(
lilv_plugin_get_num_ports_of_class(
p, _world.lv2_InputPort, _world.lv2_AudioPort, NULL));
info->n_inputs.set_midi(
lilv_plugin_get_num_ports_of_class(
p, _world.lv2_InputPort, _world.ev_EventPort, NULL)
- + lilv_plugin_get_num_ports_of_class(
- p, _world.lv2_InputPort, _world.atom_AtomPort, NULL));
+ + count_midi_in);
info->n_outputs.set_audio(
lilv_plugin_get_num_ports_of_class(
@@ -1782,8 +1825,7 @@ LV2PluginInfo::discover()
info->n_outputs.set_midi(
lilv_plugin_get_num_ports_of_class(
p, _world.lv2_OutputPort, _world.ev_EventPort, NULL)
- + lilv_plugin_get_num_ports_of_class(
- p, _world.lv2_OutputPort, _world.atom_AtomPort, NULL));
+ + count_midi_out);
info->unique_id = lilv_node_as_uri(lilv_plugin_get_uri(p));
info->index = 0; // Meaningless for LV2