summaryrefslogtreecommitdiff
path: root/libs/ardour/audioengine.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-11-03 15:18:04 +0100
committerRobin Gareus <robin@gareus.org>2019-11-03 15:19:37 +0100
commit2fde6a5777694c454d102c7fa1bd9ea594d4db2b (patch)
treee0d774c36fe9dc1ce23f23a7cbd2497be51cccfd /libs/ardour/audioengine.cc
parent98224a264ec53c5c3488e3507ed3ce7b138820c1 (diff)
Correctly flush MIDI buffers on cycle-split
Diffstat (limited to 'libs/ardour/audioengine.cc')
-rw-r--r--libs/ardour/audioengine.cc28
1 files changed, 27 insertions, 1 deletions
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 69418c1911..c7e4efa1d1 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -146,11 +146,37 @@ AudioEngine::split_cycle (pframes_t offset)
{
/* caller must hold process lock */
+ boost::shared_ptr<Ports> p = ports.reader();
+
+ /* This is mainly for the benefit of rt-control ports (MTC, MClk)
+ *
+ * Normally ports are flushed by the route:
+ * ARDOUR::MidiPort::flush_buffers(unsigned int)
+ * ARDOUR::Delivery::flush_buffers(long)
+ * ARDOUR::Route::flush_processor_buffers_locked(long)
+ * ARDOUR::Route::run_route(long, long, unsigned int, bool, bool)
+ * ...
+ *
+ * This is required so that route -> route connections work during
+ * normal processing.
+ *
+ * However some non-route ports may contain MIDI events
+ * from current Port::port_offset() .. Port::port_offset() + offset.
+ * If those events are not pushed to ports before the cycle split,
+ * MidiPort::flush_buffers will drop them (event time is out of bounds).
+ *
+ * TODO: for optimized builds MidiPort::flush_buffers() could
+ * be relaxed, ignore ev->time() checks, and simply send
+ * all events as-is.
+ */
+ for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
+ i->second->flush_buffers (offset);
+ }
+
Port::increment_global_port_buffer_offset (offset);
/* tell all Ports that we're going to start a new (split) cycle */
- boost::shared_ptr<Ports> p = ports.reader();
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
i->second->cycle_split ();