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