fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / session_ltc.cc
index d873bc07f96effd01e5ff5852523d1685c3f1061..945f96519e3f60a8c7ed1c7483eacf9b8d0c4e47 100644 (file)
 #include "ardour/session.h"
 #include "ardour/slave.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
-using namespace MIDI;
 using namespace PBD;
 using namespace Timecode;
 
@@ -56,7 +55,7 @@ using namespace Timecode;
  * This filter is adaptive so that fast vari-speed signals
  * will not be affected by it.
  */
-#define LTC_RISE_TIME(speed) MIN (100, MAX(40, (4000000 / ((speed==0)?1:speed) / engine().frame_rate())))
+#define LTC_RISE_TIME(speed) MIN (100, MAX(40, (4000000 / ((speed==0)?1:speed) / engine().sample_rate())))
 
 #define TV_STANDARD(tcf) \
        (timecode_to_frames_per_second(tcf)==25.0 ? LTC_TV_625_50 : \
@@ -245,13 +244,26 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
        /* port latency compensation:
         * The _generated timecode_ is offset by the port-latency,
         * therefore the offset depends on the direction of transport.
+        *
+        * latency is compensated by adding it to the timecode to
+        * be generated. e.g. if the signal will reach the output in
+        * N samples time from now, generate the timecode for (now + N).
+        *
+        * sample-sync is achieved by further calculating the difference
+        * between the timecode and the session-transport and offsetting the
+        * buffer.
+        *
+        * The timecode is generated directly in the Session process callback
+        * using _transport_frame. It requires that the session has set the
+        * port's playback latency to worst_playback_latency() prior to
+        * calling ltc_tx_send_time_code_for_cycle().
         */
        framepos_t cycle_start_frame;
 
        if (current_speed < 0) {
-               cycle_start_frame = (start_frame - ltc_out_latency.max);
+               cycle_start_frame = (start_frame - ltc_out_latency.max + worst_playback_latency());
        } else if (current_speed > 0) {
-               cycle_start_frame = (start_frame + ltc_out_latency.max);
+               cycle_start_frame = (start_frame + ltc_out_latency.max - worst_playback_latency());
        } else {
                /* There is no need to compensate for latency when not rolling
                 * rather send the accurate NOW timecode
@@ -496,7 +508,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
 
                DEBUG_TRACE (DEBUG::LTC, string_compose("LTC TX4: now: %1 trs: %2 toff %3\n", cycle_start_frame, tc_sample_start, soff));
 
-               uint32_t cyc_off;
+               int32_t cyc_off;
                if (soff < 0 || soff >= fptcf) {
                        /* session framerate change between (2) and now */
                        ltc_tx_reset();
@@ -532,7 +544,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
                        restarting = true;
                }
 
-               if (cyc_off >= 0 && cyc_off <= nframes) {
+               if (cyc_off >= 0 && cyc_off <= (int32_t) nframes) {
                        /* offset in this cycle */
                        txf= rint(cyc_off / fabs(ltc_speed));
                        memset(out, 0, cyc_off * sizeof(Sample));
@@ -565,7 +577,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
                 * To do better than this, resampling (or a rewrite of the
                 * encoder) is required.
                 */
-               ltc_speed -= ((ltc_enc_pos + ltc_enc_cnt - poff) - cycle_start_frame) / engine().frame_rate();
+               ltc_speed -= ((ltc_enc_pos + ltc_enc_cnt - poff) - cycle_start_frame) / engine().sample_rate();
        }