Sort various things to reduce merge hell. No functional changes.
[ardour.git] / libs / ardour / mtc_slave.cc
index 906a0372a4737b9d7e2b8f53bc3d4143a046dbd3..0a0fbc15292804e82f7eb27cc5d46fe707a9d708 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <errno.h>
 using namespace ARDOUR;
 using namespace sigc;
 using namespace MIDI;
+using namespace PBD;
 
 MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) 
        : session (s)
 {
+       can_notify_on_unknown_rate = true;
+
        rebind (p);
        reset ();
 }
@@ -67,8 +69,8 @@ void
 MTC_Slave::update_mtc_qtr (Parser& p)
 {
        cycles_t cnow = get_cycles ();
-       jack_nframes_t now = session.engine().frame_time();
-       jack_nframes_t qtr;
+       nframes_t now = session.engine().frame_time();
+       nframes_t qtr;
        static cycles_t last_qtr = 0;
 
        qtr = (long) (session.frames_per_smpte_frame() / 4);
@@ -86,15 +88,46 @@ MTC_Slave::update_mtc_qtr (Parser& p)
 void
 MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
 {
-       jack_nframes_t now = session.engine().frame_time();
-       SMPTE_Time smpte;
+       nframes_t now = session.engine().frame_time();
+       SMPTE::Time smpte;
        
        smpte.hours = msg[3];
        smpte.minutes = msg[2];
        smpte.seconds = msg[1];
        smpte.frames = msg[0];
-       
-       session.smpte_to_sample( smpte, mtc_frame, true, false );
+
+       switch (msg[4]) {
+       case MTC_24_FPS:
+               smpte.rate = 24;
+               smpte.drop = false;
+               can_notify_on_unknown_rate = true;
+               break;
+       case MTC_25_FPS:
+               smpte.rate = 25;
+               smpte.drop = false;
+               can_notify_on_unknown_rate = true;
+               break;
+       case MTC_30_FPS_DROP:
+               smpte.rate = 30;
+               smpte.drop = true;
+               can_notify_on_unknown_rate = true;
+               break;
+       case MTC_30_FPS:
+               smpte.rate = 30;
+               smpte.drop = false;
+               can_notify_on_unknown_rate = true;
+               break;
+       default:
+               /* throttle error messages about unknown MTC rates */
+               if (can_notify_on_unknown_rate) {
+                       error << _("Unknown rate/drop value in incoming MTC stream, session values used instead") << endmsg;
+                       can_notify_on_unknown_rate = false;
+               }
+               smpte.rate = session.smpte_frames_per_second();
+               smpte.drop = session.smpte_drop_frames();
+       }
+
+       session.smpte_to_sample (smpte, mtc_frame, true, false);
        
        if (was_full) {
                
@@ -104,6 +137,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
                current.guard2++;        
                
                session.request_locate (mtc_frame, false);       
+               session.request_transport_speed (0);
                update_mtc_status (MIDI::Parser::MTC_Stopped);   
 
                reset ();
@@ -113,10 +147,11 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
                /* We received the last quarter frame 7 quarter frames (1.75 mtc
                   frames) after the instance when the contents of the mtc quarter
                   frames were decided. Add time to compensate for the elapsed 1.75
-                  frames 
+                  frames.
+                  Also compensate for audio latency. 
                */
 
-               mtc_frame += (long) (1.75 * session.frames_per_smpte_frame());
+               mtc_frame += (long) (1.75 * session.frames_per_smpte_frame()) + session.worst_output_latency();
                
                if (first_mtc_frame == 0) {
                        first_mtc_frame = mtc_frame;
@@ -215,12 +250,12 @@ MTC_Slave::ok() const
 }
 
 bool 
-MTC_Slave::speed_and_position (float& speed, jack_nframes_t& pos)
+MTC_Slave::speed_and_position (float& speed, nframes_t& pos)
 {
-       jack_nframes_t now = session.engine().frame_time();
+       nframes_t now = session.engine().frame_time();
        SafeTime last;
-       jack_nframes_t frame_rate;
-       jack_nframes_t elapsed;
+       nframes_t frame_rate;
+       nframes_t elapsed;
        float speed_now;
 
        read_current (&last);
@@ -237,6 +272,7 @@ MTC_Slave::speed_and_position (float& speed, jack_nframes_t& pos)
                mtc_speed = 0;
                pos = last.position;
                session.request_locate (pos, false);
+               session.request_transport_speed (0);
                update_mtc_status (MIDI::Parser::MTC_Stopped);
                reset();
                return false;
@@ -277,7 +313,7 @@ MTC_Slave::speed_and_position (float& speed, jack_nframes_t& pos)
                /* scale elapsed time by the current MTC speed */
                
                if (last.timestamp && (now > last.timestamp)) {
-                       elapsed = (jack_nframes_t) floor (mtc_speed * (now - last.timestamp));
+                       elapsed = (nframes_t) floor (mtc_speed * (now - last.timestamp));
                } else {
                        elapsed = 0; /* XXX is this right? */
                }
@@ -291,10 +327,10 @@ MTC_Slave::speed_and_position (float& speed, jack_nframes_t& pos)
        return true;
 }
 
-jack_nframes_t
+ARDOUR::nframes_t
 MTC_Slave::resolution() const
 {
-       return (jack_nframes_t) session.frames_per_smpte_frame();
+       return (nframes_t) session.frames_per_smpte_frame();
 }
 
 void