359dd573cf513f32dd466799b3e65e0e75bdd5ad
[ardour.git] / libs / ardour / midi_diskstream.cc
1 /*
2     Copyright (C) 2000-2003 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <cstdio>
20 #include <unistd.h>
21 #include <cmath>
22 #include <cerrno>
23 #include <string>
24 #include <climits>
25 #include <fcntl.h>
26 #include <cstdlib>
27 #include <ctime>
28 #include <sys/stat.h>
29
30 #include "pbd/error.h"
31 #include "pbd/ffs.h"
32 #include "pbd/basename.h"
33 #include <glibmm/threads.h>
34 #include "pbd/xml++.h"
35 #include "pbd/memento_command.h"
36 #include "pbd/enumwriter.h"
37 #include "pbd/stateful_diff_command.h"
38 #include "pbd/stacktrace.h"
39
40 #include "ardour/audioengine.h"
41 #include "ardour/butler.h"
42 #include "ardour/debug.h"
43 #include "ardour/io.h"
44 #include "ardour/midi_diskstream.h"
45 #include "ardour/midi_model.h"
46 #include "ardour/midi_playlist.h"
47 #include "ardour/midi_port.h"
48 #include "ardour/midi_region.h"
49 #include "ardour/midi_ring_buffer.h"
50 #include "ardour/midi_track.h"
51 #include "ardour/playlist_factory.h"
52 #include "ardour/region_factory.h"
53 #include "ardour/session.h"
54 #include "ardour/session_playlists.h"
55 #include "ardour/smf_source.h"
56 #include "ardour/types.h"
57 #include "ardour/utils.h"
58
59 #include "midi++/types.h"
60
61 #include "pbd/i18n.h"
62 #include <locale.h>
63
64 using namespace std;
65 using namespace ARDOUR;
66 using namespace PBD;
67
68 framecnt_t MidiDiskstream::midi_readahead = 4096;
69
70 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
71         : Diskstream(sess, name, flag)
72         , _playback_buf(0)
73         , _capture_buf(0)
74         , _note_mode(Sustained)
75         , _frames_written_to_ringbuffer(0)
76         , _frames_read_from_ringbuffer(0)
77         , _frames_pending_write(0)
78         , _num_captured_loops(0)
79         , _accumulated_capture_offset(0)
80         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
81 {
82         in_set_state = true;
83
84         init ();
85         use_new_playlist ();
86         use_new_write_source (0);
87
88         in_set_state = false;
89
90         if (destructive()) {
91                 throw failed_constructor();
92         }
93 }
94
95 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
96         : Diskstream(sess, node)
97         , _playback_buf(0)
98         , _capture_buf(0)
99         , _note_mode(Sustained)
100         , _frames_written_to_ringbuffer(0)
101         , _frames_read_from_ringbuffer(0)
102         , _frames_pending_write(0)
103         , _num_captured_loops(0)
104         , _accumulated_capture_offset(0)
105         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
106 {
107         in_set_state = true;
108
109         init ();
110
111         if (set_state (node, Stateful::loading_state_version)) {
112                 in_set_state = false;
113                 throw failed_constructor();
114         }
115
116         use_new_write_source (0);
117
118         in_set_state = false;
119 }
120
121 void
122 MidiDiskstream::init ()
123 {
124         /* there are no channels at this point, so these
125            two calls just get speed_buffer_size and wrap_buffer
126            size setup without duplicating their code.
127         */
128
129         set_block_size (_session.get_block_size());
130         allocate_temporary_buffers ();
131
132         const size_t size = _session.butler()->midi_diskstream_buffer_size();
133         _playback_buf = new MidiRingBuffer<framepos_t>(size);
134         _capture_buf = new MidiRingBuffer<framepos_t>(size);
135
136         _n_channels = ChanCount(DataType::MIDI, 1);
137         interpolation.add_channel_to (0,0);
138 }
139
140 MidiDiskstream::~MidiDiskstream ()
141 {
142         Glib::Threads::Mutex::Lock lm (state_lock);
143         delete _playback_buf;
144         delete _capture_buf;
145 }
146
147
148 void
149 MidiDiskstream::non_realtime_locate (framepos_t position)
150 {
151         if (_write_source) {
152                 _write_source->set_timeline_position (position);
153         }
154         seek (position, false);
155 }
156
157
158 void
159 MidiDiskstream::non_realtime_input_change ()
160 {
161         {
162                 Glib::Threads::Mutex::Lock lm (state_lock);
163
164                 if (input_change_pending.type == IOChange::NoChange) {
165                         return;
166                 }
167
168                 if (input_change_pending.type & IOChange::ConfigurationChanged) {
169                         uint32_t ni = _io->n_ports().n_midi();
170
171                         if (ni != _n_channels.n_midi()) {
172                                 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
173                                                          name(),
174                                                          _io->n_ports(),
175                                                          _n_channels, input_change_pending.type)
176                                       << endmsg;
177                         }
178
179                         if (ni == 0) {
180                                 _source_port.reset ();
181                         } else {
182                                 _source_port = _io->midi(0);
183                         }
184                 }
185
186                 if (input_change_pending.type & IOChange::ConnectionsChanged) {
187                         set_capture_offset ();
188                         set_align_style_from_io ();
189                 }
190
191                 input_change_pending.type = IOChange::NoChange;
192
193                 /* implicit unlock */
194         }
195
196         /* unlike with audio, there is never any need to reset write sources
197            based on input configuration changes because ... a MIDI track
198            has just 1 MIDI port as input, always.
199         */
200
201         /* now refill channel buffers */
202
203         if (speed() != 1.0f || speed() != -1.0f) {
204                 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
205         }
206         else {
207                 seek (_session.transport_frame());
208         }
209
210         g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
211         g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
212 }
213
214 int
215 MidiDiskstream::find_and_use_playlist (const string& name)
216 {
217         boost::shared_ptr<MidiPlaylist> playlist;
218
219         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
220                 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
221         }
222
223         if (!playlist) {
224                 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
225                 return -1;
226         }
227
228         return use_playlist (playlist);
229 }
230
231 int
232 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
233 {
234         if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
235                 Diskstream::use_playlist(playlist);
236         }
237
238         return 0;
239 }
240
241 int
242 MidiDiskstream::use_new_playlist ()
243 {
244         string newname;
245         boost::shared_ptr<MidiPlaylist> playlist;
246
247         if (!in_set_state && destructive()) {
248                 return 0;
249         }
250
251         if (_playlist) {
252                 newname = Playlist::bump_name (_playlist->name(), _session);
253         } else {
254                 newname = Playlist::bump_name (_name, _session);
255         }
256
257         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
258                         DataType::MIDI, _session, newname, hidden()))) != 0) {
259
260                 return use_playlist (playlist);
261
262         } else {
263                 return -1;
264         }
265 }
266
267 int
268 MidiDiskstream::use_copy_playlist ()
269 {
270         if (destructive()) {
271                 return 0;
272         }
273
274         if (_playlist == 0) {
275                 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
276                 return -1;
277         }
278
279         string newname;
280         boost::shared_ptr<MidiPlaylist> playlist;
281
282         newname = Playlist::bump_name (_playlist->name(), _session);
283
284         if ((playlist  = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
285                 return use_playlist (playlist);
286         } else {
287                 return -1;
288         }
289 }
290
291 /** Overloaded from parent to die horribly
292  */
293 int
294 MidiDiskstream::set_destructive (bool yn)
295 {
296         return yn ? -1 : 0;
297 }
298
299 void
300 MidiDiskstream::set_note_mode (NoteMode m)
301 {
302         _note_mode = m;
303         midi_playlist()->set_note_mode(m);
304         if (_write_source && _write_source->model())
305                 _write_source->model()->set_note_mode(m);
306 }
307
308 /** Get the start, end, and length of a location "atomically".
309  *
310  * Note: Locations don't get deleted, so all we care about when I say "atomic"
311  * is that we are always pointing to the same one and using start/length values
312  * obtained just once.  Use this function to achieve this since location being
313  * a parameter achieves this.
314  */
315 static void
316 get_location_times(const Location* location,
317                    framepos_t*     start,
318                    framepos_t*     end,
319                    framepos_t*     length)
320 {
321         if (location) {
322                 *start  = location->start();
323                 *end    = location->end();
324                 *length = *end - *start;
325         }
326 }
327
328 int
329 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
330 {
331         framecnt_t rec_offset = 0;
332         framecnt_t rec_nframes = 0;
333         bool      nominally_recording;
334         bool      re = record_enabled ();
335         bool      can_record = _session.actively_recording ();
336
337         playback_distance = 0;
338
339         check_record_status (transport_frame, can_record);
340
341         nominally_recording = (can_record && re);
342
343         if (nframes == 0) {
344                 return 0;
345         }
346
347         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
348
349         if (sp == 0) {
350                 return 1;
351         }
352
353         Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
354
355         if (!sm.locked()) {
356                 return 1;
357         }
358
359         const Location* const loop_loc    = loop_location;
360         framepos_t            loop_start  = 0;
361         framepos_t            loop_end    = 0;
362         framepos_t            loop_length = 0;
363
364         get_location_times (loop_loc, &loop_start, &loop_end, &loop_length);
365
366         adjust_capture_position = 0;
367
368         if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
369                 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
370                 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
371
372                 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
373                 /* For audio: not writing frames to the capture ringbuffer offsets
374                  * the recording. For midi: we need to keep track of the record range
375                  * and subtract the accumulated difference from the event time.
376                  */
377                 if (rec_nframes) {
378                         _accumulated_capture_offset += rec_offset;
379                 } else {
380                         _accumulated_capture_offset += nframes;
381                 }
382
383                 if (rec_nframes && !was_recording) {
384                         if (loop_loc) {
385                                 /* Loop recording, so pretend the capture started at the loop
386                                    start rgardless of what time it is now, so the source starts
387                                    at the loop start and can handle time wrapping around.
388                                    Otherwise, start the source right now as usual.
389                                 */
390                                 capture_captured    = transport_frame - loop_start;
391                                 capture_start_frame = loop_start;
392                         }
393                         _write_source->mark_write_starting_now(
394                                 capture_start_frame, capture_captured, loop_length);
395                         g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
396                         g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
397                         was_recording = true;
398                 }
399         }
400
401         if (can_record && !_last_capture_sources.empty()) {
402                 _last_capture_sources.clear ();
403         }
404
405         if (nominally_recording || rec_nframes) {
406                 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
407                 MidiBuffer&        buf    = sp->get_midi_buffer(nframes);
408                 MidiTrack*         mt     = dynamic_cast<MidiTrack*>(_track);
409                 MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
410
411                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
412                         Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
413                         if (ev.time() + rec_offset > rec_nframes) {
414                                 break;
415                         }
416 #ifndef NDEBUG
417                         if (DEBUG_ENABLED(DEBUG::MidiIO)) {
418                                 const uint8_t* __data = ev.buffer();
419                                 DEBUG_STR_DECL(a);
420                                 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
421                                 for (size_t i=0; i < ev.size(); ++i) {
422                                         DEBUG_STR_APPEND(a,hex);
423                                         DEBUG_STR_APPEND(a,"0x");
424                                         DEBUG_STR_APPEND(a,(int)__data[i]);
425                                         DEBUG_STR_APPEND(a,' ');
426                                 }
427                                 DEBUG_STR_APPEND(a,'\n');
428                                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
429                         }
430 #endif
431                         /* Write events to the capture buffer in frames from session start,
432                            but ignoring looping so event time progresses monotonically.
433                            The source knows the loop length so it knows exactly where the
434                            event occurs in the series of recorded loops and can implement
435                            any desirable behaviour.  We don't want to send event with
436                            transport time here since that way the source can not
437                            reconstruct their actual time; future clever MIDI looping should
438                            probably be implemented in the source instead of here.
439                         */
440                         const framecnt_t loop_offset = _num_captured_loops * loop_length;
441                         const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
442                         if (event_time < 0 || event_time < first_recordable_frame) {
443                                 /* Event out of range, skip */
444                                 continue;
445                         }
446
447                         if (!filter || !filter->filter(ev.buffer(), ev.size())) {
448                                 _capture_buf->write(event_time, ev.type(), ev.size(), ev.buffer());
449                         }
450                 }
451                 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
452
453                 if (buf.size() != 0) {
454                         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
455
456                         if (lm.locked ()) {
457                                 /* Copy this data into our GUI feed buffer and tell the GUI
458                                    that it can read it if it likes.
459                                 */
460                                 _gui_feed_buffer.clear ();
461
462                                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
463                                         /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
464                                            the end of the world if it does.
465                                         */
466                                         _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
467                                 }
468                         }
469
470                         DataRecorded (_write_source); /* EMIT SIGNAL */
471                 }
472
473         } else {
474
475                 if (was_recording) {
476                         finish_capture ();
477                 }
478                 _accumulated_capture_offset = 0;
479
480         }
481
482         if (rec_nframes) {
483
484                 /* data will be written to disk */
485
486                 if (rec_nframes == nframes && rec_offset == 0) {
487                         playback_distance = nframes;
488                 }
489
490                 adjust_capture_position = rec_nframes;
491
492         } else if (nominally_recording) {
493
494                 /* XXXX do this for MIDI !!!
495                    can't do actual capture yet - waiting for latency effects to finish before we start
496                    */
497
498                 playback_distance = nframes;
499
500         } else if (_actual_speed != 1.0f && _target_speed > 0) {
501
502                 interpolation.set_speed (_target_speed);
503
504                 playback_distance = interpolation.distance  (nframes);
505
506         } else {
507                 playback_distance = nframes;
508         }
509
510         if (need_disk_signal && !_session.declick_out_pending()) {
511                 /* copy the diskstream data to all output buffers */
512
513                 MidiBuffer& mbuf (bufs.get_midi (0));
514                 get_playback (mbuf, playback_distance);
515
516                 /* leave the audio count alone */
517                 ChanCount cnt (DataType::MIDI, 1);
518                 cnt.set (DataType::AUDIO, bufs.count().n_audio());
519                 bufs.set_count (cnt);
520
521                 /* vari-speed */
522                 if (_target_speed > 0 && _actual_speed != 1.0f) {
523                         MidiBuffer& mbuf (bufs.get_midi (0));
524                         for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
525                                 MidiBuffer::TimeType *tme = i.timeptr();
526                                 *tme = (*tme) * nframes / playback_distance;
527                         }
528                 }
529         }
530
531         return 0;
532 }
533
534 frameoffset_t
535 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
536 {
537         frameoffset_t playback_distance = nframes;
538
539         if (!record_enabled() && _actual_speed != 1.0f && _actual_speed > 0.f) {
540                 interpolation.set_speed (_target_speed);
541                 playback_distance = interpolation.distance (nframes, false);
542         }
543
544         if (_actual_speed < 0.0) {
545                 return -playback_distance;
546         } else {
547                 return playback_distance;
548         }
549 }
550
551 bool
552 MidiDiskstream::commit (framecnt_t playback_distance)
553 {
554         bool need_butler = false;
555
556         if (!_io || !_io->active()) {
557                 return false;
558         }
559
560         if (_actual_speed < 0.0) {
561                 playback_sample -= playback_distance;
562         } else {
563                 playback_sample += playback_distance;
564         }
565
566         if (adjust_capture_position != 0) {
567                 capture_captured += adjust_capture_position;
568                 adjust_capture_position = 0;
569         }
570
571         uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
572         uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
573
574         /*
575           cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
576           " = " << frames_written - frames_read
577           << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
578         */
579
580         /* frames_read will generally be less than frames_written, but
581          * immediately after an overwrite, we can end up having read some data
582          * before we've written any. we don't need to trip an assert() on this,
583          * but we do need to check so that the decision on whether or not we
584          * need the butler is done correctly.
585          */
586
587         /* furthermore..
588          *
589          * Doing heavy GUI operations[1] can stall also the butler.
590          * The RT-thread meanwhile will happily continue and
591          * â€˜frames_read’ (from buffer to output) will become larger
592          * than â€˜frames_written’ (from disk to buffer).
593          *
594          * The disk-stream is now behind..
595          *
596          * In those cases the butler needs to be summed to refill the buffer (done now)
597          * AND we need to skip (frames_read - frames_written). ie remove old events
598          * before playback_sample from the rinbuffer.
599          *
600          * [1] one way to do so is described at #6170.
601          * For me just popping up the context-menu on a MIDI-track header
602          * of a track with a large (think beethoven :) midi-region also did the
603          * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
604          *
605          * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
606          * and can stall
607          */
608         if (frames_read <= frames_written) {
609                 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
610                         need_butler = true;
611                 }
612         } else {
613                 need_butler = true;
614         }
615
616
617         return need_butler;
618 }
619
620 void
621 MidiDiskstream::set_pending_overwrite (bool yn)
622 {
623         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
624
625         _pending_overwrite = yn;
626         overwrite_frame = playback_sample;
627 }
628
629 int
630 MidiDiskstream::overwrite_existing_buffers ()
631 {
632         /* Clear the playback buffer contents.  This is safe as long as the butler
633            thread is suspended, which it should be. */
634         _playback_buf->reset ();
635         _playback_buf->reset_tracker ();
636
637         g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
638         g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
639
640         /* Resolve all currently active notes in the playlist.  This is more
641            aggressive than it needs to be: ideally we would only resolve what is
642            absolutely necessary, but this seems difficult and/or impossible without
643            having the old data or knowing what change caused the overwrite. */
644         midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
645
646         read (overwrite_frame, disk_read_chunk_frames, false);
647         file_frame = overwrite_frame; // it was adjusted by ::read()
648         overwrite_queued = false;
649         _pending_overwrite = false;
650
651         return 0;
652 }
653
654 int
655 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
656 {
657         Glib::Threads::Mutex::Lock lm (state_lock);
658         int ret = -1;
659
660         if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
661                 /* we haven't read anything since the last seek,
662                    so flush all note trackers to prevent
663                    wierdness
664                 */
665                 reset_tracker ();
666         }
667
668         _playback_buf->reset();
669         _capture_buf->reset();
670         g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
671         g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
672
673         playback_sample = frame;
674         file_frame = frame;
675
676         if (complete_refill) {
677                 while ((ret = do_refill_with_alloc ()) > 0) ;
678         } else {
679                 ret = do_refill_with_alloc ();
680         }
681
682         return ret;
683 }
684
685 int
686 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
687 {
688         uint32_t frames_read    = g_atomic_int_get(&_frames_read_from_ringbuffer);
689         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
690         return ((frames_written - frames_read) < distance);
691 }
692
693 int
694 MidiDiskstream::internal_playback_seek (framecnt_t distance)
695 {
696         first_recordable_frame += distance;
697         playback_sample += distance;
698
699         return 0;
700 }
701
702 /** @a start is set to the new frame position (TIME) read up to */
703 int
704 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
705 {
706         framecnt_t this_read   = 0;
707         framepos_t loop_end    = 0;
708         framepos_t loop_start  = 0;
709         framecnt_t loop_length = 0;
710         Location*  loc         = loop_location;
711         framepos_t effective_start = start;
712         Evoral::Range<framepos_t>*  loop_range (0);
713
714         MidiTrack*         mt     = dynamic_cast<MidiTrack*>(_track);
715         MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
716
717         frameoffset_t loop_offset = 0;
718
719         if (!reversed && loc) {
720                 get_location_times (loc, &loop_start, &loop_end, &loop_length);
721         }
722
723         while (dur) {
724
725                 /* take any loop into account. we can't read past the end of the loop. */
726
727                 if (loc && !reversed) {
728
729                         if (!loop_range) {
730                                 loop_range = new Evoral::Range<framepos_t> (loop_start, loop_end-1); // inclusive semantics require -1
731                         }
732
733                         /* if we are (seamlessly) looping, ensure that the first frame we read is at the correct
734                            position within the loop.
735                         */
736
737                         effective_start = loop_range->squish (effective_start);
738
739                         if ((loop_end - effective_start) <= dur) {
740                                 /* too close to end of loop to read "dur", so
741                                    shorten it.
742                                 */
743                                 this_read = loop_end - effective_start;
744                         } else {
745                                 this_read = dur;
746                         }
747
748                 } else {
749                         this_read = dur;
750                 }
751
752                 if (this_read == 0) {
753                         break;
754                 }
755
756                 this_read = min (dur,this_read);
757
758                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS ::read at %1 for %2 loffset %3\n", effective_start, this_read, loop_offset));
759
760                 if (midi_playlist()->read (*_playback_buf, effective_start, this_read, loop_range, 0, filter) != this_read) {
761                         error << string_compose(
762                                         _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
763                                         id(), this_read, start) << endmsg;
764                         return -1;
765                 }
766
767                 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
768
769                 if (reversed) {
770
771                         // Swap note ons with note offs here.  etc?
772                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
773                         // CC values etc.  hard.
774
775                 } else {
776
777                         /* adjust passed-by-reference argument (note: this is
778                            monotonic and does not reflect looping.
779                         */
780                         start += this_read;
781
782                         /* similarly adjust effective_start, but this may be
783                            readjusted for seamless looping as we continue around
784                            the loop.
785                         */
786                         effective_start += this_read;
787                 }
788
789                 dur -= this_read;
790                 //offset += this_read;
791         }
792
793         return 0;
794 }
795
796 int
797 MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
798 {
799         return do_refill();
800 }
801
802 int
803 MidiDiskstream::do_refill ()
804 {
805         int     ret         = 0;
806         size_t  write_space = _playback_buf->write_space();
807         bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
808
809         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("MDS refill, write space = %1 file frame = %2\n",
810                                                               write_space, file_frame));
811
812         /* no space to write */
813         if (write_space == 0) {
814                 return 0;
815         }
816
817         if (reversed) {
818                 return 0;
819         }
820
821         /* at end: nothing to do */
822         if (file_frame == max_framepos) {
823                 return 0;
824         }
825
826         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
827         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
828
829         if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
830                 return 0;
831         }
832
833         framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
834
835         to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
836         to_read = min (to_read, (framecnt_t) write_space);
837
838         if (read (file_frame, to_read, reversed)) {
839                 ret = -1;
840         }
841
842         return ret;
843 }
844
845 /** Flush pending data to disk.
846  *
847  * Important note: this function will write *AT MOST* disk_write_chunk_frames
848  * of data to disk. it will never write more than that.  If it writes that
849  * much and there is more than that waiting to be written, it will return 1,
850  * otherwise 0 on success or -1 on failure.
851  *
852  * If there is less than disk_write_chunk_frames to be written, no data will be
853  * written at all unless @a force_flush is true.
854  */
855 int
856 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
857 {
858         framecnt_t to_write;
859         int32_t ret = 0;
860
861         if (!_write_source) {
862                 return 0;
863         }
864
865         const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
866
867         if (total == 0 ||
868             _capture_buf->read_space() == 0 ||
869             (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
870                 goto out;
871         }
872
873         /* if there are 2+ chunks of disk i/o possible for
874            this track), let the caller know so that it can arrange
875            for us to be called again, ASAP.
876
877            if we are forcing a flush, then if there is* any* extra
878            work, let the caller know.
879
880            if we are no longer recording and there is any extra work,
881            let the caller know too.
882            */
883
884         if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
885                 ret = 1;
886         }
887
888         if (force_flush) {
889                 /* push out everything we have, right now */
890                 to_write = max_framecnt;
891         } else {
892                 to_write = disk_write_chunk_frames;
893         }
894
895         if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
896                 Source::Lock lm(_write_source->mutex());
897                 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
898                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
899                         return -1;
900                 }
901                 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
902         }
903
904 out:
905         return ret;
906 }
907
908 void
909 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
910 {
911         bool more_work = true;
912         int err = 0;
913         boost::shared_ptr<MidiRegion> region;
914         MidiRegion::SourceList srcs;
915         MidiRegion::SourceList::iterator src;
916         vector<CaptureInfo*>::iterator ci;
917
918         finish_capture ();
919
920         /* butler is already stopped, but there may be work to do
921            to flush remaining data to disk.
922            */
923
924         while (more_work && !err) {
925                 switch (do_flush (TransportContext, true)) {
926                 case 0:
927                         more_work = false;
928                         break;
929                 case 1:
930                         break;
931                 case -1:
932                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
933                         err++;
934                 }
935         }
936
937         /* XXX is there anything we can do if err != 0 ? */
938         Glib::Threads::Mutex::Lock lm (capture_info_lock);
939
940         if (capture_info.empty()) {
941                 goto no_capture_stuff_to_do;
942         }
943
944         if (abort_capture) {
945
946                 if (_write_source) {
947                         _write_source->mark_for_remove ();
948                         _write_source->drop_references ();
949                         _write_source.reset();
950                 }
951
952                 /* new source set up in "out" below */
953
954         } else {
955
956                 framecnt_t total_capture = 0;
957                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
958                         total_capture += (*ci)->frames;
959                 }
960
961                 if (_write_source->length (capture_info.front()->start) != 0) {
962
963                         /* phew, we have data */
964
965                         Source::Lock source_lock(_write_source->mutex());
966
967                         /* figure out the name for this take */
968
969                         srcs.push_back (_write_source);
970
971                         _write_source->set_timeline_position (capture_info.front()->start);
972                         _write_source->set_captured_for (_name);
973
974                         /* set length in beats to entire capture length */
975
976                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
977                         const Evoral::Beats total_capture_beats = converter.from (total_capture);
978                         _write_source->set_length_beats (total_capture_beats);
979
980                         /* flush to disk: this step differs from the audio path,
981                            where all the data is already on disk.
982                         */
983
984                         _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
985
986                         /* we will want to be able to keep (over)writing the source
987                            but we don't want it to be removable. this also differs
988                            from the audio situation, where the source at this point
989                            must be considered immutable. luckily, we can rely on
990                            MidiSource::mark_streaming_write_completed() to have
991                            already done the necessary work for that.
992                         */
993
994                         string whole_file_region_name;
995                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
996
997                         /* Register a new region with the Session that
998                            describes the entire source. Do this first
999                            so that any sub-regions will obviously be
1000                            children of this one (later!)
1001                         */
1002
1003                         try {
1004                                 PropertyList plist;
1005
1006                                 plist.add (Properties::name, whole_file_region_name);
1007                                 plist.add (Properties::whole_file, true);
1008                                 plist.add (Properties::automatic, true);
1009                                 plist.add (Properties::start, 0);
1010                                 plist.add (Properties::length, total_capture);
1011                                 plist.add (Properties::layer, 0);
1012
1013                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1014
1015                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1016                                 region->special_set_position (capture_info.front()->start);
1017                         }
1018
1019
1020                         catch (failed_constructor& err) {
1021                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1022                                 /* XXX what now? */
1023                         }
1024
1025                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1026
1027                         _playlist->clear_changes ();
1028                         _playlist->freeze ();
1029
1030                         /* Session frame time of the initial capture in this pass, which is where the source starts */
1031                         framepos_t initial_capture = 0;
1032                         if (!capture_info.empty()) {
1033                                 initial_capture = capture_info.front()->start;
1034                         }
1035
1036                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1037
1038                                 string region_name;
1039
1040                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1041
1042                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1043                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1044
1045
1046                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1047
1048                                 try {
1049                                         PropertyList plist;
1050
1051                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1052                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1053                                         plist.add (Properties::length, (*ci)->frames);
1054                                         plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
1055                                         plist.add (Properties::name, region_name);
1056
1057                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1058                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1059                                 }
1060
1061                                 catch (failed_constructor& err) {
1062                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1063                                         continue; /* XXX is this OK? */
1064                                 }
1065
1066                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1067
1068                                 i_am_the_modifier++;
1069                                 _playlist->add_region (region, (*ci)->start);
1070                                 i_am_the_modifier--;
1071                         }
1072
1073                         _playlist->thaw ();
1074                         _session.add_command (new StatefulDiffCommand(_playlist));
1075
1076                 } else {
1077
1078                         /* No data was recorded, so this capture will
1079                            effectively be aborted; do the same as we
1080                            do for an explicit abort.
1081                         */
1082
1083                         if (_write_source) {
1084                                 _write_source->mark_for_remove ();
1085                                 _write_source->drop_references ();
1086                                 _write_source.reset();
1087                         }
1088                 }
1089
1090         }
1091
1092         use_new_write_source (0);
1093
1094         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1095                 delete *ci;
1096         }
1097
1098         capture_info.clear ();
1099         capture_start_frame = 0;
1100
1101   no_capture_stuff_to_do:
1102
1103         reset_tracker ();
1104 }
1105
1106 void
1107 MidiDiskstream::transport_looped (framepos_t)
1108 {
1109         /* Here we only keep track of the number of captured loops so monotonic
1110            event times can be delivered to the write source in process().  Trying
1111            to be clever here is a world of trouble, it is better to simply record
1112            the input in a straightforward non-destructive way.  In the future when
1113            we want to implement more clever MIDI looping modes it should be done in
1114            the Source and/or entirely after the capture is finished.
1115         */
1116         if (was_recording) {
1117                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1118         }
1119 }
1120
1121 void
1122 MidiDiskstream::finish_capture ()
1123 {
1124         was_recording = false;
1125
1126         if (capture_captured == 0) {
1127                 return;
1128         }
1129
1130         CaptureInfo* ci = new CaptureInfo;
1131
1132         ci->start  = capture_start_frame;
1133         ci->frames = capture_captured;
1134
1135         /* XXX theoretical race condition here. Need atomic exchange ?
1136            However, the circumstances when this is called right
1137            now (either on record-disable or transport_stopped)
1138            mean that no actual race exists. I think ...
1139            We now have a capture_info_lock, but it is only to be used
1140            to synchronize in the transport_stop and the capture info
1141            accessors, so that invalidation will not occur (both non-realtime).
1142         */
1143
1144         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1145
1146         capture_info.push_back (ci);
1147         capture_captured = 0;
1148 }
1149
1150 void
1151 MidiDiskstream::set_record_enabled (bool yn)
1152 {
1153         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1154                 return;
1155         }
1156
1157         /* yes, i know that this not proof against race conditions, but its
1158            good enough. i think.
1159         */
1160
1161         if (record_enabled() != yn) {
1162                 if (yn) {
1163                         engage_record_enable ();
1164                 } else {
1165                         disengage_record_enable ();
1166                 }
1167
1168                 RecordEnableChanged (); /* EMIT SIGNAL */
1169         }
1170 }
1171
1172 void
1173 MidiDiskstream::set_record_safe (bool yn)
1174 {
1175         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1176                 return;
1177         }
1178
1179         /* yes, i know that this not proof against race conditions, but its
1180          good enough. i think.
1181          */
1182
1183         if (record_safe () != yn) {
1184                 if (yn) {
1185                         engage_record_safe ();
1186                 } else {
1187                         disengage_record_safe ();
1188                 }
1189
1190                 RecordSafeChanged (); /* EMIT SIGNAL */
1191         }
1192 }
1193
1194 bool
1195 MidiDiskstream::prep_record_enable ()
1196 {
1197         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1198                 return false;
1199         }
1200
1201         bool const rolling = _session.transport_speed() != 0.0f;
1202
1203         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1204
1205         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1206                 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1207         }
1208
1209         return true;
1210 }
1211
1212 bool
1213 MidiDiskstream::prep_record_disable ()
1214 {
1215
1216         return true;
1217 }
1218
1219 XMLNode&
1220 MidiDiskstream::get_state ()
1221 {
1222         XMLNode& node (Diskstream::get_state());
1223         char buf[64];
1224         LocaleGuard lg;
1225
1226         if (_write_source && _session.get_record_enabled()) {
1227
1228                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1229                 XMLNode* cs_grandchild;
1230
1231                 cs_grandchild = new XMLNode (X_("file"));
1232                 cs_grandchild->add_property (X_("path"), _write_source->path());
1233                 cs_child->add_child_nocopy (*cs_grandchild);
1234
1235                 /* store the location where capture will start */
1236
1237                 Location* pi;
1238
1239                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1240                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1241                 } else {
1242                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1243                 }
1244
1245                 cs_child->add_property (X_("at"), buf);
1246                 node.add_child_nocopy (*cs_child);
1247         }
1248
1249         return node;
1250 }
1251
1252 int
1253 MidiDiskstream::set_state (const XMLNode& node, int version)
1254 {
1255         XMLNodeList nlist = node.children();
1256         XMLNodeIterator niter;
1257         XMLNode* capture_pending_node = 0;
1258         LocaleGuard lg;
1259
1260         /* prevent write sources from being created */
1261
1262         in_set_state = true;
1263
1264         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1265                 if ((*niter)->name() == X_("CapturingSources")) {
1266                         capture_pending_node = *niter;
1267                 }
1268         }
1269
1270         if (Diskstream::set_state (node, version)) {
1271                 return -1;
1272         }
1273
1274         if (capture_pending_node) {
1275                 use_pending_capture_data (*capture_pending_node);
1276         }
1277
1278         in_set_state = false;
1279
1280         return 0;
1281 }
1282
1283 int
1284 MidiDiskstream::use_new_write_source (uint32_t n)
1285 {
1286         if (!_session.writable() || !recordable()) {
1287                 return 1;
1288         }
1289
1290         _accumulated_capture_offset = 0;
1291         _write_source.reset();
1292
1293         try {
1294                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1295                         _session.create_midi_source_for_session (write_source_name ()));
1296
1297                 if (!_write_source) {
1298                         throw failed_constructor();
1299                 }
1300         }
1301
1302         catch (failed_constructor &err) {
1303                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1304                 _write_source.reset();
1305                 return -1;
1306         }
1307
1308         return 0;
1309 }
1310 /**
1311  * We want to use the name of the existing write source (the one that will be
1312  * used by the next capture) for another purpose. So change the name of the
1313  * current source, and return its current name.
1314  *
1315  * Return an empty string if the change cannot be accomplished.
1316  */
1317 std::string
1318 MidiDiskstream::steal_write_source_name ()
1319 {
1320         string our_old_name = _write_source->name();
1321
1322         /* this will bump the name of the current write source to the next one
1323          * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1324          * current write source name (e.g. "MIDI 1-1" available). See the
1325          * comments in Session::create_midi_source_by_stealing_name() about why
1326          * we do this.
1327          */
1328
1329         try {
1330                 string new_path = _session.new_midi_source_path (name());
1331
1332                 if (_write_source->rename (new_path)) {
1333                         return string();
1334                 }
1335         } catch (...) {
1336                 return string ();
1337         }
1338
1339         return our_old_name;
1340 }
1341
1342 void
1343 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1344 {
1345         if (!_session.writable() || !recordable()) {
1346                 return;
1347         }
1348
1349         if (_write_source && mark_write_complete) {
1350                 Source::Lock lm(_write_source->mutex());
1351                 _write_source->mark_streaming_write_completed (lm);
1352         }
1353         use_new_write_source (0);
1354 }
1355
1356 void
1357 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1358 {
1359 }
1360
1361 void
1362 MidiDiskstream::allocate_temporary_buffers ()
1363 {
1364 }
1365
1366 void
1367 MidiDiskstream::ensure_input_monitoring (bool yn)
1368 {
1369         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1370
1371         if (sp) {
1372                 sp->ensure_input_monitoring (yn);
1373         }
1374 }
1375
1376 void
1377 MidiDiskstream::set_align_style_from_io ()
1378 {
1379         if (_alignment_choice != Automatic) {
1380                 return;
1381         }
1382
1383         /* XXX Not sure what, if anything we can do with MIDI
1384            as far as capture alignment etc.
1385         */
1386
1387         set_align_style (ExistingMaterial);
1388 }
1389
1390
1391 float
1392 MidiDiskstream::playback_buffer_load () const
1393 {
1394         /* For MIDI it's not trivial to differentiate the following two cases:
1395
1396            1.  The playback buffer is empty because the system has run out of time to fill it.
1397            2.  The playback buffer is empty because there is no more data on the playlist.
1398
1399            If we use a simple buffer load computation, we will report that the MIDI diskstream
1400            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1401            are so low compared to audio, just give a pretend answer here.
1402         */
1403
1404         return 1;
1405 }
1406
1407 float
1408 MidiDiskstream::capture_buffer_load () const
1409 {
1410         /* We don't report playback buffer load, so don't report capture load either */
1411
1412         return 1;
1413 }
1414
1415 int
1416 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1417 {
1418         return 0;
1419 }
1420
1421 void
1422 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1423 {
1424         _playback_buf->flush (start, end);
1425         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1426 }
1427
1428 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1429  *  so that an event at playback_sample has time = 0
1430  */
1431 void
1432 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1433 {
1434         dst.clear();
1435
1436         Location* loc = loop_location;
1437
1438         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1439                              "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
1440                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1441                              (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
1442
1443         //cerr << "======== PRE ========\n";
1444         //_playback_buf->dump (cerr);
1445         //cerr << "----------------\n";
1446
1447         size_t events_read = 0;
1448
1449         if (loc) {
1450                 framepos_t effective_start;
1451
1452                 Evoral::Range<framepos_t> loop_range (loc->start(), loc->end() - 1);
1453                 effective_start = loop_range.squish (playback_sample);
1454
1455                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1456
1457                 if (effective_start == loc->start()) {
1458                         /* We need to turn off notes that may extend
1459                            beyond the loop end.
1460                         */
1461
1462                         _playback_buf->resolve_tracker (dst, 0);
1463                 }
1464
1465                 /* for split-cycles we need to offset the events */
1466
1467                 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1468
1469                         /* end of loop is within the range we are reading, so
1470                            split the read in two, and lie about the location
1471                            for the 2nd read
1472                         */
1473
1474                         framecnt_t first, second;
1475
1476                         first = loc->end() - effective_start;
1477                         second = nframes - first;
1478
1479                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4, cycle offset %5\n",
1480                                                                               effective_start, loc->end(), first, second));
1481
1482                         if (first) {
1483                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1484                                                                                       effective_start, first));
1485                                 events_read = _playback_buf->read (dst, effective_start, first);
1486                         }
1487
1488                         if (second) {
1489                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1490                                                                                       loc->start(), second));
1491                                 events_read += _playback_buf->read (dst, loc->start(), second);
1492                         }
1493
1494                 } else {
1495                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1496                                                                               effective_start, nframes));
1497                         events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1498                 }
1499         } else {
1500                 const size_t n_skipped = _playback_buf->skip_to (playback_sample);
1501                 if (n_skipped > 0) {
1502                         warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
1503                 }
1504                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", playback_sample, playback_sample + nframes, nframes));
1505                 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1506         }
1507
1508         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1509                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1510                              _name, events_read, playback_sample, playback_sample + nframes,
1511                              _playback_buf->read_space(), _playback_buf->write_space(),
1512                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1513
1514         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1515
1516         //cerr << "======== POST ========\n";
1517         //_playback_buf->dump (cerr);
1518         //cerr << "----------------\n";
1519 }
1520
1521 bool
1522 MidiDiskstream::set_name (string const & name)
1523 {
1524         if (_name == name) {
1525                 return true;
1526         }
1527         Diskstream::set_name (name);
1528
1529         /* get a new write source so that its name reflects the new diskstream name */
1530         use_new_write_source (0);
1531
1532         return true;
1533 }
1534
1535 bool
1536 MidiDiskstream::set_write_source_name (const std::string& str) {
1537         if (_write_source_name == str) {
1538                 return true;
1539         }
1540         Diskstream::set_write_source_name (str);
1541         if (_write_source_name == name()) {
1542                 return true;
1543         }
1544         use_new_write_source (0);
1545         return true;
1546 }
1547
1548 boost::shared_ptr<MidiBuffer>
1549 MidiDiskstream::get_gui_feed_buffer () const
1550 {
1551         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1552
1553         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1554         b->copy (_gui_feed_buffer);
1555         return b;
1556 }
1557
1558 void
1559 MidiDiskstream::reset_tracker ()
1560 {
1561         _playback_buf->reset_tracker ();
1562
1563         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1564
1565         if (mp) {
1566                 mp->reset_note_trackers ();
1567         }
1568 }
1569
1570 void
1571 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1572 {
1573         _playback_buf->resolve_tracker(buffer, time);
1574
1575         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1576
1577         if (mp) {
1578                 mp->reset_note_trackers ();
1579         }
1580 }
1581
1582
1583 boost::shared_ptr<MidiPlaylist>
1584 MidiDiskstream::midi_playlist ()
1585 {
1586         return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);
1587 }