summaryrefslogtreecommitdiff
path: root/libs/ardour/disk_reader.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-06-27 15:33:41 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2017-09-18 11:40:53 -0400
commit30c6096d20799fa7da6a45051ff70a448d272f6b (patch)
tree7996f15e0842a4c2d1d254a31577830b545f1698 /libs/ardour/disk_reader.cc
parent1c603682b71b7ef64f35fd6b3ef3afdfeaba95c5 (diff)
locating no longer interrupts process()
Diffstat (limited to 'libs/ardour/disk_reader.cc')
-rw-r--r--libs/ardour/disk_reader.cc153
1 files changed, 82 insertions, 71 deletions
diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc
index 09e72d03ab..cc4a0fe2f3 100644
--- a/libs/ardour/disk_reader.cc
+++ b/libs/ardour/disk_reader.cc
@@ -239,7 +239,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
uint32_t n;
boost::shared_ptr<ChannelList> c = channels.reader();
ChannelList::iterator chan;
- frameoffset_t playback_distance = nframes;
+ frameoffset_t playback_distance;
MonitorState ms = _route->monitoring_state ();
if (_active) {
@@ -269,15 +269,17 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
interpolation.set_speed (speed);
midi_interpolation.set_speed (speed);
playback_distance = midi_interpolation.distance (nframes);
- }
-
- if (speed < 0.0) {
- playback_distance = -playback_distance;
+ if (speed < 0.0) {
+ playback_distance = -playback_distance;
+ }
+ } else {
+ playback_distance = nframes;
}
BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count()));
+ const bool still_locating = _session.locate_pending();
- if (!result_required || ((ms & MonitoringDisk) == 0)) {
+ if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating) {
/* no need for actual disk data, just advance read pointer and return */
@@ -285,6 +287,12 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
(*chan)->buf->increment_read_ptr (playback_distance);
}
+ /* if monitoring disk but locating, put silence in the buffers */
+
+ if (still_locating && (ms == MonitoringDisk)) {
+ bufs.silence (playback_distance, 0);
+ }
+
} else {
/* we need audio data from disk */
@@ -302,7 +310,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
ChannelInfo* chaninfo (*chan);
- AudioBuffer& buf (bufs.get_audio (n%n_buffers));
+ AudioBuffer& output (bufs.get_audio (n%n_buffers));
Sample* disk_signal = 0; /* assignment not really needed but it keeps the compiler quiet and helps track bugs */
if (ms & MonitoringInput) {
@@ -310,7 +318,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
disk_signal = scratch_bufs.get_audio(n).data ();
} else {
/* no input stream needed, just overwrite buffers */
- disk_signal = buf.data ();
+ disk_signal = output.data ();
}
chaninfo->buf->get_read_vector (&(*chan)->rw_vector);
@@ -373,7 +381,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
if ((speed != 0.0) && (ms & MonitoringInput)) {
/* mix the disk signal into the input signal (already in bufs) */
- mix_buffers_no_gain (buf.data(), disk_signal, speed == 0.0 ? nframes : playback_distance);
+ mix_buffers_no_gain (output.data(), disk_signal, speed == 0.0 ? nframes : playback_distance);
}
}
}
@@ -381,83 +389,86 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
/* MIDI data handling */
if (!_session.declick_out_pending()) {
- if (ms & MonitoringDisk) {
+ if (ms & MonitoringDisk && !still_locating) {
get_midi_playback (bufs.get_midi (0), playback_distance, ms, scratch_bufs, speed, playback_distance);
}
}
- if (speed < 0.0) {
- playback_sample -= playback_distance;
- } else {
- playback_sample += playback_distance;
- }
+ if (!still_locating) {
- if (_playlists[DataType::AUDIO]) {
- if (!c->empty()) {
- if (_slaved) {
- if (c->front()->buf->write_space() >= c->front()->buf->bufsize() / 2) {
- DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->buf->write_space(),
- c->front()->buf->bufsize()));
- _need_butler = true;
- }
- } else {
- if ((framecnt_t) c->front()->buf->write_space() >= _chunk_frames) {
- DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->buf->write_space(),
- _chunk_frames));
- _need_butler = true;
+ if (speed < 0.0) {
+ playback_sample -= playback_distance;
+ } else {
+ playback_sample += playback_distance;
+ }
+
+ if (_playlists[DataType::AUDIO]) {
+ if (!c->empty()) {
+ if (_slaved) {
+ if (c->front()->buf->write_space() >= c->front()->buf->bufsize() / 2) {
+ DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->buf->write_space(),
+ c->front()->buf->bufsize()));
+ _need_butler = true;
+ }
+ } else {
+ if ((framecnt_t) c->front()->buf->write_space() >= _chunk_frames) {
+ DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->buf->write_space(),
+ _chunk_frames));
+ _need_butler = true;
+ }
}
}
}
- }
- if (_playlists[DataType::MIDI]) {
- /* MIDI butler needed part */
+ if (_playlists[DataType::MIDI]) {
+ /* MIDI butler needed part */
- uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
- uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
+ uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
+ uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
- /*
- cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
- " = " << frames_written - frames_read
- << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
- */
-
- /* frames_read will generally be less than frames_written, but
- * immediately after an overwrite, we can end up having read some data
- * before we've written any. we don't need to trip an assert() on this,
- * but we do need to check so that the decision on whether or not we
- * need the butler is done correctly.
- */
+ /*
+ cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
+ " = " << frames_written - frames_read
+ << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
+ */
- /* furthermore..
- *
- * Doing heavy GUI operations[1] can stall also the butler.
- * The RT-thread meanwhile will happily continue and
- * ‘frames_read’ (from buffer to output) will become larger
- * than ‘frames_written’ (from disk to buffer).
- *
- * The disk-stream is now behind..
- *
- * In those cases the butler needs to be summed to refill the buffer (done now)
- * AND we need to skip (frames_read - frames_written). ie remove old events
- * before playback_sample from the rinbuffer.
- *
- * [1] one way to do so is described at #6170.
- * For me just popping up the context-menu on a MIDI-track header
- * of a track with a large (think beethoven :) midi-region also did the
- * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
- *
- * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
- * and can stall
- */
- if (frames_read <= frames_written) {
- if ((frames_written - frames_read) + playback_distance < midi_readahead) {
+ /* frames_read will generally be less than frames_written, but
+ * immediately after an overwrite, we can end up having read some data
+ * before we've written any. we don't need to trip an assert() on this,
+ * but we do need to check so that the decision on whether or not we
+ * need the butler is done correctly.
+ */
+
+ /* furthermore..
+ *
+ * Doing heavy GUI operations[1] can stall also the butler.
+ * The RT-thread meanwhile will happily continue and
+ * ‘frames_read’ (from buffer to output) will become larger
+ * than ‘frames_written’ (from disk to buffer).
+ *
+ * The disk-stream is now behind..
+ *
+ * In those cases the butler needs to be summed to refill the buffer (done now)
+ * AND we need to skip (frames_read - frames_written). ie remove old events
+ * before playback_sample from the rinbuffer.
+ *
+ * [1] one way to do so is described at #6170.
+ * For me just popping up the context-menu on a MIDI-track header
+ * of a track with a large (think beethoven :) midi-region also did the
+ * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
+ *
+ * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
+ * and can stall
+ */
+ if (frames_read <= frames_written) {
+ if ((frames_written - frames_read) + playback_distance < midi_readahead) {
+ _need_butler = true;
+ }
+ } else {
_need_butler = true;
}
- } else {
- _need_butler = true;
- }
+ }
}
DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 reader run, needs butler = %2\n", name(), _need_butler));