attempt to fix roll delay logic by moving it into DiskReader (the only place it matters)

This commit is contained in:
Paul Davis 2017-09-19 18:53:27 -04:00
parent cb71d49dc6
commit 48d11000e5
5 changed files with 67 additions and 57 deletions

View file

@ -627,7 +627,6 @@ public:
bool _active;
samplecnt_t _signal_latency;
samplecnt_t _initial_delay;
samplecnt_t _roll_delay;
ProcessorList _processors;
mutable Glib::Threads::RWLock _processor_lock;

View file

@ -72,7 +72,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
bool can_record();
void set_latency_compensation (samplecnt_t);
void update_latency_information ();
enum FreezeState {
NoFreeze,
@ -228,7 +227,6 @@ class LIBARDOUR_API Track : public Route, public Recordable
virtual void record_enable_changed (bool, PBD::Controllable::GroupControlDisposition);
virtual void record_safe_changed (bool, PBD::Controllable::GroupControlDisposition);
samplecnt_t check_initial_delay (samplecnt_t nframes, samplepos_t&);
virtual void monitoring_changed (bool, PBD::Controllable::GroupControlDisposition);
AlignChoice _alignment_choice;

View file

@ -129,6 +129,7 @@ DiskReader::set_name (string const & str)
void
DiskReader::set_roll_delay (ARDOUR::samplecnt_t nframes)
{
/* Must be called from process context or with process lock held */
_roll_delay = nframes;
}
@ -278,14 +279,38 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
disk_samples_to_consume = nframes;
}
bool roll_delayed = false;
samplecnt_t roll_delay_offset = 0;
if (speed != 0.0) {
if (_roll_delay > disk_samples_to_consume) {
/* still waiting for _roll_delay to end */
_roll_delay -= disk_samples_to_consume;
/* we could set disk_samples_to_consume to zero here, but it
won't be used anyway.
*/
roll_delayed = true;
} else if (_roll_delay > 0) {
/* roll delay will end during this call to ::run(), but
* there's some silence needed in the signal-from-disk first
*/
roll_delay_offset = _roll_delay;
bufs.silence (_roll_delay, 0);
disk_samples_to_consume -= _roll_delay;
start_sample += _roll_delay;
_roll_delay = 0;
}
}
BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count()));
const bool still_locating = _session.global_locate_pending();
if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output) {
if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output || roll_delayed) {
/* no need for actual disk data, just advance read pointer and return */
if (!still_locating || _no_disk_output) {
if (!roll_delayed && (!still_locating || _no_disk_output)) {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->buf->increment_read_ptr (disk_samples_to_consume);
}
@ -293,7 +318,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
/* if monitoring disk but locating put silence in the buffers */
if ((_no_disk_output || still_locating) && (ms == MonitoringDisk)) {
if ((roll_delayed || _no_disk_output || still_locating) && (ms == MonitoringDisk)) {
bufs.silence (nframes, 0);
}
@ -325,13 +350,35 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
disk_signal = output.data ();
}
/* if we skipped some number of samples at the start
because of the _roll_delay being non-zero but small
enough that we will process some data from disk,
advance where we're going to write that data to,
thus skipping over the silence that was written
there.
*/
disk_signal += roll_delay_offset;
assert (start_sample >= playback_sample);
if (start_sample != playback_sample) {
cerr << owner()->name() << " playback not aligned, jump ahead " << (start_sample - playback_sample) << endl;
if (can_internal_playback_seek (start_sample - playback_sample)) {
internal_playback_seek (start_sample - playback_sample);
} else {
cerr << owner()->name() << " playback not possible: ss = " << start_sample << " ps = " << playback_sample << endl;
goto midi;
}
}
chaninfo->buf->get_read_vector (&(*chan)->rw_vector);
if (disk_samples_to_consume <= (samplecnt_t) chaninfo->rw_vector.len[0]) {
if (fabsf (speed) != 1.0f) {
(void) interpolation.interpolate (
n, nframes,
n, disk_samples_to_consume,
chaninfo->rw_vector.buf[0],
disk_signal);
} else if (speed != 0.0) {
@ -377,20 +424,23 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
}
if (scaling != 1.0f && speed != 0.0) {
apply_gain_to_buffer (disk_signal, nframes, scaling);
apply_gain_to_buffer (disk_signal, disk_samples_to_consume, scaling);
}
chaninfo->buf->increment_read_ptr (disk_samples_to_consume);
if ((speed != 0.0) && (ms & MonitoringInput)) {
monitor_mix:
if (ms & MonitoringInput) {
/* mix the disk signal into the input signal (already in bufs) */
mix_buffers_no_gain (output.data(), disk_signal, speed == 0.0 ? nframes : disk_samples_to_consume);
mix_buffers_no_gain (output.data(), disk_signal, disk_samples_to_consume);
}
}
}
/* MIDI data handling */
midi:
if (!_session.declick_out_pending() && bufs.count().n_midi()) {
MidiBuffer* dst;

View file

@ -96,7 +96,6 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
, _active (true)
, _signal_latency (0)
, _initial_delay (0)
, _roll_delay (0)
, _disk_io_point (DiskIOPreFader)
, _pending_process_reorder (0)
, _pending_signals (0)
@ -3353,7 +3352,9 @@ Route::non_realtime_transport_stop (samplepos_t now, bool flush)
}
}
_roll_delay = _initial_delay;
if (_disk_reader) {
_disk_reader->set_roll_delay (_initial_delay);
}
}
void
@ -3941,7 +3942,9 @@ Route::set_latency_compensation (samplecnt_t longest_session_latency)
}
if (_session.transport_stopped()) {
_roll_delay = _initial_delay;
if (_disk_reader) {
_disk_reader->set_roll_delay (_initial_delay);
}
}
}
@ -4885,7 +4888,10 @@ Route::non_realtime_locate (samplepos_t pos)
(*i)->non_realtime_locate (pos);
}
}
_roll_delay = _initial_delay;
if (_disk_reader) {
_disk_reader->set_roll_delay (_initial_delay);
}
}
void

View file

@ -414,13 +414,6 @@ Track::set_name (const string& str)
return ret;
}
void
Track::set_latency_compensation (samplecnt_t longest_session_latency)
{
Route::set_latency_compensation (longest_session_latency);
_disk_reader->set_roll_delay (_roll_delay);
}
int
Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing)
{
@ -1001,42 +994,6 @@ Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)
}
}
samplecnt_t
Track::check_initial_delay (samplecnt_t nframes, samplepos_t& transport_sample)
{
if (_roll_delay > nframes) {
_roll_delay -= nframes;
silence_unlocked (nframes);
/* transport sample is not legal for caller to use */
return 0;
} else if (_roll_delay > 0) {
nframes -= _roll_delay;
silence_unlocked (_roll_delay);
transport_sample += _roll_delay;
/* shuffle all the port buffers for things that lead "out" of this Route
to reflect that we just wrote _roll_delay samples of silence.
*/
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
if (iop) {
iop->increment_port_buffer_offset (_roll_delay);
}
}
_output->increment_port_buffer_offset (_roll_delay);
_roll_delay = 0;
}
return nframes;
}
void
Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
{