Correctly flush MIDI buffers on cycle-split
This commit is contained in:
parent
98224a264e
commit
2fde6a5777
@ -146,11 +146,37 @@ AudioEngine::split_cycle (pframes_t offset)
|
|||||||
{
|
{
|
||||||
/* caller must hold process lock */
|
/* 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);
|
Port::increment_global_port_buffer_offset (offset);
|
||||||
|
|
||||||
/* tell all Ports that we're going to start a new (split) cycle */
|
/* 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) {
|
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||||
i->second->cycle_split ();
|
i->second->cycle_split ();
|
||||||
|
@ -308,6 +308,9 @@ MidiPort::flush_buffers (pframes_t nframes)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XXX consider removing this check for optimized builds
|
||||||
|
// and just send 'em all, at cycle_end
|
||||||
|
// see AudioEngine::split_cycle (), PortManager::cycle_end()
|
||||||
if ( ev.time() >= _global_port_buffer_offset
|
if ( ev.time() >= _global_port_buffer_offset
|
||||||
&& ev.time() < _global_port_buffer_offset + nframes) {
|
&& ev.time() < _global_port_buffer_offset + nframes) {
|
||||||
pframes_t tme = floor (ev.time() / _speed_ratio);
|
pframes_t tme = floor (ev.time() / _speed_ratio);
|
||||||
|
@ -845,7 +845,9 @@ PortManager::cycle_end (pframes_t nframes, Session* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
|
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
|
||||||
p->second->flush_buffers (nframes);
|
/* AudioEngine::split_cycle flushes buffers until Port::port_offset.
|
||||||
|
* Now only flush remaining events (after Port::port_offset) */
|
||||||
|
p->second->flush_buffers (nframes - Port::port_offset ());
|
||||||
}
|
}
|
||||||
|
|
||||||
_cycle_ports.reset ();
|
_cycle_ports.reset ();
|
||||||
|
Loading…
Reference in New Issue
Block a user