summaryrefslogtreecommitdiff
path: root/libs/ardour/midi_diskstream.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2015-03-12 14:16:55 +0100
committerRobin Gareus <robin@gareus.org>2015-03-12 15:22:18 +0100
commita16dd7c071e71f90a3c47671262ec984c097c045 (patch)
tree5fe104bf672e0693bcc45f91cdc5d7f3ef00121e /libs/ardour/midi_diskstream.cc
parent831f2989aca683aedda032061a74727707f0b871 (diff)
explain midi starvation, issue #6170
this is not a fix yet, just some comments and code cleanup done while reading/investigating: * limit reads to available write-space * skip inactive tracks * handle potential unsigned + negative value.
Diffstat (limited to 'libs/ardour/midi_diskstream.cc')
-rw-r--r--libs/ardour/midi_diskstream.cc34
1 files changed, 31 insertions, 3 deletions
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index f19c88d3b3..80faab1f9d 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -579,6 +579,10 @@ MidiDiskstream::commit (framecnt_t playback_distance)
{
bool need_butler = false;
+ if (!_io || !_io->active()) {
+ return false;
+ }
+
if (_actual_speed < 0.0) {
playback_sample -= playback_distance;
} else {
@@ -606,10 +610,33 @@ MidiDiskstream::commit (framecnt_t playback_distance)
* 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. (not yet done)
+ *
+ * [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;
}
@@ -812,16 +839,17 @@ MidiDiskstream::do_refill ()
uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
- if ((frames_written - frames_read) >= midi_readahead) {
+ if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
return 0;
}
- framecnt_t to_read = midi_readahead - (frames_written - frames_read);
+ framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
//cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
// << frames_written - frames_read << endl;
- to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
+ to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
+ to_read = min (to_read, (framecnt_t) write_space);
if (read (file_frame, to_read, reversed)) {
ret = -1;