summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-09-19 18:53:27 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2017-09-19 18:53:27 -0400
commit48d11000e5c13ebc831b98c56bc18329e6fc7505 (patch)
tree789d0200510f9f3d486d50c4948060468dbeb22b /libs/ardour
parentcb71d49dc6040e5de8d581d8aca4654406f9014d (diff)
attempt to fix roll delay logic by moving it into DiskReader (the only place it matters)
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/route.h1
-rw-r--r--libs/ardour/ardour/track.h2
-rw-r--r--libs/ardour/disk_reader.cc64
-rw-r--r--libs/ardour/route.cc14
-rw-r--r--libs/ardour/track.cc43
5 files changed, 67 insertions, 57 deletions
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 0e1d0b65e1..bf8d05dd12 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -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;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index ec81e92939..865b9c0619 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -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;
diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc
index 6f559b6167..5194b6ca2a 100644
--- a/libs/ardour/disk_reader.cc
+++ b/libs/ardour/disk_reader.cc
@@ -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;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 041640a973..4d473eb740 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 57891968b6..f451a3ed51 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -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)
{