* 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
This commit is contained in:
parent
838ed37aff
commit
5ee4d2bb24
@ -1079,6 +1079,13 @@ class Session : public PBD::StatefulDestructible
|
|||||||
|
|
||||||
void reset_slave_state ();
|
void reset_slave_state ();
|
||||||
bool follow_slave (nframes_t, nframes_t);
|
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);
|
void set_slave_source (SlaveSource);
|
||||||
|
|
||||||
SlaveSource post_export_slave;
|
SlaveSource post_export_slave;
|
||||||
|
@ -103,6 +103,7 @@ class Slave {
|
|||||||
*
|
*
|
||||||
* @param speed - The transport speed requested
|
* @param speed - The transport speed requested
|
||||||
* @param position - The transport position 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;
|
virtual bool speed_and_position (float& speed, nframes_t& position) = 0;
|
||||||
|
|
||||||
|
@ -495,16 +495,6 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
|
|||||||
slave_speed = 0.0f;
|
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 (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) {
|
||||||
|
|
||||||
/* if the TC source is synced, then we assume that its
|
/* if the TC source is synced, then we assume that its
|
||||||
@ -522,6 +512,126 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
|
|||||||
our speed to remain locked.
|
our speed to remain locked.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
calculate_moving_average_of_slave_delta(dir, this_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
track_slave_state(slave_speed, slave_transport_frame, this_delta, starting);
|
||||||
|
|
||||||
|
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:" <<endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (slave_speed && _transport_speed) {
|
||||||
|
|
||||||
|
/* something isn't right, but we should move with the master
|
||||||
|
for now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool need_butler;
|
||||||
|
|
||||||
|
prepare_diskstreams ();
|
||||||
|
silent_process_routes (nframes, offset);
|
||||||
|
commit_diskstreams (nframes, need_butler);
|
||||||
|
|
||||||
|
if (need_butler) {
|
||||||
|
summon_butler ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
|
||||||
|
|
||||||
|
if (frames_moved < 0) {
|
||||||
|
decrement_transport_position (-frames_moved);
|
||||||
|
} else {
|
||||||
|
increment_transport_position (frames_moved);
|
||||||
|
}
|
||||||
|
|
||||||
|
nframes_t stop_limit;
|
||||||
|
|
||||||
|
if (actively_recording()) {
|
||||||
|
stop_limit = max_frames;
|
||||||
|
} else {
|
||||||
|
if (Config->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:" <<endl;
|
||||||
|
#endif
|
||||||
|
no_roll (nframes, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
|
||||||
|
{
|
||||||
if (delta_accumulator_cnt >= delta_accumulator_size) {
|
if (delta_accumulator_cnt >= delta_accumulator_size) {
|
||||||
have_first_delta_accumulator = true;
|
have_first_delta_accumulator = true;
|
||||||
delta_accumulator_cnt = 0;
|
delta_accumulator_cnt = 0;
|
||||||
@ -546,6 +656,13 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Session::track_slave_state(
|
||||||
|
float slave_speed,
|
||||||
|
nframes_t slave_transport_frame,
|
||||||
|
nframes_t this_delta,
|
||||||
|
bool starting)
|
||||||
|
{
|
||||||
if (slave_speed != 0.0f) {
|
if (slave_speed != 0.0f) {
|
||||||
|
|
||||||
/* slave is running */
|
/* slave is running */
|
||||||
@ -631,7 +748,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
|
|||||||
start_transport ();
|
start_transport ();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else { // slave_speed is 0
|
||||||
|
|
||||||
/* slave has stopped */
|
/* slave has stopped */
|
||||||
|
|
||||||
@ -658,104 +775,6 @@ Session::follow_slave (nframes_t nframes, nframes_t offset)
|
|||||||
|
|
||||||
slave_state = Stopped;
|
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:" <<endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (slave_speed && _transport_speed) {
|
|
||||||
|
|
||||||
/* something isn't right, but we should move with the master
|
|
||||||
for now.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool need_butler;
|
|
||||||
|
|
||||||
prepare_diskstreams ();
|
|
||||||
silent_process_routes (nframes, offset);
|
|
||||||
commit_diskstreams (nframes, need_butler);
|
|
||||||
|
|
||||||
if (need_butler) {
|
|
||||||
summon_butler ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
|
|
||||||
|
|
||||||
if (frames_moved < 0) {
|
|
||||||
decrement_transport_position (-frames_moved);
|
|
||||||
} else {
|
|
||||||
increment_transport_position (frames_moved);
|
|
||||||
}
|
|
||||||
|
|
||||||
nframes_t stop_limit;
|
|
||||||
|
|
||||||
if (actively_recording()) {
|
|
||||||
stop_limit = max_frames;
|
|
||||||
} else {
|
|
||||||
if (Config->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:" <<endl;
|
|
||||||
#endif
|
|
||||||
no_roll (nframes, 0);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user