+ mtc_frame += (long) (1.75 * session.frames_per_timecode_frame()) + session.worst_playback_latency();
+
+
+ if (now) {
+
+ if (last_mtc_timestamp == 0) {
+
+ last_mtc_timestamp = now;
+ last_mtc_frame = mtc_frame;
+
+ } else {
+
+ if (give_slave_full_control_over_transport_speed()) {
+ /* PIC
+ *
+ * its not the average, but we will assign it to current.speed below
+ */
+
+ static framepos_t last_seen_timestamp = 0;
+ static framepos_t last_seen_position = 0;
+
+ if ((now - last_seen_timestamp) < 300) {
+ mtc_frame = (mtc_frame + last_seen_position)/2;
+ }
+
+ last_seen_timestamp = now;
+ last_seen_position = mtc_frame;
+
+
+
+ } else {
+
+ /* Non-PiC
+ */
+
+ framepos_t time_delta = (now - last_mtc_timestamp);
+
+ if (time_delta != 0) {
+ double apparent_speed = (mtc_frame - last_mtc_frame) / (double) (time_delta);
+
+ process_apparent_speed (apparent_speed);
+ DEBUG_TRACE (DEBUG::Slave, string_compose ("apparent speed was %1 average is now %2\n", apparent_speed, average_speed));
+ } else {
+ DEBUG_TRACE (DEBUG::Slave, string_compose ("no apparent calc, average is %1\n", average_speed));
+ }
+
+ /* every second, recalibrate the starting point for the speed measurement */
+ if (mtc_frame - last_mtc_frame > session.frame_rate()) {
+ last_mtc_timestamp = now;
+ last_mtc_frame = mtc_frame;
+ }
+ }
+ }
+
+ current.guard1++;
+ current.position = mtc_frame;
+ current.timestamp = now;
+ current.speed = average_speed;
+ current.guard2++;
+ window_root = mtc_frame;
+ }
+ }
+
+ if (now) {
+ last_inbound_frame = now;
+ }
+
+ if (window_root >= 0) {
+ reset_window (window_root);
+ }
+}
+
+void
+MTC_Slave::process_apparent_speed (double this_speed)
+{
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("speed cnt %1 sz %2 have %3\n", speed_accumulator_cnt, speed_accumulator_size, have_first_speed_accumulator));
+
+ /* clamp to an expected range */
+
+ if (this_speed > 4.0 || this_speed < -4.0) {
+ this_speed = average_speed;
+ }
+
+ if (speed_accumulator_cnt >= speed_accumulator_size) {
+ have_first_speed_accumulator = true;
+ speed_accumulator_cnt = 0;
+ }
+
+ speed_accumulator[speed_accumulator_cnt++] = this_speed;
+
+ if (have_first_speed_accumulator) {
+ average_speed = 0.0;
+ for (size_t i = 0; i < speed_accumulator_size; ++i) {
+ average_speed += speed_accumulator[i];
+ }
+ average_speed /= speed_accumulator_size;