- if (qtr_frame_messages_valid_for_time) {
-
- nframes64_t now = session.engine().frame_time();
-
- if (which_qtr != 7) {
-
- /* leave position and speed updates for the last
- qtr frame message of the 8 to be taken
- care of in update_mtc_time(), invoked
- by the Parser right after this.
- */
-
- nframes_t qtr;
-
- qtr = (long) (session.frames_per_timecode_frame() / 4);
- mtc_frame += qtr;
-
- double speed = compute_apparent_speed (now);
-
- current.guard1++;
- current.position = mtc_frame;
- current.timestamp = now;
- current.speed = speed;
- current.guard2++;
+ if (p == "slave-timecode-offset"
+ || p == "timecode-format"
+ ) {
+ parse_timecode_offset();
+ }
+}
+
+bool
+MTC_Slave::give_slave_full_control_over_transport_speed() const
+{
+ return true; // DLL align to engine transport
+ // return false; // for Session-level computed varispeed
+}
+
+ARDOUR::framecnt_t
+MTC_Slave::resolution () const
+{
+ return (framecnt_t) quarter_frame_duration * 4.0;
+}
+
+ARDOUR::framecnt_t
+MTC_Slave::seekahead_distance () const
+{
+ return quarter_frame_duration * 8 * transport_direction;
+}
+
+bool
+MTC_Slave::outside_window (framepos_t pos) const
+{
+ return ((pos < window_begin) || (pos > window_end));
+}
+
+
+bool
+MTC_Slave::locked () const
+{
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("locked ? %1 last %2 initstate %3\n", port->self_parser().mtc_locked(), last_inbound_frame, engine_dll_initstate));
+ return port->self_parser().mtc_locked() && last_inbound_frame !=0 && engine_dll_initstate !=0;
+}
+
+bool
+MTC_Slave::ok() const
+{
+ return true;
+}
+
+void
+MTC_Slave::queue_reset (bool reset_pos)
+{
+ Glib::Threads::Mutex::Lock lm (reset_lock);
+ reset_pending++;
+ if (reset_pos) {
+ reset_position = true;
+ }
+}
+
+void
+MTC_Slave::maybe_reset ()
+{
+ Glib::Threads::Mutex::Lock lm (reset_lock);
+
+ if (reset_pending) {
+ reset (reset_position);
+ reset_pending = 0;
+ reset_position = false;
+ }
+}
+
+void
+MTC_Slave::reset (bool with_position)
+{
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC_Slave reset %1\n", with_position?"with position":"without position"));
+ if (with_position) {
+ last_inbound_frame = 0;
+ current.guard1++;
+ current.position = 0;
+ current.timestamp = 0;
+ current.speed = 0;
+ current.guard2++;
+ } else {
+ last_inbound_frame = 0;
+ current.guard1++;
+ current.timestamp = 0;
+ current.speed = 0;
+ current.guard2++;
+ }
+ first_mtc_timestamp = 0;
+ window_begin = 0;
+ window_end = 0;
+ transport_direction = 1;
+ current_delta = 0;
+}
+
+void
+MTC_Slave::handle_locate (const MIDI::byte* mmc_tc)
+{
+ MIDI::byte mtc[5];
+ DEBUG_TRACE (DEBUG::MTC, "MTC_Slave::handle_locate\n");
+
+ mtc[4] = last_mtc_fps_byte;
+ mtc[3] = mmc_tc[0] & 0xf; /* hrs only */
+ mtc[2] = mmc_tc[1];
+ mtc[1] = mmc_tc[2];
+ mtc[0] = mmc_tc[3];
+
+ update_mtc_time (mtc, true, 0);
+}
+
+void
+MTC_Slave::read_current (SafeTime *st) const
+{
+ int tries = 0;
+
+ do {
+ if (tries == 10) {
+ error << _("MTC Slave: atomic read of current time failed, sleeping!") << endmsg;
+ usleep (20);
+ tries = 0;