-void
-MTC_Slave::init_engine_dll (framepos_t pos, framepos_t inc)
-{
- /* the bandwidth of the DLL is a trade-off,
- * because the max-speed of the transport in ardour is
- * limited to +-8.0, a larger bandwidth would cause oscillations
- *
- * But this is only really a problem if the user performs manual
- * seeks while transport is running and slaved to MTC.
- */
- oe = 2.0 * M_PI * double(inc) / 2.0 / double(session.frame_rate());
- be = 1.4142135623730950488 * oe;
- ce = oe * oe;
-
- ee2 = double(transport_direction * inc);
- te0 = double(pos);
- te1 = te0 + ee2;
- DEBUG_TRACE (DEBUG::MTC, string_compose ("[re-]init Engine DLL %1 %2 %3\n", te0, te1, ee2));
-}
-
-/* main entry point from session_process.cc
-xo * in process callback context */
-bool
-MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
-{
- framepos_t now = session.engine().sample_time_at_cycle_start();
- framepos_t sess_pos = session.transport_frame(); // corresponds to now
- //sess_pos -= session.engine().frames_since_cycle_start();
-
- SafeTime last;
- frameoffset_t elapsed;
- bool engine_dll_reinitialized = false;
-
- read_current (&last);
-
- DEBUG_TRACE (DEBUG::MTC, string_compose ("speed&pos: timestamp %1 speed %2 initstate %3 dir %4 tpos %5 now %6 last-in %7\n",
- last.timestamp,
- last.speed,
- engine_dll_initstate,
- transport_direction,
- sess_pos,
- now,
- last_inbound_frame));
-
- /* re-init engine DLL here when state changed (direction, first_mtc_timestamp) */
- if (last.timestamp == 0) {
- engine_dll_initstate = 0;
- } else if (engine_dll_initstate != transport_direction && last.speed != 0) {
- engine_dll_initstate = transport_direction;
- init_engine_dll(last.position, session.engine().samples_per_cycle());
- engine_dll_reinitialized = true;
- }
-
- if (last.timestamp == 0) {
- speed = 0;
- pos = session.transport_frame() ; // last.position;
- DEBUG_TRACE (DEBUG::MTC, string_compose ("first call to MTC_Slave::speed_and_position, pos = %1\n", pos));
- return true;
- }
-
- /* no timecode for two frames - conclude that it's stopped */
- if (last_inbound_frame && now > last_inbound_frame && now - last_inbound_frame > labs(seekahead_distance())) {
- speed = 0;
- pos = last.position;
- session.request_locate (pos, false);
- session.request_transport_speed (0);
- engine_dll_initstate = 0;
- queue_reset (false);
- DEBUG_TRACE (DEBUG::MTC, "MTC not seen for 2 frames - reset pending\n");
- return false;
- }
-
-
- DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position mtc-tme: %1 mtc-pos: %2 mtc-spd: %3\n", last.timestamp, last.position, last.speed));
- DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position eng-tme: %1 eng-pos: %2\n", now, sess_pos));
-
- double speed_flt = last.speed; ///< MTC speed from MTC-quarter-frame DLL
-
- /* interpolate position according to speed and time since last quarter-frame*/
- if (speed_flt == 0.0f) {
- elapsed = 0;
- } else {
- /* scale elapsed time by the current MTC speed */
- elapsed = (framecnt_t) rint (speed_flt * (now - last.timestamp));
- if (give_slave_full_control_over_transport_speed() && !engine_dll_reinitialized) {
- /* there is an engine vs MTC position frame-delta.
- * This mostly due to quantization and rounding of (speed * nframes)
- * but can also due to the session-process not calling
- * speed_and_position() every cycle under some circumstances.
- * Thus we use an other DLL to align the engine and the MTC
- */
-
- /* update engine DLL and calculate speed */
- const double e = double (last.position + elapsed - sess_pos);
- te0 = te1;
- te1 += be * e + ee2;
- ee2 += ce * e;
- speed_flt = (te1 - te0) / double(session.engine().samples_per_cycle());
- DEBUG_TRACE (DEBUG::MTC, string_compose ("engine DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", te0, te1, e, speed_flt, ee2 - session.engine().samples_per_cycle() ));
- }
- }
-
- pos = last.position + elapsed;
- speed = speed_flt;
-
- /* may happen if the user performs a seek in the timeline while slaved to running MTC
- * engine-DLL can oscillate back before 0.
- * also see note in MTC_Slave::init_engine_dll
- */
- if (!session.actively_recording()
- && speed != 0
- && ((pos < 0) || (labs(pos - sess_pos) > 3 * session.frame_rate()))) {
- engine_dll_initstate = 0;
- queue_reset (false);
- }
-
- /* provide a .1% deadzone to lock the speed */
- if (fabs (speed - 1.0) <= 0.001)
- speed = 1.0;
-
- DEBUG_TRACE (DEBUG::MTC, string_compose ("MTCsync spd: %1 pos: %2 | last-pos: %3 elapsed: %4 delta: %5\n",
- speed, pos, last.position, elapsed, pos - sess_pos));
-
- current_delta = (pos - sess_pos);
-
- return true;
-}
-