From 9d390f38bfbceb0a9946255b6772932c59a829ea Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 12 Jul 2020 01:50:01 +0200 Subject: [PATCH] Cache MIDI generator port latency This reduces excessive, expensive calls to get_connected_latency_range() --- libs/ardour/ardour/session.h | 2 ++ libs/ardour/ardour/ticker.h | 5 ++++- libs/ardour/session_midi.cc | 15 +++++++++++++-- libs/ardour/session_state.cc | 4 ++++ libs/ardour/ticker.cc | 17 ++++++++++++++--- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index ae88437230..dcc8c88ed1 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1726,6 +1726,7 @@ private: bool ltc_timecode_negative_offset; LatencyRange ltc_out_latency; + LatencyRange mtc_out_latency; void ltc_tx_initialize(); void ltc_tx_cleanup(); @@ -1789,6 +1790,7 @@ private: * cycle */ + void mtc_tx_resync_latency (bool); int send_full_time_code (samplepos_t, pframes_t nframes); void send_song_position_pointer (samplepos_t); diff --git a/libs/ardour/ardour/ticker.h b/libs/ardour/ardour/ticker.h index 13f69ef6a4..80f2f585ff 100644 --- a/libs/ardour/ardour/ticker.h +++ b/libs/ardour/ardour/ticker.h @@ -49,6 +49,7 @@ private: boost::shared_ptr _midi_port; void reset (); + void resync_latency (bool); double one_ppqn_in_samples (samplepos_t transport_position) const; void send_midi_clock_event (pframes_t offset, pframes_t nframes); @@ -64,7 +65,9 @@ private: samplepos_t _transport_pos; ARDOUR::Session* _session; - LatencyRange _mclk_out_latency; + + LatencyRange _mclk_out_latency; + PBD::ScopedConnection _latency_connection; }; } // namespace ARDOUR diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 0c37d8a686..36eeead795 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -376,6 +376,19 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) } } +void +Session::mtc_tx_resync_latency (bool playback) +{ + if (deletion_in_progress() || !playback) { + return; + } + boost::shared_ptr mtxport = _midi_ports->mtc_output_port (); + if (mtxport) { + mtxport->get_connected_latency_range(mtc_out_latency, true); + DEBUG_TRACE (DEBUG::MTC, string_compose ("resync latency: %1\n", mtc_out_latency.max)); + } +} + /** Send MTC Full Frame message (complete Timecode time) for the start of this cycle. * This resets the MTC code, the next quarter frame message that is sent will be * the first one with the beginning of this cycle as the new start point. @@ -409,8 +422,6 @@ Session::send_full_time_code (samplepos_t const t, MIDI::pframes_t nframes) outbound_mtc_timecode_frame = mtc_tc; transmitting_timecode_time = timecode; - LatencyRange mtc_out_latency; - _midi_ports->mtc_output_port ()->get_connected_latency_range (ltc_out_latency, true); sampleoffset_t mtc_offset = mtc_out_latency.max; // only if rolling.. ? diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 7193910cf7..8c7ccb2c53 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -242,6 +242,10 @@ Session::post_engine_init () setup_midi_machine_control (); + /* setup MTC generator */ + mtc_tx_resync_latency (true); + LatencyUpdated.connect_same_thread (*this, boost::bind (&Session::mtc_tx_resync_latency, this, _1)); + if (_butler->start_thread()) { error << _("Butler did not start") << endmsg; return -1; diff --git a/libs/ardour/ticker.cc b/libs/ardour/ticker.cc index edfa625ce2..dbd1be26be 100644 --- a/libs/ardour/ticker.cc +++ b/libs/ardour/ticker.cc @@ -45,6 +45,7 @@ MidiClockTicker::MidiClockTicker (Session* s) _session = s; _midi_port = s->midi_clock_output_port (); reset (); + s->LatencyUpdated.connect_same_thread (_latency_connection, boost::bind (&MidiClockTicker::resync_latency, this, _1)); } MidiClockTicker::~MidiClockTicker () @@ -59,6 +60,19 @@ MidiClockTicker::reset () _beat_pos = 0; _clock_cnt = 0; _transport_pos = -1; + + resync_latency (true); +} + +void +MidiClockTicker::resync_latency (bool playback) +{ + if (_session->deletion_in_progress() || !playback) { + return; + } + assert (_midi_port); + _midi_port->get_connected_latency_range(_mclk_out_latency, true); + DEBUG_TRACE (DEBUG::MidiClock, string_compose ("resync latency: %1\n", _mclk_out_latency.max)); } void @@ -77,9 +91,6 @@ MidiClockTicker::tick (samplepos_t start_sample, samplepos_t end_sample, pframes goto out; } - // TODO: cache - _midi_port->get_connected_latency_range (_mclk_out_latency, true); - if (speed == 0 && start_sample == 0 && end_sample == 0) { /* test if pre-roll is active, special-case * "start at zero"