From ed67f465fb765d33ebe4a459540b371bbae44a95 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 27 Dec 2019 21:15:16 -0700 Subject: [PATCH] fix JACK transport sync key change: to sync with JACK always locate jack-position PLUS buffer-sized-rounded-worst_latency_preroll() ahead --- libs/ardour/session_export.cc | 2 +- libs/ardour/session_process.cc | 45 ++++++++++++++++++++++++-------- libs/ardour/session_time.cc | 33 +++++++++++++++-------- libs/ardour/session_transport.cc | 4 +-- 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index c1a7f5f388..3ec32e1d6f 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -161,7 +161,7 @@ Session::start_audio_export (samplepos_t position, bool realtime, bool region_ex _transport_sample = position; if (!region_export) { - _remaining_latency_preroll = worst_latency_preroll (); + _remaining_latency_preroll = worst_latency_preroll_buffer_size_ceil (); } else { _remaining_latency_preroll = 0; } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index e1d80ad4fc..b3efb2bb73 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -346,7 +346,7 @@ Session::process_with_events (pframes_t nframes) assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll); - // DEBUG_TRACE (DEBUG::Transport, string_compose ("Running count in/latency preroll of %1 & %2\n", _count_in_samples, _remaining_latency_preroll)); + DEBUG_TRACE (DEBUG::Transport, string_compose ("Running count in/latency preroll of %1 & %2\n", _count_in_samples, _remaining_latency_preroll)); while (_count_in_samples > 0 || _remaining_latency_preroll > 0) { samplecnt_t ns; @@ -1109,20 +1109,43 @@ Session::follow_transport_master (pframes_t nframes) if (tmm.current()->type() == Engine) { - /* JACK Transport: if we're not aligned with the current JACK - * time, then jump to it - */ + /* JACK Transport. */ - if (delta && !actively_recording()) { + if (master_speed == 0) { - if (!locate_pending() && !declick_in_progress()) { - DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: jump to master position %1\n", master_transport_sample)); - /* for JACK transport always stop after the locate (2nd argument == false) */ - TFSM_LOCATE (master_transport_sample, false, true, false, false); - } else { - DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: locate already in process, sts = %1\n", master_transport_sample)); + if (!actively_recording()) { + + const samplecnt_t wlp = worst_latency_preroll_buffer_size_ceil (); + + if (delta != wlp) { + + /* if we're not aligned with the current JACK * time, then jump to it */ + + if (!locate_pending() && !declick_in_progress() && !tmm.current()->starting()) { + + const samplepos_t locate_target = master_transport_sample + wlp; + DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: jump to master position %1 by locating to %2\n", master_transport_sample, locate_target)); + /* for JACK transport always stop after the locate (2nd argument == false) */ + TFSM_LOCATE (locate_target, false, true, false, false); + + } else { + DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: locate already in process, sts = %1\n", master_transport_sample)); + } + } } + } else { + + if (_transport_speed) { + /* master is rolling, and we're rolling ... with JACK we should always be perfectly in sync, so ... WTF? */ + if (delta) { + if (remaining_latency_preroll() && worst_latency_preroll()) { + /* our transport position is not moving because we're doing latency alignment. Nothing in particular to do */ + } else { + cerr << "\n\n\n IMPOSSIBLE! OUT OF SYNC WITH JACK TRANSPORT (rlp = " << remaining_latency_preroll() << " wlp " << worst_latency_preroll() << ")\n\n\n"; + } + } + } } } else { diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index f08976aa39..b573ad9dd5 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -187,28 +187,39 @@ int Session::backend_sync_callback (TransportState state, samplepos_t pos) { bool slaved = synced_to_engine(); + int ready = true; + + // cerr << "SYNC state = " << enum_2_string (state) << endl; switch (state) { case TransportStopped: - if (slaved && (_transport_sample != pos) && (post_transport_work() == 0)) { - //cerr << "SYNC: stopped, need locate to " << pos << " from " << _transport_sample << endl; - return false; + if (slaved && (_transport_sample != pos) && !locate_pending()) { + /* we need to locate. This will be picked up in + * Session::follow_transport_master and the locate will + * be initiated there. + */ + // cerr << "SYNC: stopped, need locate to " << pos << " from " << _transport_sample << endl; + ready = false; } else { // cerr << "SYNC: stopped, nothing to do" << endl; - return true; } + break; case TransportStarting: if (slaved) { - const int ready_to_roll = _transport_sample == pos && !locate_pending() && !declick_in_progress() && (remaining_latency_preroll() == 0); - DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: ts %1 = %2 lp = %3 dip = %4 rlp = %5 RES: %6\n", _transport_sample, pos, locate_pending(), declick_in_progress(), remaining_latency_preroll(), ready_to_roll)); - return ready_to_roll; + /* JACK is stopped (though starting). Our position + * should be a buffer-size-rounded + * worst_latency_preroll() ahead of JACK. + */ + const samplepos_t matching = pos + worst_latency_preroll_buffer_size_ceil (); + + ready = (_transport_sample == matching) && !locate_pending() && !declick_in_progress() && (remaining_latency_preroll() == 0); + DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: ts %1 = %2 lp = %3 dip = %4 rlp = %5 RES: %6\n", _transport_sample, pos, locate_pending(), declick_in_progress(), remaining_latency_preroll(), ready)); } else { /* we're not participating, so just say we are in sync to stop interfering with other components of the engine transport (JACK) system. */ - return true; } break; @@ -216,11 +227,11 @@ Session::backend_sync_callback (TransportState state, samplepos_t pos) break; default: - error << string_compose (_("Unknown transport state %1 in sync callback"), state) - << endmsg; + error << string_compose (_("Unknown transport state %1 in sync callback"), state) << endmsg; } - return true; + // cerr << "SYNC, ready ? " << ready << endl; + return ready; } diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 01bdcea7cb..b6c5d64503 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -211,7 +211,7 @@ Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, boo g_atomic_int_inc (&_seek_counter); _last_roll_or_reversal_location = target_sample; if (!for_loop_end) { - _remaining_latency_preroll = worst_latency_preroll (); + _remaining_latency_preroll = worst_latency_preroll_buffer_size_ceil (); } timecode_time(_transport_sample, transmitting_timecode_time); // XXX here? @@ -585,7 +585,7 @@ Session::start_transport () _last_roll_location = _transport_sample; _last_roll_or_reversal_location = _transport_sample; - _remaining_latency_preroll = worst_latency_preroll (); + _remaining_latency_preroll = worst_latency_preroll_buffer_size_ceil (); have_looped = false;