+
+ const double samples_per_quarter = (timestamp - current.timestamp) * 24.0;
+ const double instantaneous_bpm = (ENGINE->sample_rate() * 60.0) / samples_per_quarter;
+
+ const double predicted_clock_interval_in_samples = (t1 - t0);
+
+ /* _speed is relative to session tempo map */
+
+ double speed = predicted_clock_interval_in_samples / one_ppqn_in_samples;
+
+ /* _bpm (really, _qpm) is absolute */
+
+ /* detect substantial changes in apparent tempo (defined as a
+ * change of more than 20% of the current tempo.
+ */
+
+ const double lpf_coeff = 0.063;
+
+ if (fabs (instantaneous_bpm - _bpm) > (0.20 * _bpm)) {
+ _bpm = instantaneous_bpm;
+ } else {
+ _bpm += lpf_coeff * (instantaneous_bpm - _bpm);
+ }
+
+ calculate_filter_coefficients (_bpm);
+
+ // need at least two clock events to compute speed
+
+ if (!_running) {
+ DEBUG_TRACE (DEBUG::MidiClock, string_compose ("start mclock running with speed = %1\n", (t1 - t0) / one_ppqn_in_samples));
+ _running = true;
+ }
+
+ midi_clock_count++;
+ current.update (current.position + one_ppqn_in_samples, timestamp, speed);
+
+ if (TransportMasterManager::instance().current().get() == this) {
+ _session->maybe_update_tempo_from_midiclock_tempo (_bpm);
+ }