Implement record with preroll
[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_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                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1039
1040                                 string region_name;
1041
1042                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1043
1044                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1045                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1046
1047
1048                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1049
1050                                 try {
1051                                         PropertyList plist;
1052
1053                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1054                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1055                                         plist.add (Properties::length, (*ci)->frames);
1056                                         plist.add (Properties::length_beats, converter.from((*ci)->frames).to_double());
1057                                         plist.add (Properties::name, region_name);
1058
1059                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1060                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1061                                 }
1062
1063                                 catch (failed_constructor& err) {
1064                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1065                                         continue; /* XXX is this OK? */
1066                                 }
1067
1068                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1069
1070                                 i_am_the_modifier++;
1071                                 _playlist->add_region (region, (*ci)->start);
1072                                 i_am_the_modifier--;
1073                         }
1074
1075                         _playlist->thaw ();
1076                         _session.add_command (new StatefulDiffCommand(_playlist));
1077
1078                 } else {
1079
1080                         /* No data was recorded, so this capture will
1081                            effectively be aborted; do the same as we
1082                            do for an explicit abort.
1083                         */
1084
1085                         if (_write_source) {
1086                                 _write_source->mark_for_remove ();
1087                                 _write_source->drop_references ();
1088                                 _write_source.reset();
1089                         }
1090                 }
1091
1092         }
1093
1094         use_new_write_source (0);
1095
1096         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1097                 delete *ci;
1098         }
1099
1100         capture_info.clear ();
1101         capture_start_frame = 0;
1102
1103   no_capture_stuff_to_do:
1104
1105         reset_tracker ();
1106 }
1107
1108 void
1109 MidiDiskstream::transport_looped (framepos_t)
1110 {
1111         /* Here we only keep track of the number of captured loops so monotonic
1112            event times can be delivered to the write source in process().  Trying
1113            to be clever here is a world of trouble, it is better to simply record
1114            the input in a straightforward non-destructive way.  In the future when
1115            we want to implement more clever MIDI looping modes it should be done in
1116            the Source and/or entirely after the capture is finished.
1117         */
1118         if (was_recording) {
1119                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1120         }
1121 }
1122
1123 void
1124 MidiDiskstream::finish_capture ()
1125 {
1126         was_recording = false;
1127
1128         if (capture_captured == 0) {
1129                 return;
1130         }
1131
1132         CaptureInfo* ci = new CaptureInfo;
1133
1134         ci->start  = capture_start_frame;
1135         ci->frames = capture_captured;
1136
1137         /* XXX theoretical race condition here. Need atomic exchange ?
1138            However, the circumstances when this is called right
1139            now (either on record-disable or transport_stopped)
1140            mean that no actual race exists. I think ...
1141            We now have a capture_info_lock, but it is only to be used
1142            to synchronize in the transport_stop and the capture info
1143            accessors, so that invalidation will not occur (both non-realtime).
1144         */
1145
1146         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1147
1148         capture_info.push_back (ci);
1149         capture_captured = 0;
1150 }
1151
1152 void
1153 MidiDiskstream::set_record_enabled (bool yn)
1154 {
1155         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) {
1156                 return;
1157         }
1158
1159         /* yes, i know that this not proof against race conditions, but its
1160            good enough. i think.
1161         */
1162
1163         if (record_enabled() != yn) {
1164                 if (yn) {
1165                         engage_record_enable ();
1166                 } else {
1167                         disengage_record_enable ();
1168                 }
1169
1170                 RecordEnableChanged (); /* EMIT SIGNAL */
1171         }
1172 }
1173
1174 void
1175 MidiDiskstream::set_record_safe (bool yn)
1176 {
1177         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) { // REQUIRES REVIEW
1178                 return;
1179         }
1180
1181         /* yes, i know that this not proof against race conditions, but its
1182          good enough. i think.
1183          */
1184
1185         if (record_safe () != yn) {
1186                 if (yn) {
1187                         engage_record_safe ();
1188                 } else {
1189                         disengage_record_safe ();
1190                 }
1191
1192                 RecordSafeChanged (); /* EMIT SIGNAL */
1193         }
1194 }
1195
1196 bool
1197 MidiDiskstream::prep_record_enable ()
1198 {
1199         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0 || record_safe ()) { // REQUIRES REVIEW "|| record_safe ()"
1200                 return false;
1201         }
1202
1203         bool const rolling = _session.transport_speed() != 0.0f;
1204
1205         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1206
1207         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1208                 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1209         }
1210
1211         return true;
1212 }
1213
1214 bool
1215 MidiDiskstream::prep_record_disable ()
1216 {
1217
1218         return true;
1219 }
1220
1221 XMLNode&
1222 MidiDiskstream::get_state ()
1223 {
1224         XMLNode& node (Diskstream::get_state());
1225         char buf[64];
1226         LocaleGuard lg;
1227
1228         if (_write_source && _session.get_record_enabled()) {
1229
1230                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1231                 XMLNode* cs_grandchild;
1232
1233                 cs_grandchild = new XMLNode (X_("file"));
1234                 cs_grandchild->add_property (X_("path"), _write_source->path());
1235                 cs_child->add_child_nocopy (*cs_grandchild);
1236
1237                 /* store the location where capture will start */
1238
1239                 Location* pi;
1240
1241                 if (_session.preroll_record_enabled ()) {
1242                         snprintf (buf, sizeof (buf), "%" PRId64, _session.preroll_record_in ());
1243                 } else if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1244                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1245                 } else {
1246                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1247                 }
1248
1249                 cs_child->add_property (X_("at"), buf);
1250                 node.add_child_nocopy (*cs_child);
1251         }
1252
1253         return node;
1254 }
1255
1256 int
1257 MidiDiskstream::set_state (const XMLNode& node, int version)
1258 {
1259         XMLNodeList nlist = node.children();
1260         XMLNodeIterator niter;
1261         XMLNode* capture_pending_node = 0;
1262         LocaleGuard lg;
1263
1264         /* prevent write sources from being created */
1265
1266         in_set_state = true;
1267
1268         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1269                 if ((*niter)->name() == X_("CapturingSources")) {
1270                         capture_pending_node = *niter;
1271                 }
1272         }
1273
1274         if (Diskstream::set_state (node, version)) {
1275                 return -1;
1276         }
1277
1278         if (capture_pending_node) {
1279                 use_pending_capture_data (*capture_pending_node);
1280         }
1281
1282         in_set_state = false;
1283
1284         return 0;
1285 }
1286
1287 int
1288 MidiDiskstream::use_new_write_source (uint32_t n)
1289 {
1290         if (!_session.writable() || !recordable()) {
1291                 return 1;
1292         }
1293
1294         _accumulated_capture_offset = 0;
1295         _write_source.reset();
1296
1297         try {
1298                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1299                         _session.create_midi_source_for_session (write_source_name ()));
1300
1301                 if (!_write_source) {
1302                         throw failed_constructor();
1303                 }
1304         }
1305
1306         catch (failed_constructor &err) {
1307                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1308                 _write_source.reset();
1309                 return -1;
1310         }
1311
1312         return 0;
1313 }
1314 /**
1315  * We want to use the name of the existing write source (the one that will be
1316  * used by the next capture) for another purpose. So change the name of the
1317  * current source, and return its current name.
1318  *
1319  * Return an empty string if the change cannot be accomplished.
1320  */
1321 std::string
1322 MidiDiskstream::steal_write_source_name ()
1323 {
1324         string our_old_name = _write_source->name();
1325
1326         /* this will bump the name of the current write source to the next one
1327          * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1328          * current write source name (e.g. "MIDI 1-1" available). See the
1329          * comments in Session::create_midi_source_by_stealing_name() about why
1330          * we do this.
1331          */
1332
1333         try {
1334                 string new_path = _session.new_midi_source_path (name());
1335
1336                 if (_write_source->rename (new_path)) {
1337                         return string();
1338                 }
1339         } catch (...) {
1340                 return string ();
1341         }
1342
1343         return our_old_name;
1344 }
1345
1346 void
1347 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1348 {
1349         if (!_session.writable() || !recordable()) {
1350                 return;
1351         }
1352
1353         if (_write_source && mark_write_complete) {
1354                 Source::Lock lm(_write_source->mutex());
1355                 _write_source->mark_streaming_write_completed (lm);
1356         }
1357         use_new_write_source (0);
1358 }
1359
1360 void
1361 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1362 {
1363 }
1364
1365 void
1366 MidiDiskstream::allocate_temporary_buffers ()
1367 {
1368 }
1369
1370 void
1371 MidiDiskstream::ensure_input_monitoring (bool yn)
1372 {
1373         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1374
1375         if (sp) {
1376                 sp->ensure_input_monitoring (yn);
1377         }
1378 }
1379
1380 void
1381 MidiDiskstream::set_align_style_from_io ()
1382 {
1383         if (_alignment_choice != Automatic) {
1384                 return;
1385         }
1386
1387         /* XXX Not sure what, if anything we can do with MIDI
1388            as far as capture alignment etc.
1389         */
1390
1391         set_align_style (ExistingMaterial);
1392 }
1393
1394
1395 float
1396 MidiDiskstream::playback_buffer_load () const
1397 {
1398         /* For MIDI it's not trivial to differentiate the following two cases:
1399
1400            1.  The playback buffer is empty because the system has run out of time to fill it.
1401            2.  The playback buffer is empty because there is no more data on the playlist.
1402
1403            If we use a simple buffer load computation, we will report that the MIDI diskstream
1404            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1405            are so low compared to audio, just give a pretend answer here.
1406         */
1407
1408         return 1;
1409 }
1410
1411 float
1412 MidiDiskstream::capture_buffer_load () const
1413 {
1414         /* We don't report playback buffer load, so don't report capture load either */
1415
1416         return 1;
1417 }
1418
1419 int
1420 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1421 {
1422         return 0;
1423 }
1424
1425 void
1426 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1427 {
1428         _playback_buf->flush (start, end);
1429         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1430 }
1431
1432 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1433  *  so that an event at playback_sample has time = 0
1434  */
1435 void
1436 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1437 {
1438         dst.clear();
1439
1440         Location* loc = loop_location;
1441
1442         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1443                              "%1 MDS pre-read read %8 offset = %9 @ %4..%5 from %2 write to %3, LOOPED ? %6 .. %7\n", _name,
1444                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes,
1445                              (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes, Port::port_offset()));
1446
1447         //cerr << "======== PRE ========\n";
1448         //_playback_buf->dump (cerr);
1449         //cerr << "----------------\n";
1450
1451         size_t events_read = 0;
1452
1453         if (loc) {
1454                 framepos_t effective_start;
1455
1456                 Evoral::Range<framepos_t> loop_range (loc->start(), loc->end() - 1);
1457                 effective_start = loop_range.squish (playback_sample);
1458
1459                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1460
1461                 if (effective_start == loc->start()) {
1462                         /* We need to turn off notes that may extend
1463                            beyond the loop end.
1464                         */
1465
1466                         _playback_buf->resolve_tracker (dst, 0);
1467                 }
1468
1469                 /* for split-cycles we need to offset the events */
1470
1471                 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1472
1473                         /* end of loop is within the range we are reading, so
1474                            split the read in two, and lie about the location
1475                            for the 2nd read
1476                         */
1477
1478                         framecnt_t first, second;
1479
1480                         first = loc->end() - effective_start;
1481                         second = nframes - first;
1482
1483                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4, cycle offset %5\n",
1484                                                                               effective_start, loc->end(), first, second));
1485
1486                         if (first) {
1487                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1488                                                                                       effective_start, first));
1489                                 events_read = _playback_buf->read (dst, effective_start, first);
1490                         }
1491
1492                         if (second) {
1493                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1494                                                                                       loc->start(), second));
1495                                 events_read += _playback_buf->read (dst, loc->start(), second);
1496                         }
1497
1498                 } else {
1499                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1500                                                                               effective_start, nframes));
1501                         events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1502                 }
1503         } else {
1504                 const size_t n_skipped = _playback_buf->skip_to (playback_sample);
1505                 if (n_skipped > 0) {
1506                         warning << string_compose(_("MidiDiskstream %1: skipped %2 events, possible underflow"), id(), n_skipped) << endmsg;
1507                 }
1508                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("playback buffer read, from %1 to %2 (%3)", playback_sample, playback_sample + nframes, nframes));
1509                 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1510         }
1511
1512         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1513                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1514                              _name, events_read, playback_sample, playback_sample + nframes,
1515                              _playback_buf->read_space(), _playback_buf->write_space(),
1516                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1517
1518         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1519
1520         //cerr << "======== POST ========\n";
1521         //_playback_buf->dump (cerr);
1522         //cerr << "----------------\n";
1523 }
1524
1525 bool
1526 MidiDiskstream::set_name (string const & name)
1527 {
1528         if (_name == name) {
1529                 return true;
1530         }
1531         Diskstream::set_name (name);
1532
1533         /* get a new write source so that its name reflects the new diskstream name */
1534         use_new_write_source (0);
1535
1536         return true;
1537 }
1538
1539 bool
1540 MidiDiskstream::set_write_source_name (const std::string& str) {
1541         if (_write_source_name == str) {
1542                 return true;
1543         }
1544         Diskstream::set_write_source_name (str);
1545         if (_write_source_name == name()) {
1546                 return true;
1547         }
1548         use_new_write_source (0);
1549         return true;
1550 }
1551
1552 boost::shared_ptr<MidiBuffer>
1553 MidiDiskstream::get_gui_feed_buffer () const
1554 {
1555         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1556
1557         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1558         b->copy (_gui_feed_buffer);
1559         return b;
1560 }
1561
1562 void
1563 MidiDiskstream::reset_tracker ()
1564 {
1565         _playback_buf->reset_tracker ();
1566
1567         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1568
1569         if (mp) {
1570                 mp->reset_note_trackers ();
1571         }
1572 }
1573
1574 void
1575 MidiDiskstream::resolve_tracker (Evoral::EventSink<framepos_t>& buffer, framepos_t time)
1576 {
1577         _playback_buf->resolve_tracker(buffer, time);
1578
1579         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1580
1581         if (mp) {
1582                 mp->reset_note_trackers ();
1583         }
1584 }
1585
1586
1587 boost::shared_ptr<MidiPlaylist>
1588 MidiDiskstream::midi_playlist ()
1589 {
1590         return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);
1591 }