summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-12-01 13:24:08 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-12-01 13:24:08 +0000
commitd2426538ad8230e62cf4c8f225e6e974aea9e115 (patch)
tree19493346dd56436dfe2886c1fbea4ed43aaada93 /libs
parentea08bbe621c146a0940ce584e2b970dcb7d7c9e2 (diff)
more changes to try to improve MTC handling even in slightly pathological cases
git-svn-id: svn://localhost/ardour2/branches/3.0@6245 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/slave.h7
-rw-r--r--libs/ardour/mtc_slave.cc88
-rw-r--r--libs/ardour/session_time.cc3
-rw-r--r--libs/midi++2/midi++/parser.h4
-rw-r--r--libs/midi++2/mtc.cc4
5 files changed, 77 insertions, 29 deletions
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h
index 672d72f7e2..af69348d4e 100644
--- a/libs/ardour/ardour/slave.h
+++ b/libs/ardour/ardour/slave.h
@@ -234,6 +234,10 @@ class MTC_Slave : public Slave, public sigc::trackable {
nframes_t mtc_frame; /* current time */
nframes_t last_inbound_frame; /* when we got it; audio clocked */
MIDI::byte last_mtc_fps_byte;
+ bool qtr_frame_messages_valid_for_time;
+
+ bool did_reset_tc_format;
+ TimecodeFormat saved_tc_format;
static const int32_t accumulator_size = 128;
double accumulator[accumulator_size];
@@ -241,11 +245,12 @@ class MTC_Slave : public Slave, public sigc::trackable {
bool have_first_accumulated_speed;
void reset ();
- void update_mtc_qtr (MIDI::Parser&);
+ void update_mtc_qtr (MIDI::Parser&, int);
void update_mtc_time (const MIDI::byte *, bool);
void update_mtc_status (MIDI::Parser::MTC_Status);
void read_current (SafeTime *) const;
double compute_apparent_speed (nframes64_t);
+
};
class MIDIClock_Slave : public Slave, public sigc::trackable {
diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc
index c502cb16a2..44386b647f 100644
--- 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;
-
+ did_reset_tc_format = false;
+
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()
{
+ if (did_reset_tc_format) {
+ session.config.set_timecode_format (saved_tc_format);
+ }
}
void
@@ -70,23 +74,36 @@ MTC_Slave::rebind (MIDI::Port& p)
}
void
-MTC_Slave::update_mtc_qtr (Parser& /*p*/)
+MTC_Slave::update_mtc_qtr (Parser& /*p*/, int which_qtr)
{
- nframes64_t now = session.engine().frame_time();
- nframes_t qtr;
+ if (qtr_frame_messages_valid_for_time) {
+
+ nframes64_t now = session.engine().frame_time();
- qtr = (long) (session.frames_per_timecode_frame() / 4);
- mtc_frame += qtr;
-
- double speed = compute_apparent_speed (now);
+ if (which_qtr != 7) {
- current.guard1++;
- current.position = mtc_frame;
- current.timestamp = now;
- current.speed = speed;
- current.guard2++;
+ /* 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
@@ -94,6 +111,8 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
{
nframes64_t now = session.engine().frame_time();
Timecode::Time timecode;
+ TimecodeFormat tc_format;
+ bool reset_tc = true;
timecode.hours = msg[3];
timecode.minutes = msg[2];
@@ -106,22 +125,26 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
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;
+ tc_format = timecode_25;
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;
+ tc_format = timecode_30;
break;
default:
/* throttle error messages about unknown MTC rates */
@@ -133,41 +156,55 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
}
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) {
+ 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);
+
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
- 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 */
+
+ double speed = compute_apparent_speed (now);
current.guard1++;
current.position = mtc_frame;
current.timestamp = now;
+ current.speed = speed;
current.guard2++;
-
- DEBUG_TRACE (DEBUG::MTC, string_compose ("stored TC frame = %1 @ %2, sp = %3\n", mtc_frame, now, speed));
-#endif
}
last_inbound_frame = now;
@@ -182,6 +219,8 @@ MTC_Slave::compute_apparent_speed (nframes64_t now)
DEBUG_TRACE (DEBUG::MTC, string_compose ("instantaneous speed = %1 from %2 - %3 / %4 - %5\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) {
@@ -374,4 +413,5 @@ MTC_Slave::reset ()
current.guard2++;
accumulator_index = 0;
have_first_accumulated_speed = false;
+ qtr_frame_messages_valid_for_time = false;
}
diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc
index 1e1ecd3ed9..c913a5cb64 100644
--- a/libs/ardour/session_time.cc
+++ b/libs/ardour/session_time.cc
@@ -147,8 +147,9 @@ Session::timecode_drop_frames() const
break;
default:
- cerr << "Editor received unexpected timecode type" << endl;
+ error << "Editor received unexpected timecode type" << endmsg;
}
+
return false;
}
void
diff --git a/libs/midi++2/midi++/parser.h b/libs/midi++2/midi++/parser.h
index 5baa3af4b6..ea89076225 100644
--- a/libs/midi++2/midi++/parser.h
+++ b/libs/midi++2/midi++/parser.h
@@ -74,8 +74,8 @@ class Parser : public sigc::trackable {
Signal position;
Signal song;
- Signal mtc;
- sigc::signal<void,Parser&> mtc_qtr;
+ Signal mtc;
+ sigc::signal<void,Parser&,int> mtc_qtr;
sigc::signal<void, Parser &> all_notes_off;
sigc::signal<void, Parser &> tune;
diff --git a/libs/midi++2/mtc.cc b/libs/midi++2/mtc.cc
index da85aa11fd..bd3205a8c1 100644
--- a/libs/midi++2/mtc.cc
+++ b/libs/midi++2/mtc.cc
@@ -226,7 +226,9 @@ Parser::process_mtc_quarter_frame (byte *msg)
/* time code is looking good */
+#ifdef DEBUG_MTC
cerr << "for quarter frame " << which_quarter_frame << " byte = " << hex << (int) msg[1] << dec << endl;
+#endif
switch (which_quarter_frame) {
case 0: // frames LS nibble
@@ -275,7 +277,7 @@ Parser::process_mtc_quarter_frame (byte *msg)
}
- mtc_qtr (*this); /* EMIT_SIGNAL */
+ mtc_qtr (*this, which_quarter_frame); /* EMIT_SIGNAL */
// mtc (*this, &msg[1], msglen - 1);