some fixes/tweaks for MTC slaving, some untested

git-svn-id: svn://localhost/ardour2/branches/3.0@6676 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-02-11 18:00:50 +00:00
parent 3a27410dcb
commit 47018a3bd1
5 changed files with 68 additions and 40 deletions

View file

@ -94,6 +94,12 @@ class AudioEngine : public SessionHandlePtr
return jack_frame_time (_priv_jack); return jack_frame_time (_priv_jack);
} }
nframes_t frame_time_at_cycle_start () {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) return 0;
return jack_last_frame_time (_priv_jack);
}
nframes_t transport_frame () const { nframes_t transport_frame () const {
const jack_client_t* _priv_jack = _jack; const jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) return 0; if (!_running || !_priv_jack) return 0;

View file

@ -60,7 +60,7 @@ class PIChaser {
PIChaser(); PIChaser();
~PIChaser(); ~PIChaser();
double get_ratio( nframes64_t realtime, nframes64_t chasetime, nframes64_t slavetime, bool in_control ); double get_ratio( nframes64_t chasetime_measured, nframes64_t chasetime, nframes64_t slavetime_measured, nframes64_t slavetime, bool in_control );
void reset(); void reset();
nframes64_t want_locate() { return want_locate_val; } nframes64_t want_locate() { return want_locate_val; }

View file

@ -264,10 +264,11 @@ class MTC_Slave : public Slave {
bool have_first_speed_accumulator; bool have_first_speed_accumulator;
double average_speed; double average_speed;
Glib::Mutex reset_lock; Glib::Mutex reset_lock;
bool reset_pending; uint32_t reset_pending;
bool reset_position;
void reset (); void reset (bool with_pos);
void queue_reset (); void queue_reset (bool with_pos);
void maybe_reset (); void maybe_reset ();
void update_mtc_qtr (MIDI::Parser&, int, nframes_t); void update_mtc_qtr (MIDI::Parser&, int, nframes_t);

View file

@ -56,7 +56,8 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
{ {
can_notify_on_unknown_rate = true; can_notify_on_unknown_rate = true;
did_reset_tc_format = false; did_reset_tc_format = false;
reset_pending = false; reset_pending = 0;
reset_position = false;
pic = new PIChaser(); pic = new PIChaser();
@ -67,7 +68,7 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
speed_accumulator = new double[speed_accumulator_size]; speed_accumulator = new double[speed_accumulator_size];
rebind (p); rebind (p);
reset (); reset (true);
} }
MTC_Slave::~MTC_Slave() MTC_Slave::~MTC_Slave()
@ -188,7 +189,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, nframes_t now)
session.request_locate (mtc_frame, false); session.request_locate (mtc_frame, false);
session.request_transport_speed (0); session.request_transport_speed (0);
update_mtc_status (MIDI::MTC_Stopped); update_mtc_status (MIDI::MTC_Stopped);
reset (); reset (false);
reset_window (mtc_frame); reset_window (mtc_frame);
} else { } else {
@ -395,6 +396,7 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos)
nframes64_t now = session.engine().frame_time(); nframes64_t now = session.engine().frame_time();
SafeTime last; SafeTime last;
nframes_t elapsed; nframes_t elapsed;
bool in_control = false;
read_current (&last); read_current (&last);
@ -412,7 +414,7 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos)
pos = last.position; pos = last.position;
session.request_locate (pos, false); session.request_locate (pos, false);
session.request_transport_speed (0); session.request_transport_speed (0);
queue_reset (); queue_reset (false);
DEBUG_TRACE (DEBUG::MTC, "MTC not seen for 1/4 second - reset pending\n"); DEBUG_TRACE (DEBUG::MTC, "MTC not seen for 1/4 second - reset pending\n");
return false; return false;
} }
@ -420,13 +422,15 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos)
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position %1 %2\n", last.speed, last.position)); DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position %1 %2\n", last.speed, last.position));
if (give_slave_full_control_over_transport_speed()) { if (give_slave_full_control_over_transport_speed()) {
bool in_control = (session.slave_state() == Session::Running); in_control = (session.slave_state() == Session::Running);
nframes64_t pic_want_locate = 0; nframes64_t pic_want_locate = 0;
//nframes64_t slave_pos = session.audible_frame(); //nframes64_t slave_pos = session.audible_frame();
nframes64_t slave_pos = session.transport_frame(); nframes64_t slave_pos = session.transport_frame();
static double average_speed = 0; static double average_speed = 0;
average_speed = pic->get_ratio (last.timestamp, last.position, slave_pos, in_control ); nframes64_t ref_now = session.engine().frame_time_at_cycle_start();
average_speed = pic->get_ratio (last.timestamp, last.position, ref_now, slave_pos, in_control );
pic_want_locate = pic->want_locate(); pic_want_locate = pic->want_locate();
if (in_control && pic_want_locate) { if (in_control && pic_want_locate) {
@ -456,7 +460,12 @@ MTC_Slave::speed_and_position (double& speed, nframes64_t& pos)
/* now add the most recent timecode value plus the estimated elapsed interval */ /* now add the most recent timecode value plus the estimated elapsed interval */
if (in_control) {
pos = session.transport_frame();
} else {
pos = last.position + elapsed; pos = last.position + elapsed;
}
speed = last.speed; speed = last.speed;
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position FINAL %1 %2\n", last.speed, pos)); DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::speed_and_position FINAL %1 %2\n", last.speed, pos));
@ -471,34 +480,44 @@ MTC_Slave::resolution() const
} }
void void
MTC_Slave::queue_reset () MTC_Slave::queue_reset (bool reset_pos)
{ {
Glib::Mutex::Lock lm (reset_lock); Glib::Mutex::Lock lm (reset_lock);
reset_pending++; reset_pending++;
if (reset_pos) {
reset_position = true;
}
} }
void void
MTC_Slave::maybe_reset () MTC_Slave::maybe_reset ()
{ {
reset_lock.lock (); Glib::Mutex::Lock lm (reset_lock);
if (reset_pending) { if (reset_pending) {
reset (); reset (reset_position);
reset_pending = 0; reset_pending = 0;
reset_position = false;
} }
reset_lock.unlock ();
} }
void void
MTC_Slave::reset () MTC_Slave::reset (bool with_position)
{ {
if (with_position) {
last_inbound_frame = 0; last_inbound_frame = 0;
current.guard1++; current.guard1++;
current.position = 0; current.position = 0;
current.timestamp = 0; current.timestamp = 0;
current.speed = 0; current.speed = 0;
current.guard2++; current.guard2++;
} else {
last_inbound_frame = 0;
current.guard1++;
current.timestamp = 0;
current.speed = 0;
current.guard2++;
}
window_begin = 0; window_begin = 0;
window_end = 0; window_end = 0;

View file

@ -151,13 +151,15 @@ PIChaser::~PIChaser() {
} }
double double
PIChaser::get_ratio(nframes64_t realtime, nframes64_t chasetime, nframes64_t slavetime, bool in_control ) { PIChaser::get_ratio(nframes64_t chasetime_measured, nframes64_t chasetime, nframes64_t slavetime_measured, nframes64_t slavetime, bool in_control ) {
feed_estimator( realtime, chasetime ); feed_estimator( chasetime_measured, chasetime );
std::cerr << (double)realtime/48000.0 << " " << chasetime << " " << slavetime << " "; std::cerr << (double)chasetime_measured/48000.0 << " " << chasetime << " " << slavetime << " ";
double crude = get_estimate(); double crude = get_estimate();
double fine; double fine;
nframes64_t massaged_chasetime = chasetime + (nframes64_t)( (double)(slavetime_measured - chasetime_measured) * crude );
fine = pic->get_ratio( slavetime - massaged_chasetime );
fine = pic->get_ratio( slavetime - chasetime ); fine = pic->get_ratio( slavetime - chasetime );
if (in_control) { if (in_control) {
if (fabs(fine-crude) > crude*speed_threshold) { if (fabs(fine-crude) > crude*speed_threshold) {