summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/lv2_plugin.h16
-rw-r--r--libs/ardour/buffer_set.cc30
-rw-r--r--libs/ardour/lv2_plugin.cc105
3 files changed, 76 insertions, 75 deletions
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index 51fa5a2987..66c44884ea 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -179,7 +179,6 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
float* _bpm_control_port; ///< Special input set by ardour
float* _freewheel_control_port; ///< Special input set by ardour
float* _latency_control_port; ///< Special output set by ardour
- uint32_t _position_seq_port_idx; ///< Index of Sequence port for position
framepos_t _next_cycle_start; ///< Expected start frame of next run cycle
double _next_cycle_speed; ///< Expected start frame of next run cycle
PBD::ID _insert_id;
@@ -190,13 +189,14 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
uint32_t* type);
typedef enum {
- PORT_INPUT = 1,
- PORT_OUTPUT = 1 << 1,
- PORT_AUDIO = 1 << 2,
- PORT_CONTROL = 1 << 3,
- PORT_EVENT = 1 << 4,
- PORT_MESSAGE = 1 << 5,
- PORT_ATOM = 1 << 6
+ PORT_INPUT = 1, ///< Input port
+ PORT_OUTPUT = 1 << 1, ///< Output port
+ PORT_AUDIO = 1 << 2, ///< Audio (buffer of float)
+ PORT_CONTROL = 1 << 3, ///< Control (single float)
+ PORT_EVENT = 1 << 4, ///< Old event API event port
+ PORT_SEQUENCE = 1 << 5, ///< New atom API event port
+ PORT_MIDI = 1 << 6, ///< Event port understands MIDI
+ PORT_POSITION = 1 << 7 ///< Event port understands position
} PortFlag;
typedef unsigned PortFlags;
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index c2be5ca007..1f8317ffe2 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -257,34 +257,11 @@ BufferSet::get_lv2_midi(bool input, size_t i, bool old_api)
{
assert(count().get(DataType::MIDI) > i);
- MidiBuffer& mbuf = get_midi(i);
LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
LV2_Evbuf* evbuf = b.second;
- lv2_evbuf_set_type(evbuf, old_api ? LV2_EVBUF_EVENT : LV2_EVBUF_ATOM);
+ lv2_evbuf_set_type(evbuf, old_api ? LV2_EVBUF_EVENT : LV2_EVBUF_ATOM);
lv2_evbuf_reset(evbuf, input);
- if (input) {
- DEBUG_TRACE(PBD::DEBUG::LV2,
- string_compose("%1 bytes of MIDI waiting @ %2\n",
- mbuf.size(), (void*) mbuf.data()));
-
- LV2_Evbuf_Iterator i = lv2_evbuf_begin(evbuf);
- const uint32_t type = LV2Plugin::urids.midi_MidiEvent;
- for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) {
- const Evoral::MIDIEvent<framepos_t> ev(*e, false);
-#ifndef NDEBUG
- DEBUG_TRACE(PBD::DEBUG::LV2,
- string_compose("\tMIDI event of size %1 @ %2\n",
- ev.size(), ev.time()));
- for (uint16_t x = 0; x < ev.size(); ++x) {
- std::stringstream ss;
- ss << "\t\tev[" << x << "] = " << std::hex << (int) ev.buffer()[x] << std::dec << std::endl;
- DEBUG_TRACE (PBD::DEBUG::LV2, ss.str());
- }
-#endif
- lv2_evbuf_write(&i, ev.time(), 0, type, ev.size(), ev.buffer());
- }
- }
return evbuf;
}
@@ -311,7 +288,10 @@ BufferSet::flush_lv2_midi(bool input, size_t i)
DEBUG_TRACE (PBD::DEBUG::LV2, string_compose ("\tByte[%1] = %2\n", x, (int) data[x]));
}
#endif
- mbuf.push_back(frames, size, data);
+ if (type == LV2Plugin::urids.midi_MidiEvent) {
+ // TODO: Make Ardour event buffers generic so plugins can communicate
+ mbuf.push_back(frames, size, data);
+ }
}
}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 928c97a32e..b48c962d0c 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -274,7 +274,6 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
_bpm_control_port = 0;
_freewheel_control_port = 0;
_latency_control_port = 0;
- _position_seq_port_idx = std::numeric_limits<uint32_t>::max();
_next_cycle_start = std::numeric_limits<framepos_t>::max();
_next_cycle_speed = 1.0;
_block_length = _engine.frames_per_cycle();
@@ -405,6 +404,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
flags |= PORT_AUDIO;
} else if (lilv_port_is_a(_impl->plugin, port, _world.ev_EventPort)) {
flags |= PORT_EVENT;
+ flags |= PORT_MIDI; // We assume old event API ports are for MIDI
} 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);
@@ -412,13 +412,12 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
_impl->plugin, port, _world.atom_supports);
if (lilv_nodes_contains(buffer_types, _world.atom_Sequence)) {
+ flags |= PORT_SEQUENCE;
if (lilv_nodes_contains(atom_supports, _world.midi_MidiEvent)) {
- flags |= PORT_MESSAGE;
- } else {
- flags |= PORT_ATOM;
+ flags |= PORT_MIDI;
}
if (lilv_nodes_contains(atom_supports, _world.time_Position)) {
- _position_seq_port_idx = i;
+ flags |= PORT_POSITION;
}
}
lilv_nodes_free(buffer_types);
@@ -1066,7 +1065,8 @@ bool
LV2Plugin::has_message_output() const
{
for (uint32_t i = 0; i < num_ports(); ++i) {
- if ((_port_flags[i] & (PORT_MESSAGE|PORT_ATOM)) && _port_flags[i] & PORT_OUTPUT) {
+ if ((_port_flags[i] & PORT_SEQUENCE) &&
+ (_port_flags[i] & PORT_OUTPUT)) {
return true;
}
}
@@ -1485,17 +1485,18 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
BufferSet& silent_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 const nil_index = std::numeric_limits<uint32_t>::max();
uint32_t audio_in_index = 0;
uint32_t audio_out_index = 0;
uint32_t midi_in_index = 0;
uint32_t midi_out_index = 0;
uint32_t atom_port_index = 0;
- bool valid;
for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
void* buf = NULL;
- uint32_t index = 0;
+ uint32_t index = nil_index;
PortFlags flags = _port_flags[port_index];
+ bool valid = false;
if (flags & PORT_AUDIO) {
if (flags & PORT_INPUT) {
index = in_map.get(DataType::AUDIO, audio_in_index++, &valid);
@@ -1508,59 +1509,78 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
? bufs.get_audio(index).data(offset)
: scratch_bufs.get_audio(0).data(offset);
}
- } else if (flags & (PORT_EVENT|PORT_MESSAGE)) {
+ } else if (flags & (PORT_EVENT|PORT_SEQUENCE)) {
/* FIXME: The checks here for bufs.count().n_midi() > index shouldn't
be necessary, but the mapping is illegal in some cases. Ideally
that should be fixed, but this is easier...
*/
- if (flags & PORT_INPUT) {
- index = in_map.get(DataType::MIDI, midi_in_index++, &valid);
- _ev_buffers[port_index] = (valid && bufs.count().n_midi() > index)
- ? bufs.get_lv2_midi(true, index, flags & PORT_EVENT)
- : silent_bufs.get_lv2_midi(true, 0, flags & PORT_EVENT);
- buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
- } else {
- index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
- _ev_buffers[port_index] = (valid && bufs.count().n_midi() > index)
- ? bufs.get_lv2_midi(false, index, flags & PORT_EVENT)
- : scratch_bufs.get_lv2_midi(false, 0, flags & PORT_EVENT);
- buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
- }
- } else if (flags & (PORT_ATOM)) {
- assert(_atom_ev_buffers && _atom_ev_buffers[atom_port_index]);
- if (flags & PORT_INPUT) {
+ if (flags & PORT_MIDI) {
+ if (flags & PORT_INPUT) {
+ index = in_map.get(DataType::MIDI, midi_in_index++, &valid);
+ } else {
+ index = out_map.get(DataType::MIDI, midi_out_index++, &valid);
+ }
+ if (valid && bufs.count().n_midi() > index) {
+ _ev_buffers[port_index] = bufs.get_lv2_midi(
+ (flags & PORT_INPUT), index, (flags & PORT_EVENT));
+ }
+ } else if ((flags & PORT_POSITION) && (flags & PORT_INPUT)) {
lv2_evbuf_reset(_atom_ev_buffers[atom_port_index], true);
_ev_buffers[port_index] = _atom_ev_buffers[atom_port_index++];
+ valid = true;
+ }
- if (port_index == _position_seq_port_idx) {
- Timecode::BBT_Time bbt;
+ if (valid && (flags & PORT_INPUT)) {
+ Timecode::BBT_Time bbt;
+ if ((flags & PORT_POSITION)) {
if (_session.transport_frame() != _next_cycle_start ||
_session.transport_speed() != _next_cycle_speed) {
- // Something has changed, write the position at cycle start
+ // Transport has changed, write position at cycle start
tmap.bbt_time(_session.transport_frame(), bbt);
write_position(&_impl->forge, _ev_buffers[port_index],
tmetric, bbt, _session.transport_speed(),
_session.transport_frame(), 0);
}
+ }
- // Write a position event for every metric change within this cycle
- while (++metric_i != tmap.metrics_end() &&
- (*metric_i)->frame() < _session.transport_frame() + nframes) {
- MetricSection* section = *metric_i;
- tmetric.set_metric(section);
- bbt = section->start();
+ // Get MIDI iterator range (empty range if no MIDI)
+ MidiBuffer::iterator m = (index != nil_index)
+ ? bufs.get_midi(index).begin()
+ : silent_bufs.get_midi(0).end();
+ MidiBuffer::iterator m_end = (index != nil_index)
+ ? bufs.get_midi(index).end()
+ : m;
+
+ // Now merge MIDI and any transport events into the buffer
+ LV2_Evbuf_Iterator i = lv2_evbuf_end(_ev_buffers[port_index]);
+ const uint32_t type = LV2Plugin::urids.midi_MidiEvent;
+ const framepos_t tend = _session.transport_frame() + nframes;
+ ++metric_i;
+ while (m != m_end || (metric_i != tmap.metrics_end() &&
+ (*metric_i)->frame() < tend)) {
+ MetricSection* metric = (metric_i != tmap.metrics_end())
+ ? *metric_i : NULL;
+ if (m != m_end && (!metric || metric->frame() > (*m).time())) {
+ const Evoral::MIDIEvent<framepos_t> ev(*m, false);
+ LV2_Evbuf_Iterator eend = lv2_evbuf_end(_ev_buffers[port_index]);
+ lv2_evbuf_write(&eend, ev.time(), 0, type, ev.size(), ev.buffer());
+ ++m;
+ } else {
+ tmetric.set_metric(metric);
+ bbt = metric->start();
write_position(&_impl->forge, _ev_buffers[port_index],
tmetric, bbt, _session.transport_speed(),
- section->frame(),
- section->frame() - _session.transport_frame());
+ metric->frame(),
+ metric->frame() - _session.transport_frame());
+ ++metric_i;
}
}
- } else {
- lv2_evbuf_reset(_atom_ev_buffers[atom_port_index], false);
- _ev_buffers[port_index] = _atom_ev_buffers[atom_port_index++];
+ } else if (!valid) {
+ // Nothing we understand or care about, connect to scratch
+ _ev_buffers[port_index] = silent_bufs.get_lv2_midi(
+ (flags & PORT_INPUT), 0, (flags & PORT_EVENT));
}
buf = lv2_evbuf_get_buffer(_ev_buffers[port_index]);
- assert(buf);
} else {
continue; // Control port, leave buffer alone
}
@@ -1601,9 +1621,10 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
midi_out_index = 0;
for (uint32_t port_index = 0; port_index < num_ports; ++port_index) {
PortFlags flags = _port_flags[port_index];
+ bool valid = false;
// Flush MIDI (write back to Ardour MIDI buffers)
- if ((flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_MESSAGE))) {
+ if ((flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
const uint32_t buf_index = out_map.get(
DataType::MIDI, midi_out_index++, &valid);
if (valid) {
@@ -1612,7 +1633,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
}
// Write messages to UI
- if (_to_ui && (flags & PORT_OUTPUT) && (flags & (PORT_MESSAGE|PORT_ATOM))) {
+ if (_to_ui && (flags & PORT_OUTPUT) && (flags & (PORT_EVENT|PORT_SEQUENCE))) {
LV2_Evbuf* buf = _ev_buffers[port_index];
for (LV2_Evbuf_Iterator i = lv2_evbuf_begin(buf);
lv2_evbuf_is_valid(i);