diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index b2f9197..fcdea2e 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1367,6 +1367,8 @@ class Session : public PBD::StatefulDestructible
 	nframes_t  last_smpte_when;
 	SMPTE::Time last_smpte;
 
+	bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle
+	
 	int send_full_time_code ();
 	int send_midi_time_code ();
 
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index ffa8eeb..b556589 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -284,6 +284,7 @@ Session::Session (AudioEngine &eng,
 	  state_tree (0),
 	  butler_mixdown_buffer (0),
 	  butler_gain_buffer (0),
+	  _send_smpte_update (false),
 	  midi_thread (pthread_t (0)),
 	  midi_requests (128), // the size of this should match the midi request pool size
 	  diskstreams (new DiskstreamList),
@@ -355,6 +356,7 @@ Session::Session (AudioEngine &eng,
 	  state_tree (0),
 	  butler_mixdown_buffer (0),
 	  butler_gain_buffer (0),
+	  _send_smpte_update (false),
 	  midi_thread (pthread_t (0)),
 	  midi_requests (16),
 	  diskstreams (new DiskstreamList),
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index 20e7309..f52a458 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -336,6 +336,7 @@ Session::process_event (Event* ev)
 			// cerr << "soft locate to " << ev->target_frame << endl;
 			start_locate (ev->target_frame, false, true, false);
 		}
+		_send_smpte_update = true;
 		break;
 
 	case Event::LocateRoll:
@@ -346,6 +347,7 @@ Session::process_event (Event* ev)
 			// cerr << "soft locate to+roll " << ev->target_frame << endl;
 			start_locate (ev->target_frame, true, true, false);
 		}
+		_send_smpte_update = true;
 		break;
 
 	case Event::LocateRollLocate:
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index ffd30fb..1f0e085 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -762,6 +762,8 @@ Session::send_full_time_code ()
 	MIDI::byte msg[10];
 	SMPTE::Time smpte;
 
+	_send_smpte_update = false;
+
 	if (_mtc_port == 0 || !session_send_mtc) {
 		return 0;
 	}
@@ -829,14 +831,8 @@ Session::send_midi_time_code ()
 		return 0;
 	}
 
-	nframes_t two_smpte_frames_duration;
-	nframes_t quarter_frame_duration;
-
-	/* Duration of two smpte frames */
-	two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
-
 	/* Duration of one quarter frame */
-	quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
+	nframes_t const quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
 
 	while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
 
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index 8d831ee..7695b50 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -282,6 +282,14 @@ Session::process_with_events (nframes_t nframes)
 		process_event (ev);
 	}
 
+	/* Events caused a transport change, send an MTC Full Frame (SMPTE) message.
+	 * This is sent whether rolling or not, to give slaves an idea of ardour time
+	 * on locates (and allow slow slaves to position and prepare for rolling)
+	 */
+	if (_send_smpte_update) {
+		send_full_time_code ();
+	}
+
 	if (!process_can_proceed()) {
 		_silent = true;
 		return;
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 2801892..e306f05 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -773,6 +773,8 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w
 	}
 	
 	loop_changing = false;
+
+	_send_smpte_update = true;
 }
 
 void
