LTC Slave: improve fps detection
authorRobin Gareus <robin@gareus.org>
Thu, 25 Oct 2012 17:07:59 +0000 (17:07 +0000)
committerRobin Gareus <robin@gareus.org>
Thu, 25 Oct 2012 17:07:59 +0000 (17:07 +0000)
and fix a few minor typos in the related doc

git-svn-id: svn://localhost/ardour2/branches/3.0@13338 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/slave.h
libs/ardour/ltc_slave.cc

index d63004ef078947d9b234903e69749e7016bd7ab8..76d2902d663d8f02807d10d6c65659fce071dd19 100644 (file)
@@ -352,6 +352,7 @@ public:
        void parse_ltc(const jack_nframes_t, const jack_default_audio_sample_t * const, const framecnt_t);
        void process_ltc(framepos_t const);
        void init_engine_dll (framepos_t, int32_t);
+       bool detect_discontinuity(LTCFrameExt *, int, bool);
        bool detect_ltc_fps(int, bool);
        void reset();
 
@@ -362,6 +363,8 @@ public:
        LTCDecoder *   decoder;
        double         frames_per_ltc_frame;
        Timecode::Time timecode;
+       LTCFrameExt    prev_frame;
+       bool           fps_detected;
 
        framecnt_t     monotonic_cnt;
        framecnt_t     last_timestamp;
index 9153facb8c151fe293663bfa5dc3ed6cd9febe81..49f0378ee60790504c3b6c38b9c008d3602cd464 100644 (file)
@@ -52,10 +52,11 @@ LTC_Slave::LTC_Slave (Session& s)
        delayedlocked = 10;
        monotonic_cnt = 0;
 
-       ltc_timecode = timecode_60; // track changes of LTC timecode
-       a3e_timecode = timecode_60; // track canges of Ardour's timecode
+       ltc_timecode = timecode_60; // track changes of LTC fps
+       a3e_timecode = timecode_60; // track changes of Ardour's fps
        printed_timecode_warning = false;
        ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
+       memset(&prev_frame, 0, sizeof(LTCFrameExt));
 
        decoder = ltc_decoder_create((int) frames_per_ltc_frame, 128 /*queue size*/);
        reset();
@@ -97,6 +98,7 @@ LTC_Slave::reset()
        transport_direction = 0;
        ltc_speed = 0;
        engine_dll_initstate = 0;
+       fps_detected=false;
 }
 
 void
@@ -106,7 +108,7 @@ LTC_Slave::parse_ltc(const jack_nframes_t nframes, const jack_default_audio_samp
        unsigned char sound[8192];
        if (nframes > 8192) {
                /* TODO warn once or wrap, loop conversion below
-                * does A3 support > 8192 spp anyway?
+                * does jack/A3 support > 8192 spp anyway?
                 */
                return;
        }
@@ -119,6 +121,45 @@ LTC_Slave::parse_ltc(const jack_nframes_t nframes, const jack_default_audio_samp
        return;
 }
 
+bool
+LTC_Slave::detect_discontinuity(LTCFrameExt *frame, int fps, bool fuzzy) {
+       bool discontinuity_detected = false;
+
+       if (fuzzy && (
+                 (frame->reverse  && prev_frame.ltc.frame_units == 0)
+               ||(!frame->reverse && frame->ltc.frame_units == 0)
+               ))
+       {
+               memcpy(&prev_frame, frame, sizeof(LTCFrameExt));
+               return false;
+       }
+
+       if (frame->reverse) {
+               ltc_frame_decrement(&prev_frame.ltc, fps , 0);
+       } else {
+               ltc_frame_increment(&prev_frame.ltc, fps , 0);
+       }
+
+       LTCFrame *a = &prev_frame.ltc;
+       LTCFrame *b = &frame->ltc;
+       if (       a->frame_units != b->frame_units
+               || a->frame_tens  != b->frame_tens
+               || a->dfbit       != b->dfbit
+               || a->secs_units  != b->secs_units
+               || a->secs_tens   != b->secs_tens
+               || a->mins_units  != b->mins_units
+               || a->mins_tens   != b->mins_tens
+               || a->hours_units != b->hours_units
+               || a->hours_tens  != b->hours_tens
+            )
+       {
+               discontinuity_detected = true;
+       }
+
+    memcpy(&prev_frame, frame, sizeof(LTCFrameExt));
+    return discontinuity_detected;
+}
+
 bool
 LTC_Slave::detect_ltc_fps(int frameno, bool df)
 {
@@ -170,7 +211,7 @@ LTC_Slave::detect_ltc_fps(int frameno, bool df)
                                did_reset_tc_format = true;
                        }
                        if (cur_timecode != tc_format) {
-                               warning << string_compose(_("Session framerate adjusted from %1 TO: LTC's %2."),
+                               warning << string_compose(_("Session framerate adjusted from %1 to LTC's %2."),
                                                Timecode::timecode_format_name(cur_timecode),
                                                Timecode::timecode_format_name(tc_format))
                                        << endmsg;
@@ -207,9 +248,16 @@ LTC_Slave::process_ltc(framepos_t const now)
                timecode.subframes  = 0;
 
                /* set timecode.rate and timecode.drop: */
+
+               if (detect_discontinuity(&frame, ceil(timecode.rate), !fps_detected)) {
+                       ltc_detect_fps_cnt = ltc_detect_fps_max = 0;
+                       fps_detected=false;
+               }
+
                if (detect_ltc_fps(stime.frame, (frame.ltc.dfbit)? true : false)) {
                        reset();
                        last_timestamp = 0;
+                       fps_detected=true;
                }
 
 #if 0 // Devel/Debug
@@ -362,7 +410,7 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
 
        /* it take 2 cycles from naught to rolling.
         * during these to initial cycles the speed == 0
-        * 
+        *
         * the first cycle:
         * DEBUG::Slave: slave stopped, move to NNN
         * DEBUG::Transport: Request forced locate to NNN