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