From 47018a3bd1990ef9328459640b6e6b385404eda6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 11 Feb 2010 18:00:50 +0000 Subject: [PATCH] some fixes/tweaks for MTC slaving, some untested git-svn-id: svn://localhost/ardour2/branches/3.0@6676 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audioengine.h | 6 +++ libs/ardour/ardour/pi_controller.h | 2 +- libs/ardour/ardour/slave.h | 7 +-- libs/ardour/mtc_slave.cc | 83 ++++++++++++++++++------------ libs/ardour/pi_controller.cc | 10 ++-- 5 files changed, 68 insertions(+), 40 deletions(-) diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index cf0eafe288..6baa724cf2 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -94,6 +94,12 @@ class AudioEngine : public SessionHandlePtr return jack_frame_time (_priv_jack); } + nframes_t frame_time_at_cycle_start () { + jack_client_t* _priv_jack = _jack; + if (!_running || !_priv_jack) return 0; + return jack_last_frame_time (_priv_jack); + } + nframes_t transport_frame () const { const jack_client_t* _priv_jack = _jack; if (!_running || !_priv_jack) return 0; diff --git a/libs/ardour/ardour/pi_controller.h b/libs/ardour/ardour/pi_controller.h index d3cd0eb6bf..c5b7c154ac 100644 --- a/libs/ardour/ardour/pi_controller.h +++ b/libs/ardour/ardour/pi_controller.h @@ -60,7 +60,7 @@ class PIChaser { PIChaser(); ~PIChaser(); - double get_ratio( nframes64_t realtime, nframes64_t chasetime, nframes64_t slavetime, bool in_control ); + double get_ratio( nframes64_t chasetime_measured, nframes64_t chasetime, nframes64_t slavetime_measured, nframes64_t slavetime, bool in_control ); void reset(); nframes64_t want_locate() { return want_locate_val; } diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 34e92d01a4..959719eea0 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -264,10 +264,11 @@ class MTC_Slave : public Slave { bool have_first_speed_accumulator; double average_speed; Glib::Mutex reset_lock; - bool reset_pending; + uint32_t reset_pending; + bool reset_position; - void reset (); - void queue_reset (); + void reset (bool with_pos); + void queue_reset (bool with_pos); void maybe_reset (); void update_mtc_qtr (MIDI::Parser&, int, nframes_t); diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 311795a928..64f67ba746 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -56,7 +56,8 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) { can_notify_on_unknown_rate = true; did_reset_tc_format = false; - reset_pending = false; + reset_pending = 0; + reset_position = false; pic = new PIChaser(); @@ -67,7 +68,7 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) speed_accumulator = new double[speed_accumulator_size]; rebind (p); - reset (); + reset (true); } MTC_Slave::~MTC_Slave() @@ -188,7 +189,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, nframes_t now) session.request_locate (mtc_frame, false); session.request_transport_speed (0); update_mtc_status (MIDI::MTC_Stopped); - reset (); + reset (false); reset_window (mtc_frame); } else { @@ -395,6 +396,7 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos) nframes64_t now = session.engine().frame_time(); SafeTime last; nframes_t elapsed; + bool in_control = false; read_current (&last); @@ -412,7 +414,7 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos) pos = last.position; session.request_locate (pos, false); session.request_transport_speed (0); - queue_reset (); + queue_reset (false); DEBUG_TRACE (DEBUG::MTC, "MTC not seen for 1/4 second - reset pending\n"); return false; } @@ -420,21 +422,23 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos) DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position %1 %2\n", last.speed, last.position)); if (give_slave_full_control_over_transport_speed()) { - bool in_control = (session.slave_state() == Session::Running); - nframes64_t pic_want_locate = 0; - //nframes64_t slave_pos = session.audible_frame(); - nframes64_t slave_pos = session.transport_frame(); - static double average_speed = 0; - - average_speed = pic->get_ratio (last.timestamp, last.position, slave_pos, in_control ); - pic_want_locate = pic->want_locate(); - - if (in_control && pic_want_locate) { - last.speed = average_speed + (double) (pic_want_locate - session.transport_frame()) / (double)session.get_block_size(); - std::cout << "locate req " << pic_want_locate << " speed: " << average_speed << "\n"; - } else { - last.speed = average_speed; - } + in_control = (session.slave_state() == Session::Running); + nframes64_t pic_want_locate = 0; + //nframes64_t slave_pos = session.audible_frame(); + nframes64_t slave_pos = session.transport_frame(); + static double average_speed = 0; + + nframes64_t ref_now = session.engine().frame_time_at_cycle_start(); + average_speed = pic->get_ratio (last.timestamp, last.position, ref_now, slave_pos, in_control ); + + pic_want_locate = pic->want_locate(); + + if (in_control && pic_want_locate) { + last.speed = average_speed + (double) (pic_want_locate - session.transport_frame()) / (double)session.get_block_size(); + std::cout << "locate req " << pic_want_locate << " speed: " << average_speed << "\n"; + } else { + last.speed = average_speed; + } } if (last.speed == 0.0f) { @@ -456,7 +460,12 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos) /* now add the most recent timecode value plus the estimated elapsed interval */ - pos = last.position + elapsed; + if (in_control) { + pos = session.transport_frame(); + } else { + pos = last.position + elapsed; + } + speed = last.speed; DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position FINAL %1 %2\n", last.speed, pos)); @@ -471,34 +480,44 @@ MTC_Slave::resolution() const } void -MTC_Slave::queue_reset () +MTC_Slave::queue_reset (bool reset_pos) { Glib::Mutex::Lock lm (reset_lock); reset_pending++; + if (reset_pos) { + reset_position = true; + } } void MTC_Slave::maybe_reset () { - reset_lock.lock (); + Glib::Mutex::Lock lm (reset_lock); if (reset_pending) { - reset (); + reset (reset_position); reset_pending = 0; + reset_position = false; } - - reset_lock.unlock (); } void -MTC_Slave::reset () +MTC_Slave::reset (bool with_position) { - last_inbound_frame = 0; - current.guard1++; - current.position = 0; - current.timestamp = 0; - current.speed = 0; - current.guard2++; + if (with_position) { + last_inbound_frame = 0; + current.guard1++; + current.position = 0; + current.timestamp = 0; + current.speed = 0; + current.guard2++; + } else { + last_inbound_frame = 0; + current.guard1++; + current.timestamp = 0; + current.speed = 0; + current.guard2++; + } window_begin = 0; window_end = 0; diff --git a/libs/ardour/pi_controller.cc b/libs/ardour/pi_controller.cc index 1db36355fe..ca923a6a28 100644 --- a/libs/ardour/pi_controller.cc +++ b/libs/ardour/pi_controller.cc @@ -151,14 +151,16 @@ PIChaser::~PIChaser() { } double -PIChaser::get_ratio(nframes64_t realtime, nframes64_t chasetime, nframes64_t slavetime, bool in_control ) { +PIChaser::get_ratio(nframes64_t chasetime_measured, nframes64_t chasetime, nframes64_t slavetime_measured, nframes64_t slavetime, bool in_control ) { - feed_estimator( realtime, chasetime ); - std::cerr << (double)realtime/48000.0 << " " << chasetime << " " << slavetime << " "; + feed_estimator( chasetime_measured, chasetime ); + std::cerr << (double)chasetime_measured/48000.0 << " " << chasetime << " " << slavetime << " "; double crude = get_estimate(); double fine; + nframes64_t massaged_chasetime = chasetime + (nframes64_t)( (double)(slavetime_measured - chasetime_measured) * crude ); - fine = pic->get_ratio( slavetime - chasetime ); + fine = pic->get_ratio( slavetime - massaged_chasetime ); + fine = pic->get_ratio( slavetime - chasetime ); if (in_control) { if (fabs(fine-crude) > crude*speed_threshold) { std::cout << "reset to " << crude << " fine = " << fine << "\n"; -- 2.30.2