#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;
/* 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
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();
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));