+ calculate_one_ppqn_in_frames_at(should_be_position);
+
+ nframes64_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));