Fix MIDI port i/o when vari-speeding

This commit is contained in:
Robin Gareus 2019-12-17 05:56:49 +01:00
parent 7fe9fb1f4e
commit 37c9a7beb1
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
3 changed files with 12 additions and 34 deletions

View file

@ -113,38 +113,11 @@ MidiBuffer::read_from (const Buffer& src, samplecnt_t nframes, sampleoffset_t ds
for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) {
const Evoral::Event<TimeType> ev(*i, false);
if (dst_offset >= 0) {
/* Positive offset: shifting events from internal
buffer view of time (always relative to to start of
current possibly split cycle) to from global/port
view of time (always relative to start of process
cycle).
Check it is within range of this (split) cycle, then shift.
*/
if (ev.time() >= 0 && ev.time() < nframes) {
push_back (ev.time(), ev.size(), ev.buffer());
} else {
cerr << "\t!!!! MIDI event @ " << ev.time() << " skipped, not within range 0 .. " << nframes << endl;
PBD::stacktrace (cerr, 30);
}
if (ev.time() >= 0 && ev.time() < nframes) {
push_back (ev.time(), ev.size(), ev.buffer());
} else {
/* Negative offset: shifting events from global/port
view of time (always relative to start of process
cycle) back to internal buffer view of time (always
relative to to start of current possibly split
cycle.
Shift first, then check it is within range of this
(split) cycle.
*/
const samplepos_t evtime = ev.time();
if (evtime >= 0 && evtime < nframes) {
push_back (evtime, ev.size(), ev.buffer());
} else {
cerr << "\t!!!! MIDI event @ " << evtime << " (based on " << ev.time() << ") skipped, not within range 0 .. " << nframes << ": ";
}
cerr << "\t!!!! MIDI event @ " << ev.time() << " skipped, not within range 0 .. " << nframes << endl;
PBD::stacktrace (cerr, 30);
}
}

View file

@ -101,6 +101,7 @@ MidiPort::get_midi_buffer (pframes_t nframes)
}
if (receives_input () && _input_active) {
_buffer->clear ();
void* buffer = port_engine.get_buffer (_port_handle, nframes);
const pframes_t event_count = port_engine.get_midi_event_count (buffer);
@ -154,6 +155,8 @@ MidiPort::get_midi_buffer (pframes_t nframes)
continue;
}
timestamp -= _global_port_buffer_offset;
if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) {
/* normalize note on with velocity 0 to proper note off */
uint8_t ev[3];
@ -288,7 +291,7 @@ MidiPort::flush_buffers (pframes_t nframes)
uint8_t const * const buf = ev.buffer();
const samplepos_t now = AudioEngine::instance()->sample_time_at_cycle_start();
_trace_parser->set_timestamp (now + adjusted_time);
_trace_parser->set_timestamp (now + adjusted_time / _speed_ratio);
uint32_t limit = ev.size();
@ -327,7 +330,9 @@ MidiPort::flush_buffers (pframes_t nframes)
cerr << "write failed, dropped event, time " << adjusted_time << '/' << ev.time() << endl;
}
} else {
cerr << "Dropped outgoing MIDI event. time " << adjusted_time << '/' << ev.time()
pframes_t tme = floor (adjusted_time / _speed_ratio);
cerr << "Dropped outgoing MIDI event. time " << adjusted_time
<< " (" << ev.time() << ") @" << _speed_ratio << " = " << tme
<< " out of range [" << _global_port_buffer_offset
<< " .. " << _global_port_buffer_offset + nframes
<< "]";

View file

@ -847,7 +847,7 @@ PortManager::cycle_end (pframes_t nframes, Session* s)
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
/* 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 ());
p->second->flush_buffers (nframes * Port::speed_ratio() - Port::port_offset ());
}
_cycle_ports.reset ();