enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[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         get_location_times(loop_loc, &loop_start, &loop_end, &loop_length);
364
365         adjust_capture_position = 0;
366
367         if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
368                 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
369                 // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
370
371                 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
372                 /* For audio: not writing frames to the capture ringbuffer offsets
373                  * the recording. For midi: we need to keep track of the record range
374                  * and subtract the accumulated difference from the event time.
375                  */
376                 if (rec_nframes) {
377                         _accumulated_capture_offset += rec_offset;
378                 } else {
379                         _accumulated_capture_offset += nframes;
380                 }
381
382                 if (rec_nframes && !was_recording) {
383                         if (loop_loc) {
384                                 /* Loop recording, so pretend the capture started at the loop
385                                    start rgardless of what time it is now, so the source starts
386                                    at the loop start and can handle time wrapping around.
387                                    Otherwise, start the source right now as usual.
388                                 */
389                                 capture_captured    = transport_frame - loop_start;
390                                 capture_start_frame = loop_start;
391                         }
392                         _write_source->mark_write_starting_now(
393                                 capture_start_frame, capture_captured, loop_length);
394                         g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
395                         g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
396                         was_recording = true;
397                 }
398         }
399
400         if (can_record && !_last_capture_sources.empty()) {
401                 _last_capture_sources.clear ();
402         }
403
404         if (nominally_recording || rec_nframes) {
405                 // Pump entire port buffer into the ring buffer (TODO: split cycles?)
406                 MidiBuffer&        buf    = sp->get_midi_buffer(nframes);
407                 MidiTrack*         mt     = dynamic_cast<MidiTrack*>(_track);
408                 MidiChannelFilter* filter = mt ? &mt->capture_filter() : NULL;
409
410                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
411                         Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
412                         if (ev.time() + rec_offset > rec_nframes) {
413                                 break;
414                         }
415 #ifndef NDEBUG
416                         if (DEBUG_ENABLED(DEBUG::MidiIO)) {
417                                 const uint8_t* __data = ev.buffer();
418                                 DEBUG_STR_DECL(a);
419                                 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
420                                 for (size_t i=0; i < ev.size(); ++i) {
421                                         DEBUG_STR_APPEND(a,hex);
422                                         DEBUG_STR_APPEND(a,"0x");
423                                         DEBUG_STR_APPEND(a,(int)__data[i]);
424                                         DEBUG_STR_APPEND(a,' ');
425                                 }
426                                 DEBUG_STR_APPEND(a,'\n');
427                                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
428                         }
429 #endif
430                         /* Write events to the capture buffer in frames from session start,
431                            but ignoring looping so event time progresses monotonically.
432                            The source knows the loop length so it knows exactly where the
433                            event occurs in the series of recorded loops and can implement
434                            any desirable behaviour.  We don't want to send event with
435                            transport time here since that way the source can not
436                            reconstruct their actual time; future clever MIDI looping should
437                            probably be implemented in the source instead of here.
438                         */
439                         const framecnt_t loop_offset = _num_captured_loops * loop_length;
440                         const framepos_t event_time = transport_frame + loop_offset - _accumulated_capture_offset + ev.time();
441                         if (event_time < 0 || event_time < first_recordable_frame) {
442                                 /* Event out of range, skip */
443                                 continue;
444                         }
445
446                         if (!filter || !filter->filter(ev.buffer(), ev.size())) {
447                                 _capture_buf->write(event_time, ev.type(), ev.size(), ev.buffer());
448                         }
449                 }
450                 g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), nframes);
451
452                 if (buf.size() != 0) {
453                         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::Threads::TRY_LOCK);
454
455                         if (lm.locked ()) {
456                                 /* Copy this data into our GUI feed buffer and tell the GUI
457                                    that it can read it if it likes.
458                                 */
459                                 _gui_feed_buffer.clear ();
460
461                                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
462                                         /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
463                                            the end of the world if it does.
464                                         */
465                                         _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
466                                 }
467                         }
468
469                         DataRecorded (_write_source); /* EMIT SIGNAL */
470                 }
471
472         } else {
473
474                 if (was_recording) {
475                         finish_capture ();
476                 }
477                 _accumulated_capture_offset = 0;
478
479         }
480
481         if (rec_nframes) {
482
483                 /* data will be written to disk */
484
485                 if (rec_nframes == nframes && rec_offset == 0) {
486                         playback_distance = nframes;
487                 }
488
489                 adjust_capture_position = rec_nframes;
490
491         } else if (nominally_recording) {
492
493                 /* XXXX do this for MIDI !!!
494                    can't do actual capture yet - waiting for latency effects to finish before we start
495                    */
496
497                 playback_distance = nframes;
498
499         } else if (_actual_speed != 1.0f && _target_speed > 0) {
500
501                 interpolation.set_speed (_target_speed);
502
503                 playback_distance = interpolation.distance  (nframes);
504
505         } else {
506                 playback_distance = nframes;
507         }
508
509         if (need_disk_signal) {
510                 /* copy the diskstream data to all output buffers */
511
512                 MidiBuffer& mbuf (bufs.get_midi (0));
513                 get_playback (mbuf, playback_distance);
514
515                 /* leave the audio count alone */
516                 ChanCount cnt (DataType::MIDI, 1);
517                 cnt.set (DataType::AUDIO, bufs.count().n_audio());
518                 bufs.set_count (cnt);
519
520                 /* vari-speed */
521                 if (_target_speed > 0 && _actual_speed != 1.0f) {
522                         MidiBuffer& mbuf (bufs.get_midi (0));
523                         for (MidiBuffer::iterator i = mbuf.begin(); i != mbuf.end(); ++i) {
524                                 MidiBuffer::TimeType *tme = i.timeptr();
525                                 *tme = (*tme) * nframes / playback_distance;
526                         }
527                 }
528         }
529
530         return 0;
531 }
532
533 frameoffset_t
534 MidiDiskstream::calculate_playback_distance (pframes_t nframes)
535 {
536         frameoffset_t playback_distance = nframes;
537
538         if (!record_enabled() && _actual_speed != 1.0f && _actual_speed > 0.f) {
539                 interpolation.set_speed (_target_speed);
540                 playback_distance = interpolation.distance (nframes, false);
541         }
542
543         if (_actual_speed < 0.0) {
544                 return -playback_distance;
545         } else {
546                 return playback_distance;
547         }
548 }
549
550 bool
551 MidiDiskstream::commit (framecnt_t playback_distance)
552 {
553         bool need_butler = false;
554
555         if (!_io || !_io->active()) {
556                 return false;
557         }
558
559         if (_actual_speed < 0.0) {
560                 playback_sample -= playback_distance;
561         } else {
562                 playback_sample += playback_distance;
563         }
564
565         if (adjust_capture_position != 0) {
566                 capture_captured += adjust_capture_position;
567                 adjust_capture_position = 0;
568         }
569
570         uint32_t frames_read = g_atomic_int_get(const_cast<gint*>(&_frames_read_from_ringbuffer));
571         uint32_t frames_written = g_atomic_int_get(const_cast<gint*>(&_frames_written_to_ringbuffer));
572
573         /*
574           cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
575           " = " << frames_written - frames_read
576           << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
577         */
578
579         /* frames_read will generally be less than frames_written, but
580          * immediately after an overwrite, we can end up having read some data
581          * before we've written any. we don't need to trip an assert() on this,
582          * but we do need to check so that the decision on whether or not we
583          * need the butler is done correctly.
584          */
585
586         /* furthermore..
587          *
588          * Doing heavy GUI operations[1] can stall also the butler.
589          * The RT-thread meanwhile will happily continue and
590          * â€˜frames_read’ (from buffer to output) will become larger
591          * than â€˜frames_written’ (from disk to buffer).
592          *
593          * The disk-stream is now behind..
594          *
595          * In those cases the butler needs to be summed to refill the buffer (done now)
596          * AND we need to skip (frames_read - frames_written). ie remove old events
597          * before playback_sample from the rinbuffer.
598          *
599          * [1] one way to do so is described at #6170.
600          * For me just popping up the context-menu on a MIDI-track header
601          * of a track with a large (think beethoven :) midi-region also did the
602          * trick. The playhead stalls for 2 or 3 sec, until the context-menu shows.
603          *
604          * In both cases the root cause is that redrawing MIDI regions on the GUI is still very slow
605          * and can stall
606          */
607         if (frames_read <= frames_written) {
608                 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
609                         need_butler = true;
610                 }
611         } else {
612                 need_butler = true;
613         }
614
615
616         return need_butler;
617 }
618
619 void
620 MidiDiskstream::set_pending_overwrite (bool yn)
621 {
622         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
623
624         _pending_overwrite = yn;
625         overwrite_frame = playback_sample;
626 }
627
628 int
629 MidiDiskstream::overwrite_existing_buffers ()
630 {
631         /* Clear the playback buffer contents.  This is safe as long as the butler
632            thread is suspended, which it should be. */
633         _playback_buf->reset ();
634         _playback_buf->reset_tracker ();
635
636         g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
637         g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
638
639         /* Resolve all currently active notes in the playlist.  This is more
640            aggressive than it needs to be: ideally we would only resolve what is
641            absolutely necessary, but this seems difficult and/or impossible without
642            having the old data or knowing what change caused the overwrite. */
643         midi_playlist()->resolve_note_trackers (*_playback_buf, overwrite_frame);
644
645         read (overwrite_frame, disk_read_chunk_frames, false);
646         file_frame = overwrite_frame; // it was adjusted by ::read()
647         overwrite_queued = false;
648         _pending_overwrite = false;
649
650         return 0;
651 }
652
653 int
654 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
655 {
656         Glib::Threads::Mutex::Lock lm (state_lock);
657         int ret = -1;
658
659         if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
660                 /* we haven't read anything since the last seek,
661                    so flush all note trackers to prevent
662                    wierdness
663                 */
664                 reset_tracker ();
665         }
666
667         _playback_buf->reset();
668         _capture_buf->reset();
669         g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
670         g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
671
672         playback_sample = frame;
673         file_frame = frame;
674
675         if (complete_refill) {
676                 while ((ret = do_refill_with_alloc ()) > 0) ;
677         } else {
678                 ret = do_refill_with_alloc ();
679         }
680
681         return ret;
682 }
683
684 int
685 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
686 {
687         uint32_t frames_read    = g_atomic_int_get(&_frames_read_from_ringbuffer);
688         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
689         return ((frames_written - frames_read) < distance);
690 }
691
692 int
693 MidiDiskstream::internal_playback_seek (framecnt_t distance)
694 {
695         first_recordable_frame += distance;
696         playback_sample += distance;
697
698         return 0;
699 }
700
701 /** @a start is set to the new frame position (TIME) read up to */
702 int
703 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
704 {
705         framecnt_t this_read   = 0;
706         bool       reloop      = false;
707         framepos_t loop_end    = 0;
708         framepos_t loop_start  = 0;
709         framecnt_t loop_length = 0;
710         Location*  loc         = 0;
711
712         MidiTrack*         mt     = dynamic_cast<MidiTrack*>(_track);
713         MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
714
715         if (!reversed) {
716
717                 loc = loop_location;
718                 get_location_times(loc, &loop_start, &loop_end, &loop_length);
719
720                 /* if we are looping, ensure that the first frame we read is at the correct
721                    position within the loop.
722                 */
723
724                 if (loc && (start >= loop_end)) {
725                         //cerr << "start adjusted from " << start;
726                         start = loop_start + ((start - loop_start) % loop_length);
727                         //cerr << "to " << start << endl;
728                 }
729                 // cerr << "start is " << start << " end " << start+dur << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
730         }
731
732         while (dur) {
733
734                 /* take any loop into account. we can't read past the end of the loop. */
735
736                 if (loc && (loop_end - start <= dur)) {
737                         this_read = loop_end - start;
738                         // cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
739                         reloop = true;
740                 } else {
741                         reloop = false;
742                         this_read = dur;
743                 }
744
745                 if (this_read == 0) {
746                         break;
747                 }
748
749                 this_read = min(dur,this_read);
750
751                 if (midi_playlist()->read (*_playback_buf, start, this_read, 0, filter) != this_read) {
752                         error << string_compose(
753                                         _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
754                                         id(), this_read, start) << endmsg;
755                         return -1;
756                 }
757
758                 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
759
760                 if (reversed) {
761
762                         // Swap note ons with note offs here.  etc?
763                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
764                         // CC values etc.  hard.
765
766                 } else {
767
768                         /* if we read to the end of the loop, go back to the beginning */
769                         if (reloop) {
770                                 // Synthesize LoopEvent here, because the next events
771                                 // written will have non-monotonic timestamps.
772                                 start = loop_start;
773                         } else {
774                                 start += this_read;
775                         }
776                 }
777
778                 dur -= this_read;
779                 //offset += this_read;
780         }
781
782         return 0;
783 }
784
785 int
786 MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
787 {
788         return do_refill();
789 }
790
791 int
792 MidiDiskstream::do_refill ()
793 {
794         int     ret         = 0;
795         size_t  write_space = _playback_buf->write_space();
796         bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
797
798         if (write_space == 0) {
799                 return 0;
800         }
801
802         if (reversed) {
803                 return 0;
804         }
805
806         /* at end: nothing to do */
807         if (file_frame == max_framepos) {
808                 return 0;
809         }
810
811         /* no space to write */
812         if (_playback_buf->write_space() == 0) {
813                 return 0;
814         }
815
816         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
817         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
818         if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
819                 return 0;
820         }
821
822         framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
823
824         //cout << "MDS read for midi_readahead " << to_read << "  rb_contains: "
825         //      << frames_written - frames_read << endl;
826
827         to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
828         to_read = min (to_read, (framecnt_t) write_space);
829
830         if (read (file_frame, to_read, reversed)) {
831                 ret = -1;
832         }
833
834         return ret;
835 }
836
837 /** Flush pending data to disk.
838  *
839  * Important note: this function will write *AT MOST* disk_write_chunk_frames
840  * of data to disk. it will never write more than that.  If it writes that
841  * much and there is more than that waiting to be written, it will return 1,
842  * otherwise 0 on success or -1 on failure.
843  *
844  * If there is less than disk_write_chunk_frames to be written, no data will be
845  * written at all unless @a force_flush is true.
846  */
847 int
848 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
849 {
850         framecnt_t to_write;
851         int32_t ret = 0;
852
853         if (!_write_source) {
854                 return 0;
855         }
856
857         const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
858
859         if (total == 0 ||
860             _capture_buf->read_space() == 0 ||
861             (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
862                 goto out;
863         }
864
865         /* if there are 2+ chunks of disk i/o possible for
866            this track), let the caller know so that it can arrange
867            for us to be called again, ASAP.
868
869            if we are forcing a flush, then if there is* any* extra
870            work, let the caller know.
871
872            if we are no longer recording and there is any extra work,
873            let the caller know too.
874            */
875
876         if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
877                 ret = 1;
878         }
879
880         if (force_flush) {
881                 /* push out everything we have, right now */
882                 to_write = max_framecnt;
883         } else {
884                 to_write = disk_write_chunk_frames;
885         }
886
887         if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
888                 Source::Lock lm(_write_source->mutex());
889                 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
890                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
891                         return -1;
892                 }
893                 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
894         }
895
896 out:
897         return ret;
898 }
899
900 void
901 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
902 {
903         bool more_work = true;
904         int err = 0;
905         boost::shared_ptr<MidiRegion> region;
906         MidiRegion::SourceList srcs;
907         MidiRegion::SourceList::iterator src;
908         vector<CaptureInfo*>::iterator ci;
909
910         finish_capture ();
911
912         /* butler is already stopped, but there may be work to do
913            to flush remaining data to disk.
914            */
915
916         while (more_work && !err) {
917                 switch (do_flush (TransportContext, true)) {
918                 case 0:
919                         more_work = false;
920                         break;
921                 case 1:
922                         break;
923                 case -1:
924                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
925                         err++;
926                 }
927         }
928
929         /* XXX is there anything we can do if err != 0 ? */
930         Glib::Threads::Mutex::Lock lm (capture_info_lock);
931
932         if (capture_info.empty()) {
933                 goto no_capture_stuff_to_do;
934         }
935
936         if (abort_capture) {
937
938                 if (_write_source) {
939                         _write_source->mark_for_remove ();
940                         _write_source->drop_references ();
941                         _write_source.reset();
942                 }
943
944                 /* new source set up in "out" below */
945
946         } else {
947
948                 framecnt_t total_capture = 0;
949                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
950                         total_capture += (*ci)->frames;
951                 }
952
953                 if (_write_source->length (capture_info.front()->start) != 0) {
954
955                         /* phew, we have data */
956
957                         Source::Lock source_lock(_write_source->mutex());
958
959                         /* figure out the name for this take */
960
961                         srcs.push_back (_write_source);
962
963                         _write_source->set_timeline_position (capture_info.front()->start);
964                         _write_source->set_captured_for (_name);
965
966                         /* set length in beats to entire capture length */
967
968                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
969                         const Evoral::Beats total_capture_beats = converter.from (total_capture);
970                         _write_source->set_length_beats (total_capture_beats);
971
972                         /* flush to disk: this step differs from the audio path,
973                            where all the data is already on disk.
974                         */
975
976                         _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
977
978                         /* we will want to be able to keep (over)writing the source
979                            but we don't want it to be removable. this also differs
980                            from the audio situation, where the source at this point
981                            must be considered immutable. luckily, we can rely on
982                            MidiSource::mark_streaming_write_completed() to have
983                            already done the necessary work for that.
984                         */
985
986                         string whole_file_region_name;
987                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
988
989                         /* Register a new region with the Session that
990                            describes the entire source. Do this first
991                            so that any sub-regions will obviously be
992                            children of this one (later!)
993                         */
994
995                         try {
996                                 PropertyList plist;
997
998                                 plist.add (Properties::name, whole_file_region_name);
999                                 plist.add (Properties::whole_file, true);
1000                                 plist.add (Properties::automatic, true);
1001                                 plist.add (Properties::start, 0);
1002                                 plist.add (Properties::length, total_capture);
1003                                 plist.add (Properties::layer, 0);
1004
1005                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1006
1007                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1008                                 region->special_set_position (capture_info.front()->start);
1009                         }
1010
1011
1012                         catch (failed_constructor& err) {
1013                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1014                                 /* XXX what now? */
1015                         }
1016
1017                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1018
1019                         _playlist->clear_changes ();
1020                         _playlist->freeze ();
1021
1022                         /* Session frame time of the initial capture in this pass, which is where the source starts */
1023                         framepos_t initial_capture = 0;
1024                         if (!capture_info.empty()) {
1025                                 initial_capture = capture_info.front()->start;
1026                         }
1027
1028                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1029
1030                                 string region_name;
1031
1032                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1033
1034                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1035                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1036
1037
1038                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1039
1040                                 try {
1041                                         PropertyList plist;
1042
1043                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1044                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1045                                         plist.add (Properties::length, (*ci)->frames);
1046                                         plist.add (Properties::length_beats, converter.from((*ci)->frames));
1047                                         plist.add (Properties::name, region_name);
1048
1049                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1050                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1051                                 }
1052
1053                                 catch (failed_constructor& err) {
1054                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1055                                         continue; /* XXX is this OK? */
1056                                 }
1057
1058                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1059
1060                                 i_am_the_modifier++;
1061                                 _playlist->add_region (region, (*ci)->start);
1062                                 i_am_the_modifier--;
1063                         }
1064
1065                         _playlist->thaw ();
1066                         _session.add_command (new StatefulDiffCommand(_playlist));
1067
1068                 } else {
1069
1070                         /* No data was recorded, so this capture will
1071                            effectively be aborted; do the same as we
1072                            do for an explicit abort.
1073                         */
1074
1075                         if (_write_source) {
1076                                 _write_source->mark_for_remove ();
1077                                 _write_source->drop_references ();
1078                                 _write_source.reset();
1079                         }
1080                 }
1081
1082         }
1083
1084         use_new_write_source (0);
1085
1086         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1087                 delete *ci;
1088         }
1089
1090         capture_info.clear ();
1091         capture_start_frame = 0;
1092
1093   no_capture_stuff_to_do:
1094
1095         reset_tracker ();
1096 }
1097
1098 void
1099 MidiDiskstream::transport_looped (framepos_t)
1100 {
1101         /* Here we only keep track of the number of captured loops so monotonic
1102            event times can be delivered to the write source in process().  Trying
1103            to be clever here is a world of trouble, it is better to simply record
1104            the input in a straightforward non-destructive way.  In the future when
1105            we want to implement more clever MIDI looping modes it should be done in
1106            the Source and/or entirely after the capture is finished.
1107         */
1108         if (was_recording) {
1109                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1110         }
1111 }
1112
1113 void
1114 MidiDiskstream::finish_capture ()
1115 {
1116         was_recording = false;
1117
1118         if (capture_captured == 0) {
1119                 return;
1120         }
1121
1122         CaptureInfo* ci = new CaptureInfo;
1123
1124         ci->start  = capture_start_frame;
1125         ci->frames = capture_captured;
1126
1127         /* XXX theoretical race condition here. Need atomic exchange ?
1128            However, the circumstances when this is called right
1129            now (either on record-disable or transport_stopped)
1130            mean that no actual race exists. I think ...
1131            We now have a capture_info_lock, but it is only to be used
1132            to synchronize in the transport_stop and the capture info
1133            accessors, so that invalidation will not occur (both non-realtime).
1134         */
1135
1136         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1137
1138         capture_info.push_back (ci);
1139         capture_captured = 0;
1140 }
1141
1142 void
1143 MidiDiskstream::set_record_enabled (bool yn)
1144 {
1145         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1146                 return;
1147         }
1148
1149         /* yes, i know that this not proof against race conditions, but its
1150            good enough. i think.
1151         */
1152
1153         if (record_enabled() != yn) {
1154                 if (yn) {
1155                         engage_record_enable ();
1156                 } else {
1157                         disengage_record_enable ();
1158                 }
1159
1160                 RecordEnableChanged (); /* EMIT SIGNAL */
1161         }
1162 }
1163
1164 void
1165 MidiDiskstream::set_record_safe (bool yn)
1166 {
1167         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1168                 return;
1169         }
1170
1171         /* yes, i know that this not proof against race conditions, but its
1172          good enough. i think.
1173          */
1174
1175         if (record_safe () != yn) {
1176                 if (yn) {
1177                         engage_record_safe ();
1178                 } else {
1179                         disengage_record_safe ();
1180                 }
1181
1182                 RecordSafeChanged (); /* EMIT SIGNAL */
1183         }
1184 }
1185
1186 bool
1187 MidiDiskstream::prep_record_enable ()
1188 {
1189         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1190                 return false;
1191         }
1192
1193         bool const rolling = _session.transport_speed() != 0.0f;
1194
1195         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1196
1197         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1198                 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1199         }
1200
1201         return true;
1202 }
1203
1204 bool
1205 MidiDiskstream::prep_record_disable ()
1206 {
1207
1208         return true;
1209 }
1210
1211 XMLNode&
1212 MidiDiskstream::get_state ()
1213 {
1214         XMLNode& node (Diskstream::get_state());
1215         char buf[64];
1216         LocaleGuard lg;
1217
1218         if (_write_source && _session.get_record_enabled()) {
1219
1220                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1221                 XMLNode* cs_grandchild;
1222
1223                 cs_grandchild = new XMLNode (X_("file"));
1224                 cs_grandchild->add_property (X_("path"), _write_source->path());
1225                 cs_child->add_child_nocopy (*cs_grandchild);
1226
1227                 /* store the location where capture will start */
1228
1229                 Location* pi;
1230
1231                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1232                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1233                 } else {
1234                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1235                 }
1236
1237                 cs_child->add_property (X_("at"), buf);
1238                 node.add_child_nocopy (*cs_child);
1239         }
1240
1241         return node;
1242 }
1243
1244 int
1245 MidiDiskstream::set_state (const XMLNode& node, int version)
1246 {
1247         XMLNodeList nlist = node.children();
1248         XMLNodeIterator niter;
1249         XMLNode* capture_pending_node = 0;
1250         LocaleGuard lg;
1251
1252         /* prevent write sources from being created */
1253
1254         in_set_state = true;
1255
1256         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1257                 if ((*niter)->name() == X_("CapturingSources")) {
1258                         capture_pending_node = *niter;
1259                 }
1260         }
1261
1262         if (Diskstream::set_state (node, version)) {
1263                 return -1;
1264         }
1265
1266         if (capture_pending_node) {
1267                 use_pending_capture_data (*capture_pending_node);
1268         }
1269
1270         in_set_state = false;
1271
1272         return 0;
1273 }
1274
1275 int
1276 MidiDiskstream::use_new_write_source (uint32_t n)
1277 {
1278         if (!_session.writable() || !recordable()) {
1279                 return 1;
1280         }
1281
1282         _accumulated_capture_offset = 0;
1283         _write_source.reset();
1284
1285         try {
1286                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1287                         _session.create_midi_source_for_session (write_source_name ()));
1288
1289                 if (!_write_source) {
1290                         throw failed_constructor();
1291                 }
1292         }
1293
1294         catch (failed_constructor &err) {
1295                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1296                 _write_source.reset();
1297                 return -1;
1298         }
1299
1300         return 0;
1301 }
1302 /**
1303  * We want to use the name of the existing write source (the one that will be
1304  * used by the next capture) for another purpose. So change the name of the
1305  * current source, and return its current name.
1306  *
1307  * Return an empty string if the change cannot be accomplished.
1308  */
1309 std::string
1310 MidiDiskstream::steal_write_source_name ()
1311 {
1312         string our_old_name = _write_source->name();
1313
1314         /* this will bump the name of the current write source to the next one
1315          * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1316          * current write source name (e.g. "MIDI 1-1" available). See the
1317          * comments in Session::create_midi_source_by_stealing_name() about why
1318          * we do this.
1319          */
1320
1321         try {
1322                 string new_path = _session.new_midi_source_path (name());
1323
1324                 if (_write_source->rename (new_path)) {
1325                         return string();
1326                 }
1327         } catch (...) {
1328                 return string ();
1329         }
1330
1331         return our_old_name;
1332 }
1333
1334 void
1335 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1336 {
1337         if (!_session.writable() || !recordable()) {
1338                 return;
1339         }
1340
1341         if (_write_source && mark_write_complete) {
1342                 Source::Lock lm(_write_source->mutex());
1343                 _write_source->mark_streaming_write_completed (lm);
1344         }
1345         use_new_write_source (0);
1346 }
1347
1348 void
1349 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1350 {
1351 }
1352
1353 void
1354 MidiDiskstream::allocate_temporary_buffers ()
1355 {
1356 }
1357
1358 void
1359 MidiDiskstream::ensure_input_monitoring (bool yn)
1360 {
1361         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1362
1363         if (sp) {
1364                 sp->ensure_input_monitoring (yn);
1365         }
1366 }
1367
1368 void
1369 MidiDiskstream::set_align_style_from_io ()
1370 {
1371         if (_alignment_choice != Automatic) {
1372                 return;
1373         }
1374
1375         /* XXX Not sure what, if anything we can do with MIDI
1376            as far as capture alignment etc.
1377         */
1378
1379         set_align_style (ExistingMaterial);
1380 }
1381
1382
1383 float
1384 MidiDiskstream::playback_buffer_load () const
1385 {
1386         /* For MIDI it's not trivial to differentiate the following two cases:
1387
1388            1.  The playback buffer is empty because the system has run out of time to fill it.
1389            2.  The playback buffer is empty because there is no more data on the playlist.
1390
1391            If we use a simple buffer load computation, we will report that the MIDI diskstream
1392            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1393            are so low compared to audio, just give a pretend answer here.
1394         */
1395
1396         return 1;
1397 }
1398
1399 float
1400 MidiDiskstream::capture_buffer_load () const
1401 {
1402         /* We don't report playback buffer load, so don't report capture load either */
1403
1404         return 1;
1405 }
1406
1407 int
1408 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1409 {
1410         return 0;
1411 }
1412
1413 void
1414 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1415 {
1416         _playback_buf->flush (start, end);
1417         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1418 }
1419
1420 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1421  *  so that an event at playback_sample has time = 0
1422  */
1423 void
1424 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1425 {
1426         dst.clear();
1427
1428         Location* loc = loop_location;
1429
1430         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1431                              "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1432                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1433                              (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1434
1435         // cerr << "================\n";
1436         // _playback_buf->dump (cerr);
1437         // cerr << "----------------\n";
1438
1439         size_t events_read = 0;
1440         const size_t split_cycle_offset = Port::port_offset ();
1441
1442         if (loc) {
1443                 framepos_t effective_start;
1444
1445                 if (playback_sample >= loc->end()) {
1446                         effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1447                 } else {
1448                         effective_start = playback_sample;
1449                 }
1450
1451                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1452
1453                 if (effective_start == loc->start()) {
1454                         /* We need to turn off notes that may extend
1455                            beyond the loop end.
1456                         */
1457
1458                         _playback_buf->resolve_tracker (dst, split_cycle_offset);
1459                 }
1460
1461                 _playback_buf->skip_to (effective_start);
1462
1463                 /* for split-cycles we need to offset the events */
1464
1465                 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1466                         /* end of loop is within the range we are reading, so
1467                            split the read in two, and lie about the location
1468                            for the 2nd read
1469                         */
1470                         framecnt_t first, second;
1471
1472                         first = loc->end() - effective_start;
1473                         second = nframes - first;
1474
1475                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1476                                                                               effective_start, loc->end(), first, second));
1477
1478                         if (first) {
1479                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1480                                                                                       effective_start, first));
1481                                 events_read = _playback_buf->read (dst, effective_start, first, split_cycle_offset);
1482                         }
1483
1484                         if (second) {
1485                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1486                                                                                       loc->start(), second));
1487                                 events_read += _playback_buf->read (dst, loc->start(), second, split_cycle_offset);
1488                         }
1489
1490                 } else {
1491                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1492                                                                               effective_start, nframes));
1493                         events_read = _playback_buf->read (dst, effective_start, effective_start + nframes, split_cycle_offset);
1494                 }
1495         } else {
1496                 _playback_buf->skip_to (playback_sample);
1497                 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes, split_cycle_offset);
1498         }
1499
1500         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1501                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1502                              _name, events_read, playback_sample, playback_sample + nframes,
1503                              _playback_buf->read_space(), _playback_buf->write_space(),
1504                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1505
1506         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1507 }
1508
1509 bool
1510 MidiDiskstream::set_name (string const & name)
1511 {
1512         if (_name == name) {
1513                 return true;
1514         }
1515         Diskstream::set_name (name);
1516
1517         /* get a new write source so that its name reflects the new diskstream name */
1518         use_new_write_source (0);
1519
1520         return true;
1521 }
1522
1523 bool
1524 MidiDiskstream::set_write_source_name (const std::string& str) {
1525         if (_write_source_name == str) {
1526                 return true;
1527         }
1528         Diskstream::set_write_source_name (str);
1529         if (_write_source_name == name()) {
1530                 return true;
1531         }
1532         use_new_write_source (0);
1533         return true;
1534 }
1535
1536 boost::shared_ptr<MidiBuffer>
1537 MidiDiskstream::get_gui_feed_buffer () const
1538 {
1539         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1540
1541         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1542         b->copy (_gui_feed_buffer);
1543         return b;
1544 }
1545
1546 void
1547 MidiDiskstream::reset_tracker ()
1548 {
1549         _playback_buf->reset_tracker ();
1550
1551         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1552
1553         if (mp) {
1554                 mp->reset_note_trackers ();
1555         }
1556 }
1557
1558 void
1559 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1560 {
1561         _playback_buf->resolve_tracker(buffer, time);
1562
1563         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1564
1565         if (mp) {
1566                 mp->reset_note_trackers ();
1567         }
1568 }
1569
1570
1571 boost::shared_ptr<MidiPlaylist>
1572 MidiDiskstream::midi_playlist ()
1573 {
1574         return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);
1575 }