fix incorrect handling of MIDI data by AsyncMIDIPort
This type of MIDI port fetches all of its data from inside ::cycle_start(), and delivers it to a FIFO connected to another thread (typically a control surface). Unlike regular MidiPorts, which will be read from inside a Session::process() call, these ports will read their data once per AudioEngine::process() cycle. They therefore cannot use MidiPort::get_midi_buffer() which scales and adjusts event timestamps as if the data is being accessed from within Session::process(). It is still an open question whether or not AsyncMIDIPort::cycle_start() should still scale event timestamps by speed. In some respects it seems more appropriate to do so, and the reading thread (e.g. a control surface) doesn't care about the "nframes" limit on timestamps that exists for calls within a Session::process() tree. For now, leave the timestamps unscaled by speed.
This commit is contained in:
parent
42c13607a2
commit
4749fcef86
@ -131,23 +131,35 @@ AsyncMIDIPort::cycle_start (MIDI::pframes_t nframes)
|
||||
*/
|
||||
|
||||
if (ARDOUR::Port::receives_input()) {
|
||||
MidiBuffer& mb (get_midi_buffer (nframes));
|
||||
samplecnt_t when;
|
||||
|
||||
if (have_timer) {
|
||||
when = timer ();
|
||||
} else {
|
||||
when = AudioEngine::instance()->sample_time_at_cycle_start();
|
||||
}
|
||||
void* buffer = port_engine.get_buffer (_port_handle, nframes);
|
||||
const pframes_t event_count = port_engine.get_midi_event_count (buffer);
|
||||
|
||||
for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) {
|
||||
if (!have_timer) {
|
||||
when += (*b).time();
|
||||
for (pframes_t i = 0; i < event_count; ++i) {
|
||||
|
||||
pframes_t timestamp;
|
||||
size_t size;
|
||||
uint8_t const* buf;
|
||||
|
||||
port_engine.midi_event_get (timestamp, size, &buf, buffer, i);
|
||||
|
||||
if (buf[0] == 0xfe) {
|
||||
/* throw away active sensing */
|
||||
continue;
|
||||
}
|
||||
input_fifo.write (when, Evoral::NO_EVENT, (*b).size(), (*b).buffer());
|
||||
|
||||
samplecnt_t when;
|
||||
|
||||
if (have_timer) {
|
||||
when = timer ();
|
||||
} else {
|
||||
when = AudioEngine::instance()->sample_time_at_cycle_start() + timestamp;
|
||||
}
|
||||
|
||||
input_fifo.write (when, Evoral::NO_EVENT, size, buf);
|
||||
}
|
||||
|
||||
if (!mb.empty()) {
|
||||
if (event_count) {
|
||||
_xthread.wakeup ();
|
||||
}
|
||||
|
||||
@ -346,4 +358,3 @@ AsyncMIDIPort::is_process_thread()
|
||||
{
|
||||
return pthread_equal (pthread_self(), _process_thread);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user