From ea29eb0d7dcc334b87f6ac3a8f884a5edb7d2ed4 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 2 Mar 2013 22:52:39 +0000 Subject: [PATCH] fix MTC slave+generator for non integer quarter_frame_duration e.g. 44.1k [SPS] / 30 [fps] / 4 [MTC-frames per timecode-frame] = 367.5 [samples per MTC-frame] git-svn-id: svn://localhost/ardour2/branches/3.0@14115 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/session.h | 2 +- libs/ardour/ardour/slave.h | 3 ++- libs/ardour/mtc_slave.cc | 8 +++++--- libs/ardour/session_midi.cc | 18 ++++++++++-------- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 414a3204bd..a012aac599 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1169,7 +1169,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi MIDI::byte mtc_msg[16]; MIDI::byte mtc_timecode_bits; /* encoding of SMTPE type for MTC */ MIDI::byte midi_msg[16]; - framepos_t outbound_mtc_timecode_frame; + double outbound_mtc_timecode_frame; Timecode::Time transmitting_timecode_time; int next_quarter_frame_to_send; diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 471a632f6e..508664e31b 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -240,7 +240,7 @@ class TimecodeSlave : public Slave { virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0; /* this is intended to be used by a UI and polled from a timeout. it should - return a string describing the current position of the TC source. it + return a string describing the current position of the TC source. it should NOT do any computation, but should use a cached value of the TC source position. */ @@ -282,6 +282,7 @@ class MTC_Slave : public TimecodeSlave { SafeTime current; framepos_t mtc_frame; /* current time */ + double mtc_frame_dll; framepos_t last_inbound_frame; /* when we got it; audio clocked */ MIDI::byte last_mtc_fps_byte; framepos_t window_begin; diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index b3992598d3..a1005ff953 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -56,6 +56,7 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) reset_pending = 0; reset_position = false; mtc_frame = 0; + mtc_frame_dll = 0; engine_dll_initstate = 0; busy_guard1 = busy_guard2 = 0; @@ -261,16 +262,16 @@ MTC_Slave::update_mtc_qtr (Parser& /*p*/, int which_qtr, framepos_t now) { busy_guard1++; const double qtr_d = quarter_frame_duration; - const framepos_t qtr = rint(qtr_d); - mtc_frame += qtr * transport_direction; + mtc_frame_dll += qtr_d * (double) transport_direction; + mtc_frame = rint(mtc_frame_dll); DEBUG_TRACE (DEBUG::MTC, string_compose ("qtr frame %1 at %2 -> mtc_frame: %3\n", which_qtr, now, mtc_frame)); double mtc_speed = 0; if (first_mtc_timestamp != 0) { /* update MTC DLL and calculate speed */ - const double e = mtc_frame - (double(transport_direction) * (double(now) - double(current.timestamp) + t0)); + const double e = mtc_frame_dll - (double)transport_direction * ((double)now - (double)current.timestamp + t0); t0 = t1; t1 += b * e + e2; e2 += c * e; @@ -463,6 +464,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now) if (first_mtc_timestamp == 0 || current.timestamp == 0) { first_mtc_timestamp = now; init_mtc_dll(mtc_frame, qtr); + mtc_frame_dll = mtc_frame; } current.guard1++; current.position = mtc_frame; diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 69de04de72..50a7178f1b 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -369,12 +369,14 @@ Session::send_full_time_code (framepos_t const t) sample_to_timecode (t, timecode, true /* use_offset */, false /* no subframes */); // sample-align outbound to rounded (no subframes) timecode - timecode_to_sample(timecode, outbound_mtc_timecode_frame, true, false); + framepos_t mtc_tc; + timecode_to_sample(timecode, mtc_tc, true, false); + outbound_mtc_timecode_frame = mtc_tc; transmitting_timecode_time = timecode; - framecnt_t const quarter_frame_duration = ((framecnt_t) _frames_per_timecode_frame) >> 2; - if (ceil((t - outbound_mtc_timecode_frame) / quarter_frame_duration) > 0) { + double const quarter_frame_duration = ((framecnt_t) _frames_per_timecode_frame) / 4.0; + if (ceil((t - mtc_tc) / quarter_frame_duration) > 0) { Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); outbound_mtc_timecode_frame += _frames_per_timecode_frame; } @@ -460,19 +462,19 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f assert (next_quarter_frame_to_send <= 7); /* Duration of one quarter frame */ - framecnt_t const quarter_frame_duration = ((framecnt_t) _frames_per_timecode_frame) >> 2; + double const quarter_frame_duration = _frames_per_timecode_frame / 4.0; DEBUG_TRACE (DEBUG::MTC, string_compose ("TF %1 SF %2 MT %3 QF %4 QD %5\n", _transport_frame, start_frame, outbound_mtc_timecode_frame, next_quarter_frame_to_send, quarter_frame_duration)); - if ((outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < _transport_frame) { + if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < _transport_frame) { send_full_time_code (_transport_frame); return 0; } /* Send quarter frames for this cycle */ - while (end_frame > (outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration))) { + while (end_frame > rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration))) { DEBUG_TRACE (DEBUG::MTC, string_compose ("next frame to send: %1\n", next_quarter_frame_to_send)); @@ -503,7 +505,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f break; } - const framepos_t msg_time = outbound_mtc_timecode_frame + (quarter_frame_duration * next_quarter_frame_to_send); + const framepos_t msg_time = rint(outbound_mtc_timecode_frame + (quarter_frame_duration * next_quarter_frame_to_send)); // This message must fall within this block or something is broken assert (msg_time >= start_frame); @@ -538,7 +540,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame()); // Re-calculate timing of first quarter frame //timecode_to_sample( transmitting_timecode_time, outbound_mtc_timecode_frame, true /* use_offset */, false ); - outbound_mtc_timecode_frame += 8 * quarter_frame_duration; + outbound_mtc_timecode_frame += 2.0 * _frames_per_timecode_frame; } }