some fixes/tweaks for MTC slaving, some untested
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Feb 2010 18:00:50 +0000 (18:00 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 11 Feb 2010 18:00:50 +0000 (18:00 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6676 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audioengine.h
libs/ardour/ardour/pi_controller.h
libs/ardour/ardour/slave.h
libs/ardour/mtc_slave.cc
libs/ardour/pi_controller.cc

index cf0eafe2884f1df799e1cb4f3a7ae039b416b2d6..6baa724cf2599ccd913098d3d2351bfaf98d3d1e 100644 (file)
@@ -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;
index d3cd0eb6bff74a00ee513c22f38a234e65c32211..c5b7c154ac5033ce34ec3518dd6cfbb6b0cdfc50 100644 (file)
@@ -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; }
 
index 34e92d01a4ed79e371583cf5dae824ccbe8edacc..959719eea03a55d095e867c413f533885d48b717 100644 (file)
@@ -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);
index 311795a928d2a74dc5af5daa94f00f12e26fa507..64f67ba7468d3e58f944ccf86ec370fc50f4c35d 100644 (file)
@@ -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;
index 1db36355fe50d509d2d89459bf903e8b1d4f56ff..ca923a6a28d346f94dec1995e65739f0ecaf6b79 100644 (file)
@@ -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";