13
0

fix JACK transport sync

key change: to sync with JACK always locate jack-position PLUS buffer-sized-rounded-worst_latency_preroll() ahead
This commit is contained in:
Paul Davis 2019-12-27 21:15:16 -07:00
parent 5cdeb2401f
commit ed67f465fb
4 changed files with 59 additions and 25 deletions

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;