7d980e5d1e6c448e1ebc0789c5e18a1a8625913d
[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 <fstream>
20 #include <cstdio>
21 #include <unistd.h>
22 #include <cmath>
23 #include <cerrno>
24 #include <string>
25 #include <climits>
26 #include <fcntl.h>
27 #include <cstdlib>
28 #include <ctime>
29 #include <sys/stat.h>
30
31 #include "pbd/error.h"
32 #include "pbd/ffs.h"
33 #include "pbd/basename.h"
34 #include <glibmm/threads.h>
35 #include "pbd/xml++.h"
36 #include "pbd/memento_command.h"
37 #include "pbd/enumwriter.h"
38 #include "pbd/stateful_diff_command.h"
39 #include "pbd/stacktrace.h"
40
41 #include "ardour/audioengine.h"
42 #include "ardour/butler.h"
43 #include "ardour/debug.h"
44 #include "ardour/io.h"
45 #include "ardour/midi_diskstream.h"
46 #include "ardour/midi_model.h"
47 #include "ardour/midi_playlist.h"
48 #include "ardour/midi_port.h"
49 #include "ardour/midi_region.h"
50 #include "ardour/midi_ring_buffer.h"
51 #include "ardour/midi_track.h"
52 #include "ardour/playlist_factory.h"
53 #include "ardour/region_factory.h"
54 #include "ardour/session.h"
55 #include "ardour/session_playlists.h"
56 #include "ardour/smf_source.h"
57 #include "ardour/types.h"
58 #include "ardour/utils.h"
59
60 #include "midi++/types.h"
61
62 #include "i18n.h"
63 #include <locale.h>
64
65 using namespace std;
66 using namespace ARDOUR;
67 using namespace PBD;
68
69 framecnt_t MidiDiskstream::midi_readahead = 4096;
70
71 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
72         : Diskstream(sess, name, flag)
73         , _playback_buf(0)
74         , _capture_buf(0)
75         , _note_mode(Sustained)
76         , _frames_written_to_ringbuffer(0)
77         , _frames_read_from_ringbuffer(0)
78         , _frames_pending_write(0)
79         , _num_captured_loops(0)
80         , _accumulated_capture_offset(0)
81         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
82 {
83         in_set_state = true;
84
85         init ();
86         use_new_playlist ();
87         use_new_write_source (0);
88
89         in_set_state = false;
90
91         if (destructive()) {
92                 throw failed_constructor();
93         }
94 }
95
96 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
97         : Diskstream(sess, node)
98         , _playback_buf(0)
99         , _capture_buf(0)
100         , _note_mode(Sustained)
101         , _frames_written_to_ringbuffer(0)
102         , _frames_read_from_ringbuffer(0)
103         , _frames_pending_write(0)
104         , _num_captured_loops(0)
105         , _accumulated_capture_offset(0)
106         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
107 {
108         in_set_state = true;
109
110         init ();
111
112         if (set_state (node, Stateful::loading_state_version)) {
113                 in_set_state = false;
114                 throw failed_constructor();
115         }
116
117         use_new_write_source (0);
118
119         in_set_state = false;
120 }
121
122 void
123 MidiDiskstream::init ()
124 {
125         /* there are no channels at this point, so these
126            two calls just get speed_buffer_size and wrap_buffer
127            size setup without duplicating their code.
128         */
129
130         set_block_size (_session.get_block_size());
131         allocate_temporary_buffers ();
132
133         const size_t size = _session.butler()->midi_diskstream_buffer_size();
134         _playback_buf = new MidiRingBuffer<framepos_t>(size);
135         _capture_buf = new MidiRingBuffer<framepos_t>(size);
136
137         _n_channels = ChanCount(DataType::MIDI, 1);
138         interpolation.add_channel_to (0,0);
139 }
140
141 MidiDiskstream::~MidiDiskstream ()
142 {
143         Glib::Threads::Mutex::Lock lm (state_lock);
144         delete _playback_buf;
145         delete _capture_buf;
146 }
147
148
149 void
150 MidiDiskstream::non_realtime_locate (framepos_t position)
151 {
152         if (_write_source) {
153                 _write_source->set_timeline_position (position);
154         }
155         seek (position, false);
156 }
157
158
159 void
160 MidiDiskstream::non_realtime_input_change ()
161 {
162         {
163                 Glib::Threads::Mutex::Lock lm (state_lock);
164
165                 if (input_change_pending.type == IOChange::NoChange) {
166                         return;
167                 }
168
169                 if (input_change_pending.type & IOChange::ConfigurationChanged) {
170                         uint32_t ni = _io->n_ports().n_midi();
171
172                         if (ni != _n_channels.n_midi()) {
173                                 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
174                                                          name(),
175                                                          _io->n_ports(),
176                                                          _n_channels, input_change_pending.type)
177                                       << endmsg;
178                         }
179
180                         if (ni == 0) {
181                                 _source_port.reset ();
182                         } else {
183                                 _source_port = _io->midi(0);
184                         }
185                 }
186
187                 if (input_change_pending.type & IOChange::ConnectionsChanged) {
188                         set_capture_offset ();
189                         set_align_style_from_io ();
190                 }
191
192                 input_change_pending.type = IOChange::NoChange;
193
194                 /* implicit unlock */
195         }
196
197         /* unlike with audio, there is never any need to reset write sources
198            based on input configuration changes because ... a MIDI track
199            has just 1 MIDI port as input, always.
200         */
201
202         /* now refill channel buffers */
203
204         if (speed() != 1.0f || speed() != -1.0f) {
205                 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
206         }
207         else {
208                 seek (_session.transport_frame());
209         }
210
211         g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
212         g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
213 }
214
215 int
216 MidiDiskstream::find_and_use_playlist (const string& name)
217 {
218         boost::shared_ptr<MidiPlaylist> playlist;
219
220         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
221                 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
222         }
223
224         if (!playlist) {
225                 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
226                 return -1;
227         }
228
229         return use_playlist (playlist);
230 }
231
232 int
233 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
234 {
235         if (boost::dynamic_pointer_cast<MidiPlaylist>(playlist)) {
236                 Diskstream::use_playlist(playlist);
237         }
238
239         return 0;
240 }
241
242 int
243 MidiDiskstream::use_new_playlist ()
244 {
245         string newname;
246         boost::shared_ptr<MidiPlaylist> playlist;
247
248         if (!in_set_state && destructive()) {
249                 return 0;
250         }
251
252         if (_playlist) {
253                 newname = Playlist::bump_name (_playlist->name(), _session);
254         } else {
255                 newname = Playlist::bump_name (_name, _session);
256         }
257
258         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
259                         DataType::MIDI, _session, newname, hidden()))) != 0) {
260
261                 return use_playlist (playlist);
262
263         } else {
264                 return -1;
265         }
266 }
267
268 int
269 MidiDiskstream::use_copy_playlist ()
270 {
271         if (destructive()) {
272                 return 0;
273         }
274
275         if (_playlist == 0) {
276                 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
277                 return -1;
278         }
279
280         string newname;
281         boost::shared_ptr<MidiPlaylist> playlist;
282
283         newname = Playlist::bump_name (_playlist->name(), _session);
284
285         if ((playlist  = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
286                 return use_playlist (playlist);
287         } else {
288                 return -1;
289         }
290 }
291
292 /** Overloaded from parent to die horribly
293  */
294 int
295 MidiDiskstream::set_destructive (bool yn)
296 {
297         return yn ? -1 : 0;
298 }
299
300 void
301 MidiDiskstream::set_note_mode (NoteMode m)
302 {
303         _note_mode = m;
304         midi_playlist()->set_note_mode(m);
305         if (_write_source && _write_source->model())
306                 _write_source->model()->set_note_mode(m);
307 }
308
309 /** Get the start, end, and length of a location "atomically".
310  *
311  * Note: Locations don't get deleted, so all we care about when I say "atomic"
312  * is that we are always pointing to the same one and using start/length values
313  * obtained just once.  Use this function to achieve this since location being
314  * a parameter achieves this.
315  */
316 static void
317 get_location_times(const Location* location,
318                    framepos_t*     start,
319                    framepos_t*     end,
320                    framepos_t*     length)
321 {
322         if (location) {
323                 *start  = location->start();
324                 *end    = location->end();
325                 *length = *end - *start;
326         }
327 }
328
329 int
330 MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance, bool need_disk_signal)
331 {
332         framecnt_t rec_offset = 0;
333         framecnt_t rec_nframes = 0;
334         bool      nominally_recording;
335         bool      re = record_enabled ();
336         bool      can_record = _session.actively_recording ();
337
338         playback_distance = 0;
339
340         check_record_status (transport_frame, can_record);
341
342         nominally_recording = (can_record && re);
343
344         if (nframes == 0) {
345                 return 0;
346         }
347
348         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
349
350         if (sp == 0) {
351                 return 1;
352         }
353
354         Glib::Threads::Mutex::Lock sm (state_lock, Glib::Threads::TRY_LOCK);
355
356         if (!sm.locked()) {
357                 return 1;
358         }
359
360         const Location* const loop_loc    = loop_location;
361         framepos_t            loop_start  = 0;
362         framepos_t            loop_end    = 0;
363         framepos_t            loop_length = 0;
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) {
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         bool       reloop      = false;
708         framepos_t loop_end    = 0;
709         framepos_t loop_start  = 0;
710         framecnt_t loop_length = 0;
711         Location*  loc         = 0;
712
713         MidiTrack*         mt     = dynamic_cast<MidiTrack*>(_track);
714         MidiChannelFilter* filter = mt ? &mt->playback_filter() : NULL;
715
716         if (!reversed) {
717
718                 loc = loop_location;
719                 get_location_times(loc, &loop_start, &loop_end, &loop_length);
720
721                 /* if we are looping, ensure that the first frame we read is at the correct
722                    position within the loop.
723                 */
724
725                 if (loc && (start >= loop_end)) {
726                         //cerr << "start adjusted from " << start;
727                         start = loop_start + ((start - loop_start) % loop_length);
728                         //cerr << "to " << start << endl;
729                 }
730                 // cerr << "start is " << start << " end " << start+dur << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
731         }
732
733         while (dur) {
734
735                 /* take any loop into account. we can't read past the end of the loop. */
736
737                 if (loc && (loop_end - start <= dur)) {
738                         this_read = loop_end - start;
739                         // cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
740                         reloop = true;
741                 } else {
742                         reloop = false;
743                         this_read = dur;
744                 }
745
746                 if (this_read == 0) {
747                         break;
748                 }
749
750                 this_read = min(dur,this_read);
751
752                 if (midi_playlist()->read (*_playback_buf, start, this_read, 0, filter) != this_read) {
753                         error << string_compose(
754                                         _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
755                                         id(), this_read, start) << endmsg;
756                         return -1;
757                 }
758
759                 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
760
761                 if (reversed) {
762
763                         // Swap note ons with note offs here.  etc?
764                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
765                         // CC values etc.  hard.
766
767                 } else {
768
769                         /* if we read to the end of the loop, go back to the beginning */
770                         if (reloop) {
771                                 // Synthesize LoopEvent here, because the next events
772                                 // written will have non-monotonic timestamps.
773                                 start = loop_start;
774                         } else {
775                                 start += this_read;
776                         }
777                 }
778
779                 dur -= this_read;
780                 //offset += this_read;
781         }
782
783         return 0;
784 }
785
786 int
787 MidiDiskstream::_do_refill_with_alloc (bool /* partial_fill */)
788 {
789         return do_refill();
790 }
791
792 int
793 MidiDiskstream::do_refill ()
794 {
795         int     ret         = 0;
796         size_t  write_space = _playback_buf->write_space();
797         bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
798
799         if (write_space == 0) {
800                 return 0;
801         }
802
803         if (reversed) {
804                 return 0;
805         }
806
807         /* at end: nothing to do */
808         if (file_frame == max_framepos) {
809                 return 0;
810         }
811
812         /* no space to write */
813         if (_playback_buf->write_space() == 0) {
814                 return 0;
815         }
816
817         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
818         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
819         if ((frames_read < frames_written) && (frames_written - frames_read) >= midi_readahead) {
820                 return 0;
821         }
822
823         framecnt_t to_read = midi_readahead - ((framecnt_t)frames_written - (framecnt_t)frames_read);
824
825         //cout << "MDS read for midi_readahead " << to_read << "  rb_contains: "
826         //      << frames_written - frames_read << endl;
827
828         to_read = min (to_read, (framecnt_t) (max_framepos - file_frame));
829         to_read = min (to_read, (framecnt_t) write_space);
830
831         if (read (file_frame, to_read, reversed)) {
832                 ret = -1;
833         }
834
835         return ret;
836 }
837
838 /** Flush pending data to disk.
839  *
840  * Important note: this function will write *AT MOST* disk_write_chunk_frames
841  * of data to disk. it will never write more than that.  If it writes that
842  * much and there is more than that waiting to be written, it will return 1,
843  * otherwise 0 on success or -1 on failure.
844  *
845  * If there is less than disk_write_chunk_frames to be written, no data will be
846  * written at all unless @a force_flush is true.
847  */
848 int
849 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
850 {
851         framecnt_t to_write;
852         int32_t ret = 0;
853
854         if (!_write_source) {
855                 return 0;
856         }
857
858         const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
859
860         if (total == 0 ||
861             _capture_buf->read_space() == 0 ||
862             (!force_flush && (total < disk_write_chunk_frames) && was_recording)) {
863                 goto out;
864         }
865
866         /* if there are 2+ chunks of disk i/o possible for
867            this track), let the caller know so that it can arrange
868            for us to be called again, ASAP.
869
870            if we are forcing a flush, then if there is* any* extra
871            work, let the caller know.
872
873            if we are no longer recording and there is any extra work,
874            let the caller know too.
875            */
876
877         if (total >= 2 * disk_write_chunk_frames || ((force_flush || !was_recording) && total > disk_write_chunk_frames)) {
878                 ret = 1;
879         }
880
881         if (force_flush) {
882                 /* push out everything we have, right now */
883                 to_write = max_framecnt;
884         } else {
885                 to_write = disk_write_chunk_frames;
886         }
887
888         if (record_enabled() && ((total > disk_write_chunk_frames) || force_flush)) {
889                 Source::Lock lm(_write_source->mutex());
890                 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
891                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
892                         return -1;
893                 }
894                 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
895         }
896
897 out:
898         return ret;
899 }
900
901 void
902 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
903 {
904         bool more_work = true;
905         int err = 0;
906         boost::shared_ptr<MidiRegion> region;
907         MidiRegion::SourceList srcs;
908         MidiRegion::SourceList::iterator src;
909         vector<CaptureInfo*>::iterator ci;
910
911         finish_capture ();
912
913         /* butler is already stopped, but there may be work to do
914            to flush remaining data to disk.
915            */
916
917         while (more_work && !err) {
918                 switch (do_flush (TransportContext, true)) {
919                 case 0:
920                         more_work = false;
921                         break;
922                 case 1:
923                         break;
924                 case -1:
925                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
926                         err++;
927                 }
928         }
929
930         /* XXX is there anything we can do if err != 0 ? */
931         Glib::Threads::Mutex::Lock lm (capture_info_lock);
932
933         if (capture_info.empty()) {
934                 goto no_capture_stuff_to_do;
935         }
936
937         if (abort_capture) {
938
939                 if (_write_source) {
940                         _write_source->mark_for_remove ();
941                         _write_source->drop_references ();
942                         _write_source.reset();
943                 }
944
945                 /* new source set up in "out" below */
946
947         } else {
948
949                 framecnt_t total_capture = 0;
950                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
951                         total_capture += (*ci)->frames;
952                 }
953
954                 if (_write_source->length (capture_info.front()->start) != 0) {
955
956                         /* phew, we have data */
957
958                         Source::Lock source_lock(_write_source->mutex());
959
960                         /* figure out the name for this take */
961
962                         srcs.push_back (_write_source);
963
964                         _write_source->set_timeline_position (capture_info.front()->start);
965                         _write_source->set_captured_for (_name);
966
967                         /* set length in beats to entire capture length */
968
969                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
970                         const Evoral::Beats total_capture_beats = converter.from (total_capture);
971                         _write_source->set_length_beats (total_capture_beats);
972
973                         /* flush to disk: this step differs from the audio path,
974                            where all the data is already on disk.
975                         */
976
977                         _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::Beats>::ResolveStuckNotes, total_capture_beats);
978
979                         /* we will want to be able to keep (over)writing the source
980                            but we don't want it to be removable. this also differs
981                            from the audio situation, where the source at this point
982                            must be considered immutable. luckily, we can rely on
983                            MidiSource::mark_streaming_write_completed() to have
984                            already done the necessary work for that.
985                         */
986
987                         string whole_file_region_name;
988                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
989
990                         /* Register a new region with the Session that
991                            describes the entire source. Do this first
992                            so that any sub-regions will obviously be
993                            children of this one (later!)
994                         */
995
996                         try {
997                                 PropertyList plist;
998
999                                 plist.add (Properties::name, whole_file_region_name);
1000                                 plist.add (Properties::whole_file, true);
1001                                 plist.add (Properties::automatic, true);
1002                                 plist.add (Properties::start, 0);
1003                                 plist.add (Properties::length, total_capture);
1004                                 plist.add (Properties::layer, 0);
1005
1006                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1007
1008                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1009                                 region->special_set_position (capture_info.front()->start);
1010                         }
1011
1012
1013                         catch (failed_constructor& err) {
1014                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1015                                 /* XXX what now? */
1016                         }
1017
1018                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1019
1020                         _playlist->clear_changes ();
1021                         _playlist->freeze ();
1022
1023                         /* Session frame time of the initial capture in this pass, which is where the source starts */
1024                         framepos_t initial_capture = 0;
1025                         if (!capture_info.empty()) {
1026                                 initial_capture = capture_info.front()->start;
1027                         }
1028
1029                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1030
1031                                 string region_name;
1032
1033                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1034
1035                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1036                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1037
1038
1039                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1040
1041                                 try {
1042                                         PropertyList plist;
1043
1044                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1045                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1046                                         plist.add (Properties::length, (*ci)->frames);
1047                                         plist.add (Properties::length_beats, converter.from((*ci)->frames));
1048                                         plist.add (Properties::name, region_name);
1049
1050                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1051                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1052                                 }
1053
1054                                 catch (failed_constructor& err) {
1055                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1056                                         continue; /* XXX is this OK? */
1057                                 }
1058
1059                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1060
1061                                 i_am_the_modifier++;
1062                                 _playlist->add_region (region, (*ci)->start);
1063                                 i_am_the_modifier--;
1064                         }
1065
1066                         _playlist->thaw ();
1067                         _session.add_command (new StatefulDiffCommand(_playlist));
1068
1069                 } else {
1070
1071                         /* No data was recorded, so this capture will
1072                            effectively be aborted; do the same as we
1073                            do for an explicit abort.
1074                         */
1075
1076                         if (_write_source) {
1077                                 _write_source->mark_for_remove ();
1078                                 _write_source->drop_references ();
1079                                 _write_source.reset();
1080                         }
1081                 }
1082
1083         }
1084
1085         use_new_write_source (0);
1086
1087         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1088                 delete *ci;
1089         }
1090
1091         capture_info.clear ();
1092         capture_start_frame = 0;
1093
1094   no_capture_stuff_to_do:
1095
1096         reset_tracker ();
1097 }
1098
1099 void
1100 MidiDiskstream::transport_looped (framepos_t)
1101 {
1102         /* Here we only keep track of the number of captured loops so monotonic
1103            event times can be delivered to the write source in process().  Trying
1104            to be clever here is a world of trouble, it is better to simply record
1105            the input in a straightforward non-destructive way.  In the future when
1106            we want to implement more clever MIDI looping modes it should be done in
1107            the Source and/or entirely after the capture is finished.
1108         */
1109         if (was_recording) {
1110                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1111         }
1112 }
1113
1114 void
1115 MidiDiskstream::finish_capture ()
1116 {
1117         was_recording = false;
1118
1119         if (capture_captured == 0) {
1120                 return;
1121         }
1122
1123         CaptureInfo* ci = new CaptureInfo;
1124
1125         ci->start  = capture_start_frame;
1126         ci->frames = capture_captured;
1127
1128         /* XXX theoretical race condition here. Need atomic exchange ?
1129            However, the circumstances when this is called right
1130            now (either on record-disable or transport_stopped)
1131            mean that no actual race exists. I think ...
1132            We now have a capture_info_lock, but it is only to be used
1133            to synchronize in the transport_stop and the capture info
1134            accessors, so that invalidation will not occur (both non-realtime).
1135         */
1136
1137         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1138
1139         capture_info.push_back (ci);
1140         capture_captured = 0;
1141 }
1142
1143 void
1144 MidiDiskstream::set_record_enabled (bool yn)
1145 {
1146         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1147                 return;
1148         }
1149
1150         /* yes, i know that this not proof against race conditions, but its
1151            good enough. i think.
1152         */
1153
1154         if (record_enabled() != yn) {
1155                 if (yn) {
1156                         engage_record_enable ();
1157                 } else {
1158                         disengage_record_enable ();
1159                 }
1160
1161                 RecordEnableChanged (); /* EMIT SIGNAL */
1162         }
1163 }
1164
1165 void
1166 MidiDiskstream::set_record_safe (bool yn)
1167 {
1168         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1169                 return;
1170         }
1171
1172         /* yes, i know that this not proof against race conditions, but its
1173          good enough. i think.
1174          */
1175
1176         if (record_safe () != yn) {
1177                 if (yn) {
1178                         engage_record_safe ();
1179                 } else {
1180                         disengage_record_safe ();
1181                 }
1182
1183                 RecordSafeChanged (); /* EMIT SIGNAL */
1184         }
1185 }
1186
1187 bool
1188 MidiDiskstream::prep_record_enable ()
1189 {
1190         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1191                 return false;
1192         }
1193
1194         bool const rolling = _session.transport_speed() != 0.0f;
1195
1196         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1197
1198         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1199                 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1200         }
1201
1202         return true;
1203 }
1204
1205 bool
1206 MidiDiskstream::prep_record_disable ()
1207 {
1208
1209         return true;
1210 }
1211
1212 XMLNode&
1213 MidiDiskstream::get_state ()
1214 {
1215         XMLNode& node (Diskstream::get_state());
1216         char buf[64];
1217         LocaleGuard lg (X_("C"));
1218
1219         if (_write_source && _session.get_record_enabled()) {
1220
1221                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1222                 XMLNode* cs_grandchild;
1223
1224                 cs_grandchild = new XMLNode (X_("file"));
1225                 cs_grandchild->add_property (X_("path"), _write_source->path());
1226                 cs_child->add_child_nocopy (*cs_grandchild);
1227
1228                 /* store the location where capture will start */
1229
1230                 Location* pi;
1231
1232                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1233                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1234                 } else {
1235                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1236                 }
1237
1238                 cs_child->add_property (X_("at"), buf);
1239                 node.add_child_nocopy (*cs_child);
1240         }
1241
1242         return node;
1243 }
1244
1245 int
1246 MidiDiskstream::set_state (const XMLNode& node, int version)
1247 {
1248         XMLNodeList nlist = node.children();
1249         XMLNodeIterator niter;
1250         XMLNode* capture_pending_node = 0;
1251         LocaleGuard lg (X_("C"));
1252
1253         /* prevent write sources from being created */
1254
1255         in_set_state = true;
1256
1257         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1258                 if ((*niter)->name() == X_("CapturingSources")) {
1259                         capture_pending_node = *niter;
1260                 }
1261         }
1262
1263         if (Diskstream::set_state (node, version)) {
1264                 return -1;
1265         }
1266
1267         if (capture_pending_node) {
1268                 use_pending_capture_data (*capture_pending_node);
1269         }
1270
1271         in_set_state = false;
1272
1273         return 0;
1274 }
1275
1276 int
1277 MidiDiskstream::use_new_write_source (uint32_t n)
1278 {
1279         if (!_session.writable() || !recordable()) {
1280                 return 1;
1281         }
1282
1283         _accumulated_capture_offset = 0;
1284         _write_source.reset();
1285
1286         try {
1287                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1288                         _session.create_midi_source_for_session (write_source_name ()));
1289
1290                 if (!_write_source) {
1291                         throw failed_constructor();
1292                 }
1293         }
1294
1295         catch (failed_constructor &err) {
1296                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1297                 _write_source.reset();
1298                 return -1;
1299         }
1300
1301         return 0;
1302 }
1303 /**
1304  * We want to use the name of the existing write source (the one that will be
1305  * used by the next capture) for another purpose. So change the name of the
1306  * current source, and return its current name.
1307  *
1308  * Return an empty string if the change cannot be accomplished.
1309  */
1310 std::string
1311 MidiDiskstream::steal_write_source_name ()
1312 {
1313         string our_old_name = _write_source->name();
1314
1315         /* this will bump the name of the current write source to the next one
1316          * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1317          * current write source name (e.g. "MIDI 1-1" available). See the
1318          * comments in Session::create_midi_source_by_stealing_name() about why
1319          * we do this.
1320          */
1321
1322         try {
1323                 string new_path = _session.new_midi_source_path (name());
1324
1325                 if (_write_source->rename (new_path)) {
1326                         return string();
1327                 }
1328         } catch (...) {
1329                 return string ();
1330         }
1331
1332         return our_old_name;
1333 }
1334
1335 void
1336 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1337 {
1338         if (!_session.writable() || !recordable()) {
1339                 return;
1340         }
1341
1342         if (_write_source && mark_write_complete) {
1343                 Source::Lock lm(_write_source->mutex());
1344                 _write_source->mark_streaming_write_completed (lm);
1345         }
1346         use_new_write_source (0);
1347 }
1348
1349 void
1350 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1351 {
1352 }
1353
1354 void
1355 MidiDiskstream::allocate_temporary_buffers ()
1356 {
1357 }
1358
1359 void
1360 MidiDiskstream::ensure_input_monitoring (bool yn)
1361 {
1362         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1363
1364         if (sp) {
1365                 sp->ensure_input_monitoring (yn);
1366         }
1367 }
1368
1369 void
1370 MidiDiskstream::set_align_style_from_io ()
1371 {
1372         if (_alignment_choice != Automatic) {
1373                 return;
1374         }
1375
1376         /* XXX Not sure what, if anything we can do with MIDI
1377            as far as capture alignment etc.
1378         */
1379
1380         set_align_style (ExistingMaterial);
1381 }
1382
1383
1384 float
1385 MidiDiskstream::playback_buffer_load () const
1386 {
1387         /* For MIDI it's not trivial to differentiate the following two cases:
1388
1389            1.  The playback buffer is empty because the system has run out of time to fill it.
1390            2.  The playback buffer is empty because there is no more data on the playlist.
1391
1392            If we use a simple buffer load computation, we will report that the MIDI diskstream
1393            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1394            are so low compared to audio, just give a pretend answer here.
1395         */
1396
1397         return 1;
1398 }
1399
1400 float
1401 MidiDiskstream::capture_buffer_load () const
1402 {
1403         /* We don't report playback buffer load, so don't report capture load either */
1404
1405         return 1;
1406 }
1407
1408 int
1409 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1410 {
1411         return 0;
1412 }
1413
1414 void
1415 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1416 {
1417         _playback_buf->flush (start, end);
1418         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1419 }
1420
1421 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1422  *  so that an event at playback_sample has time = 0
1423  */
1424 void
1425 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1426 {
1427         dst.clear();
1428
1429         Location* loc = loop_location;
1430
1431         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1432                              "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1433                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1434                              (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1435
1436         // cerr << "================\n";
1437         // _playback_buf->dump (cerr);
1438         // cerr << "----------------\n";
1439
1440         size_t events_read = 0;
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, 0);
1459                 }
1460
1461                 _playback_buf->skip_to (effective_start);
1462
1463                 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1464                         /* end of loop is within the range we are reading, so
1465                            split the read in two, and lie about the location
1466                            for the 2nd read
1467                         */
1468                         framecnt_t first, second;
1469
1470                         first = loc->end() - effective_start;
1471                         second = nframes - first;
1472
1473                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1474                                                                               effective_start, loc->end(), first, second));
1475
1476                         if (first) {
1477                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1478                                                                                       effective_start, first));
1479                                 events_read = _playback_buf->read (dst, effective_start, first);
1480                         }
1481
1482                         if (second) {
1483                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1484                                                                                       loc->start(), second));
1485                                 events_read += _playback_buf->read (dst, loc->start(), second);
1486                         }
1487
1488                 } else {
1489                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1490                                                                               effective_start, nframes));
1491                         events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1492                 }
1493         } else {
1494                 _playback_buf->skip_to (playback_sample);
1495                 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1496         }
1497
1498         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1499                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1500                              _name, events_read, playback_sample, playback_sample + nframes,
1501                              _playback_buf->read_space(), _playback_buf->write_space(),
1502                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1503
1504         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1505 }
1506
1507 bool
1508 MidiDiskstream::set_name (string const & name)
1509 {
1510         if (_name == name) {
1511                 return true;
1512         }
1513         Diskstream::set_name (name);
1514
1515         /* get a new write source so that its name reflects the new diskstream name */
1516         use_new_write_source (0);
1517
1518         return true;
1519 }
1520
1521 bool
1522 MidiDiskstream::set_write_source_name (const std::string& str) {
1523         if (_write_source_name == str) {
1524                 return true;
1525         }
1526         Diskstream::set_write_source_name (str);
1527         if (_write_source_name == name()) {
1528                 return true;
1529         }
1530         use_new_write_source (0);
1531         return true;
1532 }
1533
1534 boost::shared_ptr<MidiBuffer>
1535 MidiDiskstream::get_gui_feed_buffer () const
1536 {
1537         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1538
1539         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1540         b->copy (_gui_feed_buffer);
1541         return b;
1542 }
1543
1544 void
1545 MidiDiskstream::reset_tracker ()
1546 {
1547         _playback_buf->reset_tracker ();
1548
1549         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1550
1551         if (mp) {
1552                 mp->reset_note_trackers ();
1553         }
1554 }
1555
1556 void
1557 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1558 {
1559         _playback_buf->resolve_tracker(buffer, time);
1560
1561         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1562
1563         if (mp) {
1564                 mp->reset_note_trackers ();
1565         }
1566 }
1567
1568
1569 boost::shared_ptr<MidiPlaylist>
1570 MidiDiskstream::midi_playlist ()
1571 {
1572         return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);
1573 }