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.
This commit is contained in:
parent
831f2989ac
commit
a16dd7c071
@ -579,6 +579,10 @@ MidiDiskstream::commit (framecnt_t playback_distance)
|
|||||||
{
|
{
|
||||||
bool need_butler = false;
|
bool need_butler = false;
|
||||||
|
|
||||||
|
if (!_io || !_io->active()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_actual_speed < 0.0) {
|
if (_actual_speed < 0.0) {
|
||||||
playback_sample -= playback_distance;
|
playback_sample -= playback_distance;
|
||||||
} else {
|
} else {
|
||||||
@ -606,10 +610,33 @@ MidiDiskstream::commit (framecnt_t playback_distance)
|
|||||||
* need the butler is done correctly.
|
* 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_read <= frames_written) {
|
||||||
if ((frames_written - frames_read) + playback_distance < midi_readahead) {
|
if ((frames_written - frames_read) + playback_distance < midi_readahead) {
|
||||||
need_butler = true;
|
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_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
|
||||||
uint32_t frames_written = g_atomic_int_get(&_frames_written_to_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;
|
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: "
|
//cout << "MDS read for midi_readahead " << to_read << " rb_contains: "
|
||||||
// << frames_written - frames_read << endl;
|
// << 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)) {
|
if (read (file_frame, to_read, reversed)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user