Towards a new disk-reader ringbuffer
[ardour.git] / libs / ardour / disk_reader.cc
1 /*
2  * Copyright (C) 2009-2018 Paul Davis
3  * Copyright (C) 2019 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include <boost/smart_ptr/scoped_array.hpp>
21
22 #include "pbd/enumwriter.h"
23 #include "pbd/memento_command.h"
24 #include "pbd/playback_buffer.h"
25
26 #include "ardour/audioengine.h"
27 #include "ardour/audioplaylist.h"
28 #include "ardour/audio_buffer.h"
29 #include "ardour/butler.h"
30 #include "ardour/debug.h"
31 #include "ardour/disk_reader.h"
32 #include "ardour/midi_ring_buffer.h"
33 #include "ardour/midi_playlist.h"
34 #include "ardour/midi_track.h"
35 #include "ardour/pannable.h"
36 #include "ardour/playlist.h"
37 #include "ardour/playlist_factory.h"
38 #include "ardour/session.h"
39 #include "ardour/session_playlists.h"
40
41 #include "pbd/i18n.h"
42
43 using namespace ARDOUR;
44 using namespace PBD;
45 using namespace std;
46
47 ARDOUR::samplecnt_t DiskReader::_chunk_samples = default_chunk_samples ();
48 PBD::Signal0<void> DiskReader::Underrun;
49 Sample* DiskReader::_sum_buffer = 0;
50 Sample* DiskReader::_mixdown_buffer = 0;
51 gain_t* DiskReader::_gain_buffer = 0;
52 samplecnt_t DiskReader::midi_readahead = 4096;
53 bool DiskReader::_no_disk_output = false;
54
55 DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
56         : DiskIOProcessor (s, str, f)
57         , overwrite_sample (0)
58         , _pending_overwrite (false)
59         , overwrite_queued (false)
60         , _declick_gain (0)
61 {
62         file_sample[DataType::AUDIO] = 0;
63         file_sample[DataType::MIDI] = 0;
64 }
65
66 DiskReader::~DiskReader ()
67 {
68         DEBUG_TRACE (DEBUG::Destruction, string_compose ("DiskReader %1 @ %2 deleted\n", _name, this));
69
70         for (uint32_t n = 0; n < DataType::num_types; ++n) {
71                 if (_playlists[n]) {
72                         _playlists[n]->release ();
73                 }
74         }
75 }
76
77 void
78 DiskReader::ReaderChannelInfo::resize (samplecnt_t bufsize)
79 {
80         delete rbuf;
81         /* touch memory to lock it */
82         rbuf = new PlaybackBuffer<Sample> (bufsize);
83         memset (rbuf->buffer(), 0, sizeof (Sample) * rbuf->bufsize());
84 }
85
86 int
87 DiskReader::add_channel_to (boost::shared_ptr<ChannelList> c, uint32_t how_many)
88 {
89         while (how_many--) {
90                 c->push_back (new ReaderChannelInfo (_session.butler()->audio_diskstream_playback_buffer_size()));
91                 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: new reader channel, write space = %2 read = %3\n",
92                                                             name(),
93                                                             c->back()->rbuf->write_space(),
94                                                             c->back()->rbuf->read_space()));
95         }
96
97         return 0;
98 }
99
100 void
101 DiskReader::allocate_working_buffers()
102 {
103         /* with varifill buffer refilling, we compute the read size in bytes (to optimize
104            for disk i/o bandwidth) and then convert back into samples. These buffers
105            need to reflect the maximum size we could use, which is 4MB reads, or 2M samples
106            using 16 bit samples.
107         */
108         _sum_buffer           = new Sample[2*1048576];
109         _mixdown_buffer       = new Sample[2*1048576];
110         _gain_buffer          = new gain_t[2*1048576];
111 }
112
113 void
114 DiskReader::free_working_buffers()
115 {
116         delete [] _sum_buffer;
117         delete [] _mixdown_buffer;
118         delete [] _gain_buffer;
119         _sum_buffer     = 0;
120         _mixdown_buffer = 0;
121         _gain_buffer    = 0;
122 }
123
124 samplecnt_t
125 DiskReader::default_chunk_samples()
126 {
127         return 65536;
128 }
129
130 bool
131 DiskReader::set_name (string const & str)
132 {
133         string my_name = X_("player:");
134         my_name += str;
135
136         if (_name != my_name) {
137                 SessionObject::set_name (my_name);
138         }
139
140         return true;
141 }
142
143 XMLNode&
144 DiskReader::state ()
145 {
146         XMLNode& node (DiskIOProcessor::state ());
147         node.set_property(X_("type"), X_("diskreader"));
148         return node;
149 }
150
151 int
152 DiskReader::set_state (const XMLNode& node, int version)
153 {
154         if (DiskIOProcessor::set_state (node, version)) {
155                 return -1;
156         }
157
158         return 0;
159 }
160
161 void
162 DiskReader::realtime_handle_transport_stopped ()
163 {
164 }
165
166 void
167 DiskReader::realtime_locate ()
168 {
169 }
170
171 float
172 DiskReader::buffer_load () const
173 {
174         /* Note: for MIDI it's not trivial to differentiate the following two cases:
175
176            1.  The playback buffer is empty because the system has run out of time to fill it.
177            2.  The playback buffer is empty because there is no more data on the playlist.
178
179            If we use a simple buffer load computation, we will report that the MIDI diskstream
180            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
181            are so low compared to audio, just use the audio value here.
182         */
183
184         boost::shared_ptr<ChannelList> c = channels.reader();
185
186         if (c->empty ()) {
187                 /* no channels, so no buffers, so completely full and ready to playback, sir! */
188                 return 1.0;
189         }
190
191         PBD::PlaybackBuffer<Sample>* b = c->front()->rbuf;
192         return (float) ((double) b->read_space() / (double) b->bufsize());
193 }
194
195 void
196 DiskReader::adjust_buffering ()
197 {
198         boost::shared_ptr<ChannelList> c = channels.reader();
199
200         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
201                 (*chan)->resize (_session.butler()->audio_diskstream_playback_buffer_size());
202         }
203 }
204
205 void
206 DiskReader::playlist_changed (const PropertyChange&)
207 {
208         playlist_modified ();
209 }
210
211 void
212 DiskReader::playlist_modified ()
213 {
214         if (!i_am_the_modifier && !overwrite_queued) {
215                 _session.request_overwrite_buffer (_route);
216                 overwrite_queued = true;
217         }
218 }
219
220 int
221 DiskReader::use_playlist (DataType dt, boost::shared_ptr<Playlist> playlist)
222 {
223         bool prior_playlist = false;
224
225         if (_playlists[dt]) {
226                 prior_playlist = true;
227         }
228
229         if (DiskIOProcessor::use_playlist (dt, playlist)) {
230                 return -1;
231         }
232
233         /* don't do this if we've already asked for it *or* if we are setting up
234            the diskstream for the very first time - the input changed handling will
235            take care of the buffer refill.
236         */
237
238         if (!overwrite_queued && (prior_playlist || _session.loading())) {
239                 _session.request_overwrite_buffer (_route);
240                 overwrite_queued = true;
241         }
242
243         return 0;
244 }
245
246 void
247 DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
248                  double speed, pframes_t nframes, bool result_required)
249 {
250         uint32_t n;
251         boost::shared_ptr<ChannelList> c = channels.reader();
252         ChannelList::iterator chan;
253         sampleoffset_t disk_samples_to_consume;
254         MonitorState ms = _route->monitoring_state ();
255
256         if (_active) {
257                 if (!_pending_active) {
258                         _active = false;
259                         return;
260                 }
261         } else {
262                 if (_pending_active) {
263                         _active = true;
264                 } else {
265                         return;
266                 }
267         }
268
269         if ((speed == 0.0) && (ms == MonitoringDisk)) {
270                 /* no channels, or stopped. Don't accidentally pass any data
271                  * from disk into our outputs (e.g. via interpolation)
272                  */
273                 return;
274         }
275
276         BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count()));
277         const bool still_locating = _session.global_locate_pending();
278
279         if (c->empty()) {
280                 /* do nothing with audio */
281                 goto midi;
282         }
283
284         assert (speed == -1 || speed == 0 || speed == 1);
285
286         if (speed < 0) {
287                 disk_samples_to_consume = -nframes;
288         } else if (speed > 0) {
289                 disk_samples_to_consume = nframes;
290         } else {
291                 disk_samples_to_consume = 0;
292         }
293
294         if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output) {
295
296                 /* no need for actual disk data, just advance read pointer and return */
297
298                 if (!still_locating || _no_disk_output) {
299                         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
300                                 (*chan)->rbuf->increment_read_ptr (disk_samples_to_consume);
301                         }
302                 }
303
304                 /* if monitoring disk but locating put silence in the buffers */
305
306                 if ((_no_disk_output || still_locating) && (ms == MonitoringDisk)) {
307                         bufs.silence (nframes, 0);
308                 }
309
310         } else {
311
312                 /* we need audio data from disk */
313
314                 size_t n_buffers = bufs.count().n_audio();
315                 size_t n_chans = c->size();
316                 gain_t scaling;
317
318                 if (n_chans > n_buffers) {
319                         scaling = ((float) n_buffers)/n_chans;
320                 } else {
321                         scaling = 1.0;
322                 }
323
324                 for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
325
326                         ChannelInfo* chaninfo (*chan);
327                         AudioBuffer& output (bufs.get_audio (n%n_buffers));
328                         Sample* disk_signal = 0; /* assignment not really needed but it keeps the compiler quiet and helps track bugs */
329
330                         if (ms & MonitoringInput) {
331                                 /* put disk stream in scratch buffer, blend at end */
332                                 disk_signal = scratch_bufs.get_audio(n).data ();
333                         } else {
334                                 /* no input stream needed, just overwrite buffers */
335                                 disk_signal = output.data ();
336                         }
337
338                         if (speed > 0) {
339                                 if (start_sample < playback_sample) {
340                                         cerr << owner()->name() << " SS = " << start_sample << " PS = " << playback_sample << endl;
341                                         abort ();
342                                 }
343                         } else if (speed < 0) {
344                                 if (playback_sample < start_sample) {
345                                         cerr << owner()->name() << " SS = " << start_sample << " PS = " << playback_sample << " REVERSE" << endl;
346                                         abort ();
347                                 }
348                         }
349
350                         if ((speed > 0) && (start_sample != playback_sample)) {
351                                 stringstream str;
352                                 str << owner()->name() << " playback @ " << start_sample << " not aligned with " << playback_sample << " jump ahead " << (start_sample - playback_sample) << endl;
353                                 cerr << str.str();
354
355                                 if (can_internal_playback_seek (start_sample - playback_sample)) {
356                                         internal_playback_seek (start_sample - playback_sample);
357                                 } else {
358                                         cerr << owner()->name() << " playback not possible: ss = " << start_sample << " ps = " << playback_sample << endl;
359                                         goto midi;
360                                 }
361                         }
362
363                         if (speed != 0.0) {
364                                 assert (disk_signal);
365                                 const samplecnt_t total = chaninfo->rbuf->read (disk_signal, disk_samples_to_consume);
366                                 if (disk_samples_to_consume > total) {
367                                         cerr << _name << " Need " << disk_samples_to_consume << " total = " << total << endl;
368                                         cerr << "underrun for " << _name << endl;
369                                         DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 underrun in %2, total space = %3\n",
370                                                                                     DEBUG_THREAD_SELF, name(), total));
371                                         Underrun ();
372                                         return;
373                                 }
374                         }
375
376                         if (scaling != 1.0f && speed != 0.0) {
377                                 apply_gain_to_buffer (disk_signal, disk_samples_to_consume, scaling);
378                         }
379
380                         //chaninfo->rbuf->increment_read_ptr (disk_samples_to_consume);
381
382                         if (ms & MonitoringInput) {
383                                 /* mix the disk signal into the input signal (already in bufs) */
384                                 mix_buffers_no_gain (output.data(), disk_signal, disk_samples_to_consume);
385                         }
386                 }
387         }
388
389         /* MIDI data handling */
390
391   midi:
392         if (/*!_session.declick_out_pending() && */ bufs.count().n_midi() && _midi_buf) {
393                 MidiBuffer* dst;
394
395                 if (_no_disk_output) {
396                         dst = &scratch_bufs.get_midi(0);
397                 } else {
398                         dst = &bufs.get_midi (0);
399                 }
400
401                 if ((ms & MonitoringDisk) && !still_locating) {
402                         get_midi_playback (*dst, start_sample, end_sample, ms, scratch_bufs, speed, disk_samples_to_consume);
403                 }
404         }
405
406         if (!still_locating) {
407
408                 bool butler_required = false;
409
410                 if (speed < 0.0) {
411                         playback_sample -= disk_samples_to_consume;
412                 } else {
413                         playback_sample += disk_samples_to_consume;
414                 }
415
416                 if (_playlists[DataType::AUDIO]) {
417                         if (!c->empty()) {
418                                 if (_slaved) {
419                                         if (c->front()->rbuf->write_space() >= c->front()->rbuf->bufsize() / 2) {
420                                                 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: slaved, write space = %2 of %3\n", name(), c->front()->rbuf->write_space(), c->front()->rbuf->bufsize()));
421                                                 butler_required = true;
422                                         }
423                                 } else {
424                                         if ((samplecnt_t) c->front()->rbuf->write_space() >= _chunk_samples) {
425                                                 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: write space = %2 of %3\n", name(), c->front()->rbuf->write_space(),
426                                                                                             _chunk_samples));
427                                                 butler_required = true;
428                                         }
429                                 }
430                         }
431                 }
432
433                 if (_playlists[DataType::MIDI]) {
434                         /* MIDI butler needed part */
435
436                         uint32_t samples_read = g_atomic_int_get(const_cast<gint*>(&_samples_read_from_ringbuffer));
437                         uint32_t samples_written = g_atomic_int_get(const_cast<gint*>(&_samples_written_to_ringbuffer));
438
439                         /*
440                           cerr << name() << " MDS written: " << samples_written << " - read: " << samples_read <<
441                           " = " << samples_written - samples_read
442                           << " + " << disk_samples_to_consume << " < " << midi_readahead << " = " << need_butler << ")" << endl;
443                         */
444
445                         /* samples_read will generally be less than samples_written, but
446                          * immediately after an overwrite, we can end up having read some data
447                          * before we've written any. we don't need to trip an assert() on this,
448                          * but we do need to check so that the decision on whether or not we
449                          * need the butler is done correctly.
450                          */
451
452                         /* furthermore..
453                          *
454                          * Doing heavy GUI operations[1] can stall also the butler.
455                          * The RT-thread meanwhile will happily continue and
456                          * â€˜samples_read’ (from buffer to output) will become larger
457                          * than â€˜samples_written’ (from disk to buffer).
458                          *
459                          * The disk-stream is now behind..
460                          *
461                          * In those cases the butler needs to be summed to refill the buffer (done now)
462                          * AND we need to skip (samples_read - samples_written). ie remove old events
463                          * before playback_sample from the rinbuffer.
464                          *
465                          * [1] one way to do so is described at #6170.
466                          * For me just popping up the context-menu on a MIDI-track header
467                          * of a track with a large (think beethoven :) midi-region also did the
468                          * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
469                          *
470                          * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
471                          * and can stall
472                          */
473                         if (samples_read <= samples_written) {
474                                 if ((samples_written - samples_read) + disk_samples_to_consume < midi_readahead) {
475                                         butler_required = true;
476                                 }
477                         } else {
478                                 butler_required = true;
479                         }
480
481                 }
482
483                 _need_butler = butler_required;
484         }
485
486         // DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 reader run, needs butler = %2\n", name(), _need_butler));
487 }
488
489 void
490 DiskReader::set_pending_overwrite (bool yn)
491 {
492         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
493
494         _pending_overwrite = yn;
495
496         overwrite_sample = playback_sample;
497
498         boost::shared_ptr<ChannelList> c = channels.reader ();
499         for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
500                 (*chan)->rbuf->read_flush ();
501         }
502 }
503
504 int
505 DiskReader::overwrite_existing_buffers ()
506 {
507         int ret = -1;
508
509         boost::shared_ptr<ChannelList> c = channels.reader();
510
511         overwrite_queued = false;
512
513         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1 overwriting existing buffers at %2\n", overwrite_sample));
514
515         if (!c->empty ()) {
516                 /* AUDIO */
517
518                 const bool reversed = _session.transport_speed() < 0.0f;
519
520                 /* assume all are the same size */
521                 samplecnt_t size = c->front()->rbuf->write_space ();
522
523                 boost::scoped_array<Sample> sum_buffer (new Sample[size]);
524                 boost::scoped_array<Sample> mixdown_buffer (new Sample[size]);
525                 boost::scoped_array<float> gain_buffer (new float[size]);
526
527                 /* reduce size so that we can fill the buffer correctly (ringbuffers
528                  * can only handle size-1, otherwise they appear to be empty)
529                  */
530                 size--;
531
532                 uint32_t n=0;
533
534                 for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) {
535
536                         samplepos_t start = overwrite_sample;
537                         samplecnt_t to_read = size;
538
539                         cerr << owner()->name() << " over-read: " << to_read << endl;
540                         if (audio_read ((*chan)->rbuf, sum_buffer.get(), mixdown_buffer.get(), gain_buffer.get(), start, to_read, n, reversed)) {
541                                 error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), size, overwrite_sample) << endmsg;
542                                 goto midi;
543                         }
544                 }
545
546                 ret = 0;
547         }
548
549   midi:
550
551         if (_midi_buf && _playlists[DataType::MIDI]) {
552
553                 /* Clear the playback buffer contents.  This is safe as long as the butler
554                    thread is suspended, which it should be.
555                 */
556                 _midi_buf->reset ();
557                 _midi_buf->reset_tracker ();
558
559                 g_atomic_int_set (&_samples_read_from_ringbuffer, 0);
560                 g_atomic_int_set (&_samples_written_to_ringbuffer, 0);
561
562                 /* Resolve all currently active notes in the playlist.  This is more
563                    aggressive than it needs to be: ideally we would only resolve what is
564                    absolutely necessary, but this seems difficult and/or impossible without
565                    having the old data or knowing what change caused the overwrite.
566                 */
567                 midi_playlist()->resolve_note_trackers (*_midi_buf, overwrite_sample);
568
569                 midi_read (overwrite_sample, _chunk_samples, false);
570                 file_sample[DataType::MIDI] = overwrite_sample; // overwrite_sample was adjusted by ::midi_read() to the new position
571         }
572
573         _pending_overwrite = false;
574
575         return ret;
576 }
577
578 int
579 DiskReader::seek (samplepos_t sample, bool complete_refill)
580 {
581         uint32_t n;
582         int ret = -1;
583         ChannelList::iterator chan;
584         boost::shared_ptr<ChannelList> c = channels.reader();
585
586         //sample = std::max ((samplecnt_t)0, sample -_session.worst_output_latency ());
587
588         for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) {
589                 (*chan)->rbuf->reset ();
590         }
591
592         if (g_atomic_int_get (&_samples_read_from_ringbuffer) == 0) {
593                 /* we haven't read anything since the last seek,
594                    so flush all note trackers to prevent
595                    wierdness
596                 */
597                 reset_tracker ();
598         }
599
600         if (_midi_buf) {
601                 _midi_buf->reset();
602         }
603         g_atomic_int_set(&_samples_read_from_ringbuffer, 0);
604         g_atomic_int_set(&_samples_written_to_ringbuffer, 0);
605
606         playback_sample = sample;
607         file_sample[DataType::AUDIO] = sample;
608         file_sample[DataType::MIDI] = sample;
609
610         if (complete_refill) {
611                 /* call _do_refill() to refill the entire buffer, using
612                    the largest reads possible.
613                 */
614                 while ((ret = do_refill_with_alloc (false)) > 0) ;
615         } else {
616                 /* call _do_refill() to refill just one chunk, and then
617                    return.
618                 */
619                 ret = do_refill_with_alloc (true);
620         }
621
622
623         return ret;
624 }
625
626 int
627 DiskReader::can_internal_playback_seek (samplecnt_t distance)
628 {
629         /* 1. Audio */
630
631         ChannelList::iterator chan;
632         boost::shared_ptr<ChannelList> c = channels.reader();
633
634         for (chan = c->begin(); chan != c->end(); ++chan) {
635                 if ((*chan)->rbuf->read_space() < (size_t) distance) {
636                         return false;
637                 }
638         }
639
640         /* 2. MIDI */
641
642         uint32_t samples_read    = g_atomic_int_get(&_samples_read_from_ringbuffer);
643         uint32_t samples_written = g_atomic_int_get(&_samples_written_to_ringbuffer);
644
645         return ((samples_written - samples_read) < distance);
646 }
647
648 int
649 DiskReader::internal_playback_seek (samplecnt_t distance)
650 {
651         ChannelList::iterator chan;
652         boost::shared_ptr<ChannelList> c = channels.reader();
653
654         for (chan = c->begin(); chan != c->end(); ++chan) {
655                 (*chan)->rbuf->increment_read_ptr (::llabs(distance));
656         }
657
658         playback_sample += distance;
659
660         return 0;
661 }
662
663 static
664 void swap_by_ptr (Sample *first, Sample *last)
665 {
666         while (first < last) {
667                 Sample tmp = *first;
668                 *first++ = *last;
669                 *last-- = tmp;
670         }
671 }
672
673 /** Read some data for 1 channel from our playlist into a buffer.
674  *  @param buf Buffer to write to.
675  *  @param start Session sample to start reading from; updated to where we end up
676  *         after the read.
677  *  @param cnt Count of samples to read.
678  *  @param reversed true if we are running backwards, otherwise false.
679  */
680 int
681 DiskReader::audio_read (PBD::PlaybackBuffer<Sample>*rb,
682                         Sample* sum_buffer,
683                         Sample* mixdown_buffer,
684                         float* gain_buffer,
685                         samplepos_t& start, samplecnt_t cnt,
686                         int channel, bool reversed)
687 {
688         samplecnt_t this_read = 0;
689         bool reloop = false;
690         samplepos_t loop_end = 0;
691         samplepos_t loop_start = 0;
692         Location *loc = 0;
693
694         if (!_playlists[DataType::AUDIO]) {
695                 // TODO optimize use zero-buffer
696                 for (uint32_t z = 0; z < cnt; ++z) {
697                         Sample t = 0;
698                         rb->write (&t, 1);
699                 }
700                 return 0;
701         }
702
703         /* XXX we don't currently play loops in reverse. not sure why */
704
705         if (!reversed) {
706
707                 samplecnt_t loop_length = 0;
708
709                 /* Make the use of a Location atomic for this read operation.
710
711                    Note: Locations don't get deleted, so all we care about
712                    when I say "atomic" is that we are always pointing to
713                    the same one and using a start/length values obtained
714                    just once.
715                 */
716
717                 if ((loc = _loop_location) != 0) {
718                         loop_start = loc->start();
719                         loop_end = loc->end();
720                         loop_length = loop_end - loop_start;
721                 }
722
723                 /* if we are looping, ensure that the first sample we read is at the correct
724                    position within the loop.
725                 */
726
727                 if (loc && start >= loop_end) {
728                         start = loop_start + ((start - loop_start) % loop_length);
729                 }
730
731         }
732
733         if (reversed) {
734                 start -= cnt;
735         }
736
737         /* We need this while loop in case we hit a loop boundary, in which case our read from
738            the playlist must be split into more than one section.
739         */
740
741         while (cnt) {
742
743                 /* take any loop into account. we can't read past the end of the loop. */
744
745                 if (loc && (loop_end - start < cnt)) {
746                         this_read = loop_end - start;
747                         reloop = true;
748                 } else {
749                         reloop = false;
750                         this_read = cnt;
751                 }
752
753                 if (this_read == 0) {
754                         break;
755                 }
756
757                 this_read = min (cnt, this_read);
758
759                 if (audio_playlist()->read (sum_buffer, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
760                         error << string_compose(_("DiskReader %1: cannot read %2 from playlist at sample %3"), id(), this_read, start) << endmsg;
761                         return -1;
762                 }
763
764                 if (reversed) {
765
766                         swap_by_ptr (sum_buffer, sum_buffer + this_read - 1);
767
768                 } else {
769
770                         /* if we read to the end of the loop, go back to the beginning */
771
772                         if (reloop) {
773                                 start = loop_start;
774                         } else {
775                                 start += this_read;
776                         }
777                 }
778
779                 if (rb->write (sum_buffer, this_read) != this_read) {
780                         cerr << owner()->name() << " Ringbuffer Write overrun" << endl;
781                 }
782
783                 cnt -= this_read;
784         }
785
786         return 0;
787 }
788
789 int
790 DiskReader::_do_refill_with_alloc (bool partial_fill)
791 {
792         /* We limit disk reads to at most 4MB chunks, which with floating point
793            samples would be 1M samples. But we might use 16 or 14 bit samples,
794            in which case 4MB is more samples than that. Therefore size this for
795            the smallest sample value .. 4MB = 2M samples (16 bit).
796         */
797
798         {
799                 boost::scoped_array<Sample> sum_buf (new Sample[2*1048576]);
800                 boost::scoped_array<Sample> mix_buf (new Sample[2*1048576]);
801                 boost::scoped_array<float>  gain_buf (new float[2*1048576]);
802
803                 int ret = refill_audio (sum_buf.get(), mix_buf.get(), gain_buf.get(), (partial_fill ? _chunk_samples : 0));
804
805                 if (ret) {
806                         return ret;
807                 }
808         }
809
810         return refill_midi ();
811 }
812
813 int
814 DiskReader::refill (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level)
815 {
816         int ret = refill_audio (sum_buffer, mixdown_buffer, gain_buffer, fill_level);
817
818         if (ret) {
819                 return ret;
820         }
821
822         return refill_midi ();
823 }
824
825
826 /** Get some more data from disk and put it in our channels' bufs,
827  *  if there is suitable space in them.
828  *
829  * If fill_level is non-zero, then we will refill the buffer so that there is
830  * still at least fill_level samples of space left to be filled. This is used
831  * after locates so that we do not need to wait to fill the entire buffer.
832  *
833  */
834
835 int
836 DiskReader::refill_audio (Sample* sum_buffer, Sample* mixdown_buffer, float* gain_buffer, samplecnt_t fill_level)
837 {
838         /* do not read from disk while session is marked as Loading, to avoid
839            useless redundant I/O.
840         */
841
842         if (_session.loading()) {
843                 return 0;
844         }
845
846         int32_t ret = 0;
847         bool const reversed = _session.transport_speed() < 0.0f;
848         samplecnt_t zero_fill;
849         uint32_t chan_n;
850         ChannelList::iterator i;
851         boost::shared_ptr<ChannelList> c = channels.reader();
852
853         if (c->empty()) {
854                 return 0;
855         }
856
857         assert(mixdown_buffer);
858         assert(gain_buffer);
859
860         samplecnt_t total_space = c->front()->rbuf->write_space();
861
862         if (total_space == 0) {
863                 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: no space to refill\n", name()));
864                 /* nowhere to write to */
865                 return 0;
866         }
867
868         if (fill_level) {
869                 if (fill_level < total_space) {
870                         total_space -= fill_level;
871                 } else {
872                         /* we can't do anything with it */
873                         fill_level = 0;
874                 }
875         }
876
877         /* if we're running close to normal speed and there isn't enough
878            space to do disk_read_chunk_samples of I/O, then don't bother.
879
880            at higher speeds, just do it because the sync between butler
881            and audio thread may not be good enough.
882
883            Note: it is a design assumption that disk_read_chunk_samples is smaller
884            than the playback buffer size, so this check should never trip when
885            the playback buffer is empty.
886         */
887
888         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: space to refill %2 vs. chunk %3 (speed = %4)\n", name(), total_space, _chunk_samples, _session.transport_speed()));
889         if ((total_space < _chunk_samples) && fabs (_session.transport_speed()) < 2.0f) {
890                 return 0;
891         }
892
893         /* when slaved, don't try to get too close to the read pointer. this
894            leaves space for the buffer reversal to have something useful to
895            work with.
896         */
897
898         if (_slaved && total_space < (samplecnt_t) (c->front()->rbuf->bufsize() / 2)) {
899                 DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: not enough to refill while slaved\n", this));
900                 return 0;
901         }
902
903         samplepos_t ffa = file_sample[DataType::AUDIO];
904
905         if (reversed) {
906
907                 if (ffa == 0) {
908                         /* at start: nothing to do but fill with silence */
909                         for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
910                                 ChannelInfo* chan (*i);
911                                 // TODO optimize use zero-buffer
912                                 samplecnt_t ws = chan->rbuf->write_space ();
913                                 for (uint32_t z = 0; z < ws; ++z) {
914                                         Sample t = 0;
915                                         chan->rbuf->write (&t, 1);
916                                 }
917                         }
918                         return 0;
919                 }
920
921                 if (ffa < total_space) {
922                         /* too close to the start: read what we can, and then zero fill the rest */
923                         zero_fill = total_space - ffa;
924                         total_space = ffa;
925                 } else {
926                         zero_fill = 0;
927                 }
928
929         } else {
930
931                 if (ffa == max_samplepos) {
932                         /* at end: nothing to do but fill with silence */
933                         for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
934                                 ChannelInfo* chan (*i);
935                                 // TODO optimize use zero-buffer
936                                 samplecnt_t ws = chan->rbuf->write_space ();
937                                 for (uint32_t z = 0; z < ws; ++z) {
938                                         Sample t = 0;
939                                         chan->rbuf->write (&t, 1);
940                                 }
941                         }
942                         return 0;
943                 }
944
945                 if (ffa > max_samplepos - total_space) {
946                         /* to close to the end: read what we can, and zero fill the rest */
947                         zero_fill = total_space - (max_samplepos - ffa);
948                         total_space = max_samplepos - ffa;
949
950                 } else {
951                         zero_fill = 0;
952                 }
953         }
954
955         /* total_space is in samples. We want to optimize read sizes in various sizes using bytes */
956         const size_t bits_per_sample = format_data_width (_session.config.get_native_file_data_format());
957         size_t total_bytes = total_space * bits_per_sample / 8;
958
959         /* chunk size range is 256kB to 4MB. Bigger is faster in terms of MB/sec, but bigger chunk size always takes longer */
960         size_t byte_size_for_read = max ((size_t) (256 * 1024), min ((size_t) (4 * 1048576), total_bytes));
961
962         /* find nearest (lower) multiple of 16384 */
963
964         byte_size_for_read = (byte_size_for_read / 16384) * 16384;
965
966         /* now back to samples */
967         samplecnt_t samples_to_read = byte_size_for_read / (bits_per_sample / 8);
968
969         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1: will refill %2 channels with %3 samples\n", name(), c->size(), total_space));
970
971         samplepos_t file_sample_tmp = ffa;
972
973         for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) {
974                 ChannelInfo* chan (*i);
975                 file_sample_tmp = ffa;
976                 samplecnt_t ts = total_space;
977
978                 samplecnt_t to_read = min (ts, (samplecnt_t) chan->rbuf->write_space ());
979                 to_read = min (to_read, samples_to_read);
980                 assert (to_read >= 0);
981
982                 cerr << owner()->name() << " to-read: " << to_read << endl;
983
984                 if (to_read) {
985                         if (audio_read (chan->rbuf, sum_buffer, mixdown_buffer, gain_buffer, file_sample_tmp, to_read, chan_n, reversed)) {
986                                 error << string_compose(_("DiskReader %1: when refilling, cannot read %2 from playlist at sample %3"), id(), to_read, ffa) << endmsg;
987                                 ret = -1;
988                                 goto out;
989                         }
990                 }
991
992                 if (zero_fill) {
993                         /* XXX: do something */
994                 }
995         }
996
997         // elapsed = g_get_monotonic_time () - before;
998         // cerr << '\t' << name() << ": bandwidth = " << (byte_size_for_read / 1048576.0) / (elapsed/1000000.0) << "MB/sec\n";
999
1000         file_sample[DataType::AUDIO] = file_sample_tmp;
1001         assert (file_sample[DataType::AUDIO] >= 0);
1002
1003         ret = ((total_space - samples_to_read) > _chunk_samples);
1004
1005   out:
1006         return ret;
1007 }
1008
1009 void
1010 DiskReader::playlist_ranges_moved (list< Evoral::RangeMove<samplepos_t> > const & movements_samples, bool from_undo_or_shift)
1011 {
1012         /* If we're coming from an undo, it will have handled
1013          * automation undo (it must, since automation-follows-regions
1014          * can lose automation data).  Hence we can do nothing here.
1015          *
1016          * Likewise when shifting regions (insert/remove time)
1017          * automation is taken care of separately (busses with
1018          * automation have no disk-reader).
1019          */
1020
1021         if (from_undo_or_shift) {
1022                 return;
1023         }
1024
1025         if (!_route || Config->get_automation_follows_regions () == false) {
1026                 return;
1027         }
1028
1029         list< Evoral::RangeMove<double> > movements;
1030
1031         for (list< Evoral::RangeMove<samplepos_t> >::const_iterator i = movements_samples.begin();
1032              i != movements_samples.end();
1033              ++i) {
1034
1035                 movements.push_back(Evoral::RangeMove<double>(i->from, i->length, i->to));
1036         }
1037
1038         /* move panner automation */
1039         boost::shared_ptr<Pannable> pannable = _route->pannable();
1040         Evoral::ControlSet::Controls& c (pannable->controls());
1041
1042         for (Evoral::ControlSet::Controls::iterator ci = c.begin(); ci != c.end(); ++ci) {
1043                 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl>(ci->second);
1044                 if (!ac) {
1045                         continue;
1046                 }
1047                 boost::shared_ptr<AutomationList> alist = ac->alist();
1048                 if (!alist->size()) {
1049                         continue;
1050                 }
1051                 XMLNode & before = alist->get_state ();
1052                 bool const things_moved = alist->move_ranges (movements);
1053                 if (things_moved) {
1054                         _session.add_command (new MementoCommand<AutomationList> (
1055                                                       *alist.get(), &before, &alist->get_state ()));
1056                 }
1057         }
1058         /* move processor automation */
1059         _route->foreach_processor (boost::bind (&DiskReader::move_processor_automation, this, _1, movements_samples));
1060 }
1061
1062 void
1063 DiskReader::move_processor_automation (boost::weak_ptr<Processor> p, list< Evoral::RangeMove<samplepos_t> > const & movements_samples)
1064 {
1065         boost::shared_ptr<Processor> processor (p.lock ());
1066         if (!processor) {
1067                 return;
1068         }
1069
1070         list< Evoral::RangeMove<double> > movements;
1071         for (list< Evoral::RangeMove<samplepos_t> >::const_iterator i = movements_samples.begin(); i != movements_samples.end(); ++i) {
1072                 movements.push_back(Evoral::RangeMove<double>(i->from, i->length, i->to));
1073         }
1074
1075         set<Evoral::Parameter> const a = processor->what_can_be_automated ();
1076
1077         for (set<Evoral::Parameter>::const_iterator i = a.begin (); i != a.end (); ++i) {
1078                 boost::shared_ptr<AutomationList> al = processor->automation_control(*i)->alist();
1079                 if (!al->size()) {
1080                         continue;
1081                 }
1082                 XMLNode & before = al->get_state ();
1083                 bool const things_moved = al->move_ranges (movements);
1084                 if (things_moved) {
1085                         _session.add_command (
1086                                 new MementoCommand<AutomationList> (
1087                                         *al.get(), &before, &al->get_state ()
1088                                         )
1089                                 );
1090                 }
1091         }
1092 }
1093
1094 void
1095 DiskReader::reset_tracker ()
1096 {
1097         if (_midi_buf) {
1098                 _midi_buf->reset_tracker ();
1099         }
1100
1101         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1102
1103         if (mp) {
1104                 mp->reset_note_trackers ();
1105         }
1106 }
1107
1108 void
1109 DiskReader::resolve_tracker (Evoral::EventSink<samplepos_t>& buffer, samplepos_t time)
1110 {
1111         if (_midi_buf) {
1112                 _midi_buf->resolve_tracker(buffer, time);
1113         }
1114
1115         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1116
1117         if (mp) {
1118                 mp->reset_note_trackers ();
1119         }
1120 }
1121
1122 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1123  *  so that an event at playback_sample has time = 0
1124  */
1125 void
1126 DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, samplepos_t end_sample, MonitorState ms, BufferSet& scratch_bufs, double speed, samplecnt_t disk_samples_to_consume)
1127 {
1128         MidiBuffer* target;
1129         samplepos_t nframes = end_sample - start_sample;
1130
1131         assert (_midi_buf);
1132
1133         if ((ms & MonitoringInput) == 0) {
1134                 /* Route::process_output_buffers() clears the buffer as-needed */
1135                 target = &dst;
1136         } else {
1137                 target = &scratch_bufs.get_midi (0);
1138         }
1139
1140         if (ms & MonitoringDisk) {
1141                 /* disk data needed */
1142
1143                 Location* loc = _loop_location;
1144
1145                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1146                                      "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
1147                                      _midi_buf->get_read_ptr(), _midi_buf->get_write_ptr(), start_sample, end_sample,
1148                                      (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
1149
1150                 //cerr << "======== PRE ========\n";
1151                 //_midi_buf->dump (cerr);
1152                 //cerr << "----------------\n";
1153
1154                 size_t events_read = 0;
1155
1156                 if (loc) {
1157                         samplepos_t effective_start;
1158
1159                         Evoral::Range<samplepos_t> loop_range (loc->start(), loc->end() - 1);
1160                         effective_start = loop_range.squish (start_sample);
1161
1162                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1163
1164                         if (effective_start == loc->start()) {
1165                                 /* We need to turn off notes that may extend
1166                                    beyond the loop end.
1167                                 */
1168
1169                                 _midi_buf->resolve_tracker (*target, 0);
1170                         }
1171
1172                         /* for split-cycles we need to offset the events */
1173
1174                         if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1175
1176                                 /* end of loop is within the range we are reading, so
1177                                    split the read in two, and lie about the location
1178                                    for the 2nd read
1179                                 */
1180
1181                                 samplecnt_t first, second;
1182
1183                                 first = loc->end() - effective_start;
1184                                 second = nframes - first;
1185
1186                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4, cycle offset %5\n",
1187                                                                                       effective_start, loc->end(), first, second));
1188
1189                                 if (first) {
1190                                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1191                                                                                               effective_start, first));
1192                                         events_read = _midi_buf->read (*target, effective_start, first);
1193                                 }
1194
1195                                 if (second) {
1196                                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1197                                                                                               loc->start(), second));
1198                                         events_read += _midi_buf->read (*target, loc->start(), second);
1199                                 }
1200
1201                         } else {
1202                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1203                                                                                       effective_start, nframes));
1204                                 events_read = _midi_buf->read (*target, effective_start, effective_start + nframes);
1205                         }
1206                 } else {
1207                         const size_t n_skipped = _midi_buf->skip_to (start_sample);
1208                         if (n_skipped > 0) {
1209                                 warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
1210                         }
1211                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", start_sample, end_sample, nframes));
1212                         events_read = _midi_buf->read (*target, start_sample, end_sample, Port::port_offset ());
1213                 }
1214
1215                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1216                                      "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1217                                      _name, events_read, playback_sample, playback_sample + nframes,
1218                                      _midi_buf->read_space(), _midi_buf->write_space(),
1219                                      _midi_buf->get_read_ptr(), _midi_buf->get_write_ptr()));
1220         }
1221
1222         g_atomic_int_add (&_samples_read_from_ringbuffer, nframes);
1223
1224         /* vari-speed */
1225         if (speed != 0.0 && fabsf (speed) != 1.0f) {
1226                 for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) {
1227                         MidiBuffer::TimeType *tme = i.timeptr();
1228                         // XXX need to subtract port offsets before scaling
1229                         // also we must only scale events read from disk
1230                         // and not existing input data in the buffer.
1231                         *tme = (*tme) * nframes / disk_samples_to_consume;
1232                 }
1233         }
1234
1235         if (ms & MonitoringInput) {
1236                 dst.merge_from (*target, nframes);
1237         }
1238
1239 #if 0
1240         if (!target->empty ()) {
1241                 cerr << "======== MIDI OUT ========\n";
1242                 for (MidiBuffer::iterator i = target->begin(); i != target->end(); ++i) {
1243                         const Evoral::Event<MidiBuffer::TimeType> ev (*i, false);
1244                         cerr << "MIDI EVENT (from disk) @ " << ev.time();
1245                         for (size_t xx = 0; xx < ev.size(); ++xx) {
1246                                 cerr << ' ' << hex << (int) ev.buffer()[xx];
1247                         }
1248                         cerr << dec << endl;
1249                 }
1250                 cerr << "----------------\n";
1251         }
1252 #endif
1253 #if 0
1254         cerr << "======== MIDI Disk Buffer ========\n";
1255         _midi_buf->dump (cerr);
1256         cerr << "----------------\n";
1257 #endif
1258 }
1259
1260 /** @a start is set to the new sample position (TIME) read up to */
1261 int
1262 DiskReader::midi_read (samplepos_t& start, samplecnt_t dur, bool reversed)
1263 {
1264         samplecnt_t this_read   = 0;
1265         samplepos_t loop_end    = 0;
1266         samplepos_t loop_start  = 0;
1267         samplecnt_t loop_length = 0;
1268         Location*  loc         = _loop_location;
1269         samplepos_t effective_start = start;
1270         Evoral::Range<samplepos_t>*  loop_range (0);
1271
1272         assert(_midi_buf);
1273
1274         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS::midi_read @ %1 cnt %2\n", start, dur));
1275
1276         boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack>(_route);
1277         MidiChannelFilter* filter = mt ? &mt->playback_filter() : 0;
1278         sampleoffset_t loop_offset = 0;
1279
1280         if (!reversed && loc) {
1281                 get_location_times (loc, &loop_start, &loop_end, &loop_length);
1282         }
1283
1284         while (dur) {
1285
1286                 /* take any loop into account. we can't read past the end of the loop. */
1287
1288                 if (loc && !reversed) {
1289
1290                         if (!loop_range) {
1291                                 loop_range = new Evoral::Range<samplepos_t> (loop_start, loop_end-1); // inclusive semantics require -1
1292                         }
1293
1294                         /* if we are (seamlessly) looping, ensure that the first sample we read is at the correct
1295                            position within the loop.
1296                         */
1297
1298                         effective_start = loop_range->squish (effective_start);
1299
1300                         if ((loop_end - effective_start) <= dur) {
1301                                 /* too close to end of loop to read "dur", so
1302                                    shorten it.
1303                                 */
1304                                 this_read = loop_end - effective_start;
1305                         } else {
1306                                 this_read = dur;
1307                         }
1308
1309                 } else {
1310                         this_read = dur;
1311                 }
1312
1313                 if (this_read == 0) {
1314                         break;
1315                 }
1316
1317                 this_read = min (dur,this_read);
1318
1319                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS ::read at %1 for %2 loffset %3\n", effective_start, this_read, loop_offset));
1320
1321                 if (midi_playlist()->read (*_midi_buf, effective_start, this_read, loop_range, 0, filter) != this_read) {
1322                         error << string_compose(
1323                                         _("MidiDiskstream %1: cannot read %2 from playlist at sample %3"),
1324                                         id(), this_read, start) << endmsg;
1325                         return -1;
1326                 }
1327
1328                 g_atomic_int_add (&_samples_written_to_ringbuffer, this_read);
1329
1330                 if (reversed) {
1331
1332                         // Swap note ons with note offs here.  etc?
1333                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
1334                         // CC values etc.  hard.
1335
1336                 } else {
1337
1338                         /* adjust passed-by-reference argument (note: this is
1339                            monotonic and does not reflect looping.
1340                         */
1341                         start += this_read;
1342
1343                         /* similarly adjust effective_start, but this may be
1344                            readjusted for seamless looping as we continue around
1345                            the loop.
1346                         */
1347                         effective_start += this_read;
1348                 }
1349
1350                 dur -= this_read;
1351         }
1352
1353         return 0;
1354 }
1355
1356 int
1357 DiskReader::refill_midi ()
1358 {
1359         if (!_playlists[DataType::MIDI] || !_midi_buf) {
1360                 return 0;
1361         }
1362
1363         const size_t  write_space = _midi_buf->write_space();
1364         const bool reversed    = _session.transport_speed() < 0.0f;
1365
1366         DEBUG_TRACE (DEBUG::DiskIO, string_compose ("MIDI refill, write space = %1 file sample = %2\n", write_space, file_sample[DataType::MIDI]));
1367
1368         /* no space to write */
1369         if (write_space == 0) {
1370                 return 0;
1371         }
1372
1373         if (reversed) {
1374                 return 0;
1375         }
1376
1377         /* at end: nothing to do */
1378
1379         samplepos_t ffm = file_sample[DataType::MIDI];
1380
1381         if (ffm == max_samplepos) {
1382                 return 0;
1383         }
1384
1385         int ret = 0;
1386         const uint32_t samples_read = g_atomic_int_get (&_samples_read_from_ringbuffer);
1387         const uint32_t samples_written = g_atomic_int_get (&_samples_written_to_ringbuffer);
1388
1389         if ((samples_read < samples_written) && (samples_written - samples_read) >= midi_readahead) {
1390                 return 0;
1391         }
1392
1393         samplecnt_t to_read = midi_readahead - ((samplecnt_t)samples_written - (samplecnt_t)samples_read);
1394
1395         to_read = min (to_read, (samplecnt_t) (max_samplepos - ffm));
1396         to_read = min (to_read, (samplecnt_t) write_space);
1397
1398         if (midi_read (ffm, to_read, reversed)) {
1399                 ret = -1;
1400         }
1401
1402         file_sample[DataType::MIDI] = ffm;
1403
1404         return ret;
1405 }
1406
1407 void
1408 DiskReader::set_no_disk_output (bool yn)
1409 {
1410         /* this MUST be called as part of the process call tree, before any
1411            disk readers are invoked. We use it when the session needs the
1412            transport (and thus effective read position for DiskReaders) to keep
1413            advancing as part of syncing up with a transport master, but we
1414            don't want any actual disk output yet because we are still not
1415            synced.
1416         */
1417         _no_disk_output = yn;
1418 }