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