+
+ calculate_one_ppqn_in_frames_at(should_be_position);
+
+ framepos_t elapsed_since_start = timestamp - first_timestamp;
+ double error = 0;
+
+ if (_starting || last_timestamp == 0) {
+ midi_clock_count = 0;
+
+ first_timestamp = timestamp;
+ elapsed_since_start = should_be_position;
+
+ // calculate filter coefficients
+ calculate_filter_coefficients();
+
+ // initialize DLL
+ e2 = double(one_ppqn_in_frames) / double(session->frame_rate());
+ t0 = double(elapsed_since_start) / double(session->frame_rate());
+ t1 = t0 + e2;
+
+ // let ardour go after first MIDI Clock Event
+ _starting = false;
+ } else {
+ midi_clock_count++;
+ should_be_position += one_ppqn_in_frames;
+ calculate_filter_coefficients();
+
+ // calculate loop error
+ // we use session->audible_frame() instead of t1 here
+ // because t1 is used to calculate the transport speed,
+ // so the loop will compensate for accumulating rounding errors
+ error = (double(should_be_position) - double(session->audible_frame()));
+ e = error / double(session->frame_rate());
+
+ // update DLL
+ t0 = t1;
+ t1 += b * e + e2;
+ e2 += c * e;
+ }
+
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("clock #%1 @ %2 arrived %3 (theoretical) audible %4 transport %5 error %6 "
+ "read delta %7 should-be delta %8 t1-t0 %9 t0 %10 t1 %11 framerate %12 appspeed %13\n",
+ midi_clock_count,
+ elapsed_since_start,
+ should_be_position,
+ session->audible_frame(),
+ session->transport_frame(),
+ error,
+ timestamp - last_timestamp,
+ one_ppqn_in_frames,
+ (t1 -t0) * session->frame_rate(),
+ t0 * session->frame_rate(),
+ t1 * session->frame_rate(),
+ session->frame_rate(),
+ ((t1 - t0) * session->frame_rate()) / one_ppqn_in_frames));
+
+ last_timestamp = timestamp;
+}
+
+void
+MIDIClock_Slave::start (Parser& /*parser*/, framepos_t timestamp)
+{
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave got start message at time %1 engine time %2\n", timestamp, session->frame_time()));
+
+ if (!_started) {
+ reset();
+
+ _started = true;
+ _starting = true;
+
+ should_be_position = session->transport_frame();
+ }
+}
+
+void
+MIDIClock_Slave::reset ()
+{
+ should_be_position = session->transport_frame();
+ last_timestamp = 0;
+
+ _starting = true;
+ _started = true;
+
+ // session->request_locate(0, false);
+ current_delta = 0;