projects
/
ardour.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
adjust to use timestamped MTC messages
[ardour.git]
/
libs
/
ardour
/
mtc_slave.cc
diff --git
a/libs/ardour/mtc_slave.cc
b/libs/ardour/mtc_slave.cc
index c502cb16a2dc27d86eda49e7cf311f9ea75a34c4..4ca86236b737c113f8587bdffabfad3f30b61d43 100644
(file)
--- a/
libs/ardour/mtc_slave.cc
+++ b/
libs/ardour/mtc_slave.cc
@@
-44,7
+44,8
@@
MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
: session (s)
{
can_notify_on_unknown_rate = true;
: session (s)
{
can_notify_on_unknown_rate = true;
-
+ did_reset_tc_format = false;
+
last_mtc_fps_byte = session.get_mtc_timecode_bits ();
rebind (p);
last_mtc_fps_byte = session.get_mtc_timecode_bits ();
rebind (p);
@@
-53,6
+54,9
@@
MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
MTC_Slave::~MTC_Slave()
{
MTC_Slave::~MTC_Slave()
{
+ if (did_reset_tc_format) {
+ session.config.set_timecode_format (saved_tc_format);
+ }
}
void
}
void
@@
-70,31
+74,51
@@
MTC_Slave::rebind (MIDI::Port& p)
}
void
}
void
-MTC_Slave::update_mtc_qtr (Parser& /*p*/)
+MTC_Slave::update_mtc_qtr (Parser& /*p*/
, int which_qtr, nframes_t now
)
{
{
- nframes64_t now = session.engine().frame_time();
- nframes_t qtr;
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("qtr frame %1 at %2, valid-for-time? %3\n", which_qtr, now, qtr_frame_messages_valid_for_time));
- qtr = (long) (session.frames_per_timecode_frame() / 4);
- mtc_frame += qtr;
-
- double speed = compute_apparent_speed (now);
+ if (qtr_frame_messages_valid_for_time) {
- current.guard1++;
- current.position = mtc_frame;
- current.timestamp = now;
- current.speed = speed;
- current.guard2++;
+ if (which_qtr != 7) {
+
+ /* leave position and speed updates for the last
+ qtr frame message of the 8 to be taken
+ care of in update_mtc_time(), invoked
+ by the Parser right after this.
+ */
- last_inbound_frame = now;
+ nframes_t qtr;
+
+ qtr = (long) (session.frames_per_timecode_frame() / 4);
+ mtc_frame += qtr;
+
+ double speed = compute_apparent_speed (now);
+
+ current.guard1++;
+ current.position = mtc_frame;
+ current.timestamp = now;
+ current.speed = speed;
+ current.guard2++;
+ }
+
+ last_inbound_frame = now;
+ }
}
void
}
void
-MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
+MTC_Slave::update_mtc_time (const byte *msg, bool was_full
, nframes_t now
)
{
{
- nframes64_t now = session.engine().frame_time();
- Timecode::Time timecode;
+ /* "now" can be zero if this is called from a context where we do not have or do not want
+ to use a timestamp indicating when this MTC time was received.
+ */
+ Timecode::Time timecode;
+ TimecodeFormat tc_format;
+ bool reset_tc = true;
+
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("full mtc time known at %1, full ? %2\n", now, was_full));
+
timecode.hours = msg[3];
timecode.minutes = msg[2];
timecode.seconds = msg[1];
timecode.hours = msg[3];
timecode.minutes = msg[2];
timecode.seconds = msg[1];
@@
-106,22
+130,26
@@
MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
case MTC_24_FPS:
timecode.rate = 24;
timecode.drop = false;
case MTC_24_FPS:
timecode.rate = 24;
timecode.drop = false;
+ tc_format = timecode_24;
can_notify_on_unknown_rate = true;
break;
case MTC_25_FPS:
timecode.rate = 25;
timecode.drop = false;
can_notify_on_unknown_rate = true;
break;
case MTC_25_FPS:
timecode.rate = 25;
timecode.drop = false;
+ tc_format = timecode_25;
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS_DROP:
timecode.rate = 30;
timecode.drop = true;
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS_DROP:
timecode.rate = 30;
timecode.drop = true;
+ tc_format = timecode_30drop;
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS:
timecode.rate = 30;
timecode.drop = false;
can_notify_on_unknown_rate = true;
can_notify_on_unknown_rate = true;
break;
case MTC_30_FPS:
timecode.rate = 30;
timecode.drop = false;
can_notify_on_unknown_rate = true;
+ tc_format = timecode_30;
break;
default:
/* throttle error messages about unknown MTC rates */
break;
default:
/* throttle error messages about unknown MTC rates */
@@
-133,44
+161,62
@@
MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
}
timecode.rate = session.timecode_frames_per_second();
timecode.drop = session.timecode_drop_frames();
}
timecode.rate = session.timecode_frames_per_second();
timecode.drop = session.timecode_drop_frames();
+ reset_tc = false;
}
}
- session.timecode_to_sample (timecode, mtc_frame, true, false);
+ if (reset_tc) {
+ if (!did_reset_tc_format) {
+ saved_tc_format = session.config.get_timecode_format();
+ did_reset_tc_format = true;
+ }
+ session.config.set_timecode_format (tc_format);
+ }
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC time timestamp = %1 TC %2 = frame %3 (from full message ? %4)\n",
now, timecode, mtc_frame, was_full));
if (was_full) {
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC time timestamp = %1 TC %2 = frame %3 (from full message ? %4)\n",
now, timecode, mtc_frame, was_full));
if (was_full) {
+ session.timecode_to_sample (timecode, mtc_frame, true, false);
session.request_locate (mtc_frame, false);
session.request_transport_speed (0);
update_mtc_status (MIDI::Parser::MTC_Stopped);
session.request_locate (mtc_frame, false);
session.request_transport_speed (0);
update_mtc_status (MIDI::Parser::MTC_Stopped);
+
reset ();
} else {
reset ();
} else {
-
+
+ /* we've had the first set of 8 qtr frame messages, determine position
+ and allow continuing qtr frame messages to provide position
+ and speed information.
+ */
+
+ qtr_frame_messages_valid_for_time = true;
+ session.timecode_to_sample (timecode, mtc_frame, true, false);
+
/* 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
/* 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.
- Also compensate for audio latency.
+ frames. Also compensate for audio latency.
*/
*/
-#if 0
- mtc_frame += (long) (1.75 * session.frames_per_timecode_frame()) + session.worst_output_latency();
-
- /* leave speed alone here. compute it only as we receive qtr frame messages */
- current.guard1++;
- current.position = mtc_frame;
- current.timestamp = now;
- current.guard2++;
+ mtc_frame += (long) (1.75 * session.frames_per_timecode_frame()) + session.worst_output_latency();
- DEBUG_TRACE (DEBUG::MTC, string_compose ("stored TC frame = %1 @ %2, sp = %3\n", mtc_frame, now, speed));
-#endif
+ if (now) {
+ double speed = compute_apparent_speed (now);
+
+ current.guard1++;
+ current.position = mtc_frame;
+ current.timestamp = now;
+ current.speed = speed;
+ current.guard2++;
+ }
}
}
- last_inbound_frame = now;
+ if (now) {
+ last_inbound_frame = now;
+ }
}
double
}
double
@@
-179,9
+225,11
@@
MTC_Slave::compute_apparent_speed (nframes64_t now)
if (current.timestamp != 0) {
double speed = (double) ((mtc_frame - current.position) / (double) (now - current.timestamp));
if (current.timestamp != 0) {
double speed = (double) ((mtc_frame - current.position) / (double) (now - current.timestamp));
- DEBUG_TRACE (DEBUG::MTC, string_compose ("instantaneous speed = %1 from %2
- %3 / %4 - %5
\n",
- speed, mtc_frame
, current.position, now,
current.timestamp));
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("instantaneous speed = %1 from %2
/ %3
\n",
+ speed, mtc_frame
- current.position, now -
current.timestamp));
+ /* crude low pass filter/smoother for speed */
+
accumulator[accumulator_index++] = speed;
if (accumulator_index >= accumulator_size) {
accumulator[accumulator_index++] = speed;
if (accumulator_index >= accumulator_size) {
@@
-219,7
+267,7
@@
MTC_Slave::handle_locate (const MIDI::byte* mmc_tc)
mtc[1] = mmc_tc[2];
mtc[0] = mmc_tc[3];
mtc[1] = mmc_tc[2];
mtc[0] = mmc_tc[3];
- update_mtc_time (mtc, true);
+ update_mtc_time (mtc, true
, 0
);
}
void
}
void
@@
-334,7
+382,9
@@
MTC_Slave::speed_and_position (double& speed, nframes64_t& pos)
/* scale elapsed time by the current MTC speed */
if (last.timestamp && (now > last.timestamp)) {
/* scale elapsed time by the current MTC speed */
if (last.timestamp && (now > last.timestamp)) {
- elapsed = (nframes_t) floor (speed * (now - last.timestamp));
+ elapsed = (nframes_t) floor (last.speed * (now - last.timestamp));
+ DEBUG_TRACE (DEBUG::MTC, string_compose ("last timecode received @ %1, now = %2, elapsed frames = %3 w/speed= %4\n",
+ last.timestamp, now, elapsed, speed));
} else {
elapsed = 0; /* XXX is this right? */
}
} else {
elapsed = 0; /* XXX is this right? */
}
@@
-374,4
+424,5
@@
MTC_Slave::reset ()
current.guard2++;
accumulator_index = 0;
have_first_accumulated_speed = false;
current.guard2++;
accumulator_index = 0;
have_first_accumulated_speed = false;
+ qtr_frame_messages_valid_for_time = false;
}
}