From 5ee4d2bb24c294c5dd3887135f72c53d0936d827 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Thu, 1 Jan 2009 21:26:23 +0000 Subject: [PATCH] * refactor Session::follow_slave to be easier to read and understand git-svn-id: svn://localhost/ardour2/branches/3.0@4370 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/session.h | 7 + libs/ardour/ardour/slave.h | 1 + libs/ardour/session_process.cc | 275 ++++++++++++++++++--------------- 3 files changed, 155 insertions(+), 128 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 16db305f94..180bb3dc8d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1079,6 +1079,13 @@ class Session : public PBD::StatefulDestructible void reset_slave_state (); bool follow_slave (nframes_t, nframes_t); + void calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta); + void track_slave_state( + float slave_speed, + nframes_t slave_transport_frame, + nframes_t this_delta, + bool starting); + void set_slave_source (SlaveSource); SlaveSource post_export_slave; diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index 1f21e28f40..2c9ef70cac 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -103,6 +103,7 @@ class Slave { * * @param speed - The transport speed requested * @param position - The transport position requested + * @return - The return value is currently ignored (see Session::follow_slave) */ virtual bool speed_and_position (float& speed, nframes_t& position) = 0; diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 1ceb2b70fa..b0c838bf8a 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -495,16 +495,6 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) slave_speed = 0.0f; } -#ifdef DEBUG_SLAVES - if (slave_speed != 0.0) - cerr << "delta = " << (int) (dir * this_delta) - << " speed = " << slave_speed - << " ts = " << _transport_speed - << " M@ "<< slave_transport_frame << " S@ " << _transport_frame - << " avgdelta = " << average_slave_delta - << endl; -#endif - if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) { /* if the TC source is synced, then we assume that its @@ -522,30 +512,157 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) our speed to remain locked. */ - if (delta_accumulator_cnt >= delta_accumulator_size) { - have_first_delta_accumulator = true; - delta_accumulator_cnt = 0; - } + calculate_moving_average_of_slave_delta(dir, this_delta); + } + + track_slave_state(slave_speed, slave_transport_frame, this_delta, starting); - if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) { - delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta); - } - - if (have_first_delta_accumulator) { - average_slave_delta = 0L; - for (int i = 0; i < delta_accumulator_size; ++i) { - average_slave_delta += delta_accumulator[i]; - } - average_slave_delta /= long(delta_accumulator_size); - if (average_slave_delta < 0L) { - average_dir = -1; - average_slave_delta = abs(average_slave_delta); - } else { - average_dir = 1; + if (slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) { + + if (_transport_speed != 0.0f) { + + /* + note that average_dir is +1 or -1 + */ + + float delta; + + #ifdef USE_MOVING_AVERAGE_OF_SLAVE + if (average_slave_delta == 0) { + delta = this_delta; + delta *= dir; + } else { + delta = average_slave_delta; + delta *= average_dir; + } + #else + delta = this_delta; + delta *= dir; + #endif + + float adjusted_speed = slave_speed + + (delta / float(_current_frame_rate)); + + #ifdef DEBUG_SLAVES + cerr << "adjust using " << delta + << " towards " << adjusted_speed + << " ratio = " << adjusted_speed / slave_speed + << " current = " << _transport_speed + << " slave @ " << slave_speed + << endl; + #endif + + request_transport_speed (adjusted_speed); + + if (abs(average_slave_delta) > (long) _slave->resolution()) { + cerr << "average slave delta greater than slave resolution, going to silent motion\n"; + goto silent_motion; } } + } + + #ifdef DEBUG_SLAVES + if (slave_speed != 0.0) + cerr << "delta = " << (int) (dir * this_delta) + << " speed = " << slave_speed + << " ts = " << _transport_speed + << " M@ "<< slave_transport_frame << " S@ " << _transport_frame + << " avgdelta = " << average_slave_delta + << endl; + #endif + + if (!starting && !non_realtime_work_pending()) { + /* speed is set, we're locked, and good to go */ + return true; } + silent_motion: +#ifdef DEBUG_SLAVES + cerr << "reached silent_motion:" <get_stop_at_session_end()) { + stop_limit = current_end_frame(); + } else { + stop_limit = max_frames; + } + } + + maybe_stop (stop_limit); + } + + noroll: + /* don't move at all */ +#ifdef DEBUG_SLAVES + cerr << "reached no_roll:" <= delta_accumulator_size) { + have_first_delta_accumulator = true; + delta_accumulator_cnt = 0; + } + + if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) { + delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta); + } + + if (have_first_delta_accumulator) { + average_slave_delta = 0L; + for (int i = 0; i < delta_accumulator_size; ++i) { + average_slave_delta += delta_accumulator[i]; + } + average_slave_delta /= long(delta_accumulator_size); + if (average_slave_delta < 0L) { + average_dir = -1; + average_slave_delta = abs(average_slave_delta); + } else { + average_dir = 1; + } + } +} + +void +Session::track_slave_state( + float slave_speed, + nframes_t slave_transport_frame, + nframes_t this_delta, + bool starting) +{ if (slave_speed != 0.0f) { /* slave is running */ @@ -631,7 +748,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) start_transport (); } - } else { + } else { // slave_speed is 0 /* slave has stopped */ @@ -658,104 +775,6 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) slave_state = Stopped; } - - if (slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) { - - - if (_transport_speed != 0.0f) { - - /* - note that average_dir is +1 or -1 - */ - - const float adjust_seconds = 1.0f; - float delta; - - //if (average_slave_delta == 0) { - delta = this_delta; - delta *= dir; -// } else { -// delta = average_slave_delta; -// delta *= average_dir; -// } - - float adjusted_speed = slave_speed + - (delta / (adjust_seconds * _current_frame_rate)); - -#ifdef DEBUG_DELAY_LOCKED_LOOP - cerr << "adjust using " << delta - << " towards " << adjusted_speed - << " ratio = " << adjusted_speed / slave_speed - << " current = " << _transport_speed - << " slave @ " << slave_speed - << endl; -#endif - - request_transport_speed (adjusted_speed); - - if (abs(average_slave_delta) > (long) _slave->resolution()) { - cerr << "average slave delta greater than slave resolution, going to silent motion\n"; - goto silent_motion; - } - } - } - - if (!starting && !non_realtime_work_pending()) { - /* speed is set, we're locked, and good to go */ - return true; - } - - silent_motion: -#ifdef DEBUG_SLAVES - cerr << "reached silent_motion:" <get_stop_at_session_end()) { - stop_limit = current_end_frame(); - } else { - stop_limit = max_frames; - } - } - - maybe_stop (stop_limit); - } - - noroll: - /* don't move at all */ -#ifdef DEBUG_SLAVES - cerr << "reached no_roll:" <