diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2020-02-24 18:44:45 -0700 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2020-02-24 18:44:58 -0700 |
commit | 4749fcef86ac572960ea5ecd1ce502ecd5b7e846 (patch) | |
tree | e22fe9575b0029b58d0e1a18b035f07d9d30b33f /libs/ardour/async_midi_port.cc | |
parent | 42c13607a210b038f491a3afc36dbdb650a92748 (diff) |
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.
Diffstat (limited to 'libs/ardour/async_midi_port.cc')
-rw-r--r-- | libs/ardour/async_midi_port.cc | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/libs/ardour/async_midi_port.cc b/libs/ardour/async_midi_port.cc index 1e898764d2..06a51279fe 100644 --- a/libs/ardour/async_midi_port.cc +++ b/libs/ardour/async_midi_port.cc @@ -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 (pframes_t i = 0; i < event_count; ++i) { - for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) { - if (!have_timer) { - when += (*b).time(); + 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); } - |