e2fd6d168144fb09809124e359449a98cd6c3c66
[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         /* This is safe as long as the butler thread is suspended, which it should be */
610         _playback_buf->reset ();
611
612         g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
613         g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
614
615         read (overwrite_frame, disk_io_chunk_frames, false);
616         file_frame = overwrite_frame; // it was adjusted by ::read()
617         overwrite_queued = false;
618         _pending_overwrite = false;
619
620         return 0;
621 }
622
623 int
624 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
625 {
626         Glib::Threads::Mutex::Lock lm (state_lock);
627         int ret = -1;
628
629         if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
630                 /* we haven't read anything since the last seek,
631                    so flush all note trackers to prevent
632                    wierdness
633                 */
634                 reset_tracker ();
635         }
636
637         _playback_buf->reset();
638         _capture_buf->reset();
639         g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
640         g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
641
642         playback_sample = frame;
643         file_frame = frame;
644
645         if (complete_refill) {
646                 while ((ret = do_refill_with_alloc ()) > 0) ;
647         } else {
648                 ret = do_refill_with_alloc ();
649         }
650
651         return ret;
652 }
653
654 int
655 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
656 {
657         uint32_t frames_read    = g_atomic_int_get(&_frames_read_from_ringbuffer);
658         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
659         return ((frames_written - frames_read) < distance);
660 }
661
662 int
663 MidiDiskstream::internal_playback_seek (framecnt_t distance)
664 {
665         first_recordable_frame += distance;
666         playback_sample += distance;
667
668         return 0;
669 }
670
671 /** @a start is set to the new frame position (TIME) read up to */
672 int
673 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
674 {
675         framecnt_t this_read   = 0;
676         bool       reloop      = false;
677         framepos_t loop_end    = 0;
678         framepos_t loop_start  = 0;
679         framecnt_t loop_length = 0;
680         Location*  loc         = 0;
681
682         if (!reversed) {
683
684                 loc = loop_location;
685                 get_location_times(loc, &loop_start, &loop_end, &loop_length);
686
687                 /* if we are looping, ensure that the first frame we read is at the correct
688                    position within the loop.
689                 */
690
691                 if (loc && (start >= loop_end)) {
692                         //cerr << "start adjusted from " << start;
693                         start = loop_start + ((start - loop_start) % loop_length);
694                         //cerr << "to " << start << endl;
695                 }
696                 // cerr << "start is " << start << " end " << start+dur << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
697         }
698
699         while (dur) {
700
701                 /* take any loop into account. we can't read past the end of the loop. */
702
703                 if (loc && (loop_end - start <= dur)) {
704                         this_read = loop_end - start;
705                         // cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
706                         reloop = true;
707                 } else {
708                         reloop = false;
709                         this_read = dur;
710                 }
711
712                 if (this_read == 0) {
713                         break;
714                 }
715
716                 this_read = min(dur,this_read);
717
718                 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
719                         error << string_compose(
720                                         _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
721                                         id(), this_read, start) << endmsg;
722                         return -1;
723                 }
724                 
725                 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
726
727                 if (reversed) {
728
729                         // Swap note ons with note offs here.  etc?
730                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
731                         // CC values etc.  hard.
732
733                 } else {
734
735                         /* if we read to the end of the loop, go back to the beginning */
736                         if (reloop) {
737                                 // Synthesize LoopEvent here, because the next events
738                                 // written will have non-monotonic timestamps.
739                                 start = loop_start;
740                         } else {
741                                 start += this_read;
742                         }
743                 }
744
745                 dur -= this_read;
746                 //offset += this_read;
747         }
748
749         return 0;
750 }
751
752 int
753 MidiDiskstream::do_refill_with_alloc ()
754 {
755         return do_refill();
756 }
757
758 int
759 MidiDiskstream::do_refill ()
760 {
761         int     ret         = 0;
762         size_t  write_space = _playback_buf->write_space();
763         bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
764
765         if (write_space == 0) {
766                 return 0;
767         }
768
769         if (reversed) {
770                 return 0;
771         }
772
773         /* at end: nothing to do */
774         if (file_frame == max_framepos) {
775                 return 0;
776         }
777
778         /* no space to write */
779         if (_playback_buf->write_space() == 0) {
780                 return 0;
781         }
782
783         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
784         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
785         if ((frames_written - frames_read) >= midi_readahead) {
786                 return 0;
787         }
788
789         framecnt_t to_read = midi_readahead - (frames_written - frames_read);
790
791         //cout << "MDS read for midi_readahead " << to_read << "  rb_contains: "
792         //      << frames_written - frames_read << endl;
793
794         to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
795
796         if (read (file_frame, to_read, reversed)) {
797                 ret = -1;
798         }
799
800         return ret;
801 }
802
803 /** Flush pending data to disk.
804  *
805  * Important note: this function will write *AT MOST* disk_io_chunk_frames
806  * of data to disk. it will never write more than that.  If it writes that
807  * much and there is more than that waiting to be written, it will return 1,
808  * otherwise 0 on success or -1 on failure.
809  *
810  * If there is less than disk_io_chunk_frames to be written, no data will be
811  * written at all unless @a force_flush is true.
812  */
813 int
814 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
815 {
816         framecnt_t to_write;
817         int32_t ret = 0;
818
819         if (!_write_source) {
820                 return 0;
821         }
822
823         const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
824
825         if (total == 0 || 
826             _capture_buf->read_space() == 0 || 
827             (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
828                 goto out;
829         }
830
831         /* if there are 2+ chunks of disk i/o possible for
832            this track), let the caller know so that it can arrange
833            for us to be called again, ASAP.
834
835            if we are forcing a flush, then if there is* any* extra
836            work, let the caller know.
837
838            if we are no longer recording and there is any extra work,
839            let the caller know too.
840            */
841
842         if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
843                 ret = 1;
844         }
845
846         if (force_flush) {
847                 /* push out everything we have, right now */
848                 to_write = max_framecnt;
849         } else {
850                 to_write = disk_io_chunk_frames;
851         }
852
853         if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
854                 Source::Lock lm(_write_source->mutex());
855                 if (_write_source->midi_write (lm, *_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
856                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
857                         return -1;
858                 } 
859                 g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
860         }
861
862 out:
863         return ret;
864 }
865
866 void
867 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
868 {
869         bool more_work = true;
870         int err = 0;
871         boost::shared_ptr<MidiRegion> region;
872         MidiRegion::SourceList srcs;
873         MidiRegion::SourceList::iterator src;
874         vector<CaptureInfo*>::iterator ci;
875
876         finish_capture ();
877
878         /* butler is already stopped, but there may be work to do
879            to flush remaining data to disk.
880            */
881
882         while (more_work && !err) {
883                 switch (do_flush (TransportContext, true)) {
884                 case 0:
885                         more_work = false;
886                         break;
887                 case 1:
888                         break;
889                 case -1:
890                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
891                         err++;
892                 }
893         }
894
895         /* XXX is there anything we can do if err != 0 ? */
896         Glib::Threads::Mutex::Lock lm (capture_info_lock);
897
898         if (capture_info.empty()) {
899                 goto no_capture_stuff_to_do;
900         }
901
902         if (abort_capture) {
903
904                 if (_write_source) {
905                         _write_source->mark_for_remove ();
906                         _write_source->drop_references ();
907                         _write_source.reset();
908                 }
909
910                 /* new source set up in "out" below */
911
912         } else {
913
914                 framecnt_t total_capture = 0;
915                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
916                         total_capture += (*ci)->frames;
917                 }
918
919                 if (_write_source->length (capture_info.front()->start) != 0) {
920
921                         /* phew, we have data */
922
923                         Source::Lock source_lock(_write_source->mutex());
924
925                         /* figure out the name for this take */
926
927                         srcs.push_back (_write_source);
928
929                         _write_source->set_timeline_position (capture_info.front()->start);
930                         _write_source->set_captured_for (_name);
931
932                         /* set length in beats to entire capture length */
933
934                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
935                         const Evoral::MusicalTime total_capture_beats = converter.from (total_capture);
936                         _write_source->set_length_beats (total_capture_beats);
937
938                         /* flush to disk: this step differs from the audio path,
939                            where all the data is already on disk.
940                         */
941
942                         _write_source->mark_midi_streaming_write_completed (source_lock, Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
943
944                         /* we will want to be able to keep (over)writing the source
945                            but we don't want it to be removable. this also differs
946                            from the audio situation, where the source at this point
947                            must be considered immutable. luckily, we can rely on
948                            MidiSource::mark_streaming_write_completed() to have
949                            already done the necessary work for that.
950                         */
951
952                         string whole_file_region_name;
953                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
954
955                         /* Register a new region with the Session that
956                            describes the entire source. Do this first
957                            so that any sub-regions will obviously be
958                            children of this one (later!)
959                         */
960
961                         try {
962                                 PropertyList plist;
963
964                                 plist.add (Properties::name, whole_file_region_name);
965                                 plist.add (Properties::whole_file, true);
966                                 plist.add (Properties::automatic, true);
967                                 plist.add (Properties::start, 0);
968                                 plist.add (Properties::length, total_capture);
969                                 plist.add (Properties::layer, 0);
970
971                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
972
973                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
974                                 region->special_set_position (capture_info.front()->start);
975                         }
976
977
978                         catch (failed_constructor& err) {
979                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
980                                 /* XXX what now? */
981                         }
982
983                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
984
985                         _playlist->clear_changes ();
986                         _playlist->freeze ();
987
988                         /* Session frame time of the initial capture in this pass, which is where the source starts */
989                         framepos_t initial_capture = 0;
990                         if (!capture_info.empty()) {
991                                 initial_capture = capture_info.front()->start;
992                         }
993
994                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
995
996                                 string region_name;
997
998                                 RegionFactory::region_name (region_name, _write_source->name(), false);
999
1000                                 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1001                                                         _name, (*ci)->start, (*ci)->frames, region_name));
1002
1003
1004                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1005
1006                                 try {
1007                                         PropertyList plist;
1008
1009                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1010                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1011                                         plist.add (Properties::length, (*ci)->frames);
1012                                         plist.add (Properties::length_beats, converter.from((*ci)->frames));
1013                                         plist.add (Properties::name, region_name);
1014
1015                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1016                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1017                                 }
1018
1019                                 catch (failed_constructor& err) {
1020                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1021                                         continue; /* XXX is this OK? */
1022                                 }
1023
1024                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1025
1026                                 i_am_the_modifier++;
1027                                 _playlist->add_region (region, (*ci)->start);
1028                                 i_am_the_modifier--;
1029                         }
1030
1031                         _playlist->thaw ();
1032                         _session.add_command (new StatefulDiffCommand(_playlist));
1033
1034                 } else {
1035
1036                         /* No data was recorded, so this capture will
1037                            effectively be aborted; do the same as we
1038                            do for an explicit abort.
1039                         */
1040
1041                         if (_write_source) {
1042                                 _write_source->mark_for_remove ();
1043                                 _write_source->drop_references ();
1044                                 _write_source.reset();
1045                         }
1046                 }
1047
1048         }
1049
1050         use_new_write_source (0);
1051
1052         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1053                 delete *ci;
1054         }
1055
1056         capture_info.clear ();
1057         capture_start_frame = 0;
1058
1059   no_capture_stuff_to_do:
1060
1061         reset_tracker ();
1062 }
1063
1064 void
1065 MidiDiskstream::transport_looped (framepos_t)
1066 {
1067         /* Here we only keep track of the number of captured loops so monotonic
1068            event times can be delivered to the write source in process().  Trying
1069            to be clever here is a world of trouble, it is better to simply record
1070            the input in a straightforward non-destructive way.  In the future when
1071            we want to implement more clever MIDI looping modes it should be done in
1072            the Source and/or entirely after the capture is finished.
1073         */
1074         if (was_recording) {
1075                 g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
1076         }
1077 }
1078
1079 void
1080 MidiDiskstream::finish_capture ()
1081 {
1082         was_recording = false;
1083
1084         if (capture_captured == 0) {
1085                 return;
1086         }
1087
1088         CaptureInfo* ci = new CaptureInfo;
1089
1090         ci->start  = capture_start_frame;
1091         ci->frames = capture_captured;
1092
1093         /* XXX theoretical race condition here. Need atomic exchange ?
1094            However, the circumstances when this is called right
1095            now (either on record-disable or transport_stopped)
1096            mean that no actual race exists. I think ...
1097            We now have a capture_info_lock, but it is only to be used
1098            to synchronize in the transport_stop and the capture info
1099            accessors, so that invalidation will not occur (both non-realtime).
1100         */
1101
1102         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1103
1104         capture_info.push_back (ci);
1105         capture_captured = 0;
1106 }
1107
1108 void
1109 MidiDiskstream::set_record_enabled (bool yn)
1110 {
1111         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1112                 return;
1113         }
1114
1115         /* yes, i know that this not proof against race conditions, but its
1116            good enough. i think.
1117         */
1118
1119         if (record_enabled() != yn) {
1120                 if (yn) {
1121                         engage_record_enable ();
1122                 } else {
1123                         disengage_record_enable ();
1124                 }
1125                 
1126                 RecordEnableChanged (); /* EMIT SIGNAL */
1127         }
1128 }
1129
1130 bool
1131 MidiDiskstream::prep_record_enable ()
1132 {
1133         if (!recordable() || !_session.record_enabling_legal() || _io->n_ports().n_midi() == 0) {
1134                 return false;
1135         }
1136
1137         bool const rolling = _session.transport_speed() != 0.0f;
1138
1139         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1140         
1141         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1142                 sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
1143         }
1144
1145         return true;
1146 }
1147
1148 bool
1149 MidiDiskstream::prep_record_disable ()
1150 {
1151
1152         return true;
1153 }
1154
1155 XMLNode&
1156 MidiDiskstream::get_state ()
1157 {
1158         XMLNode& node (Diskstream::get_state());
1159         char buf[64];
1160         LocaleGuard lg (X_("POSIX"));
1161
1162         if (_write_source && _session.get_record_enabled()) {
1163
1164                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1165                 XMLNode* cs_grandchild;
1166
1167                 cs_grandchild = new XMLNode (X_("file"));
1168                 cs_grandchild->add_property (X_("path"), _write_source->path());
1169                 cs_child->add_child_nocopy (*cs_grandchild);
1170
1171                 /* store the location where capture will start */
1172
1173                 Location* pi;
1174
1175                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1176                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1177                 } else {
1178                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1179                 }
1180
1181                 cs_child->add_property (X_("at"), buf);
1182                 node.add_child_nocopy (*cs_child);
1183         }
1184
1185         return node;
1186 }
1187
1188 int
1189 MidiDiskstream::set_state (const XMLNode& node, int version)
1190 {
1191         XMLNodeList nlist = node.children();
1192         XMLNodeIterator niter;
1193         XMLNode* capture_pending_node = 0;
1194         LocaleGuard lg (X_("POSIX"));
1195
1196         /* prevent write sources from being created */
1197
1198         in_set_state = true;
1199
1200         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1201                 if ((*niter)->name() == X_("CapturingSources")) {
1202                         capture_pending_node = *niter;
1203                 }
1204         }
1205
1206         if (Diskstream::set_state (node, version)) {
1207                 return -1;
1208         }
1209
1210         if (capture_pending_node) {
1211                 use_pending_capture_data (*capture_pending_node);
1212         }
1213
1214         in_set_state = false;
1215
1216         return 0;
1217 }
1218
1219 int
1220 MidiDiskstream::use_new_write_source (uint32_t n)
1221 {
1222         if (!_session.writable() || !recordable()) {
1223                 return 1;
1224         }
1225
1226         _accumulated_capture_offset = 0;
1227         _write_source.reset();
1228
1229         try {
1230                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1231                         _session.create_midi_source_for_session (write_source_name ()));
1232
1233                 if (!_write_source) {
1234                         throw failed_constructor();
1235                 }
1236         }
1237
1238         catch (failed_constructor &err) {
1239                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1240                 _write_source.reset();
1241                 return -1;
1242         }
1243
1244         return 0;
1245 }
1246 /**
1247  * We want to use the name of the existing write source (the one that will be
1248  * used by the next capture) for another purpose. So change the name of the
1249  * current source, and return its current name.
1250  *
1251  * Return an empty string if the change cannot be accomplished.
1252  */
1253 std::string
1254 MidiDiskstream::steal_write_source_name ()
1255 {
1256         string our_old_name = _write_source->name();
1257
1258         /* this will bump the name of the current write source to the next one
1259          * (e.g. "MIDI 1-1" gets renamed to "MIDI 1-2"), thus leaving the
1260          * current write source name (e.g. "MIDI 1-1" available). See the
1261          * comments in Session::create_midi_source_by_stealing_name() about why
1262          * we do this.
1263          */
1264
1265         try {
1266                 string new_path = _session.new_midi_source_path (name());
1267                 
1268                 if (_write_source->rename (new_path)) {
1269                         return string();
1270                 }
1271         } catch (...) {
1272                 return string ();
1273         }
1274         
1275         return our_old_name;
1276 }
1277
1278 void
1279 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1280 {
1281         if (!_session.writable() || !recordable()) {
1282                 return;
1283         }
1284
1285         if (_write_source && mark_write_complete) {
1286                 Source::Lock lm(_write_source->mutex());
1287                 _write_source->mark_streaming_write_completed (lm);
1288         }
1289         use_new_write_source (0);
1290 }
1291
1292 void
1293 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1294 {
1295 }
1296
1297 void
1298 MidiDiskstream::allocate_temporary_buffers ()
1299 {
1300 }
1301
1302 void
1303 MidiDiskstream::ensure_input_monitoring (bool yn)
1304 {
1305         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1306         
1307         if (sp) {
1308                 sp->ensure_input_monitoring (yn);
1309         }
1310 }
1311
1312 void
1313 MidiDiskstream::set_align_style_from_io ()
1314 {
1315         if (_alignment_choice != Automatic) {
1316                 return;
1317         }
1318
1319         /* XXX Not sure what, if anything we can do with MIDI
1320            as far as capture alignment etc.
1321         */
1322
1323         set_align_style (ExistingMaterial);
1324 }
1325
1326
1327 float
1328 MidiDiskstream::playback_buffer_load () const
1329 {
1330         /* For MIDI it's not trivial to differentiate the following two cases:
1331            
1332            1.  The playback buffer is empty because the system has run out of time to fill it.
1333            2.  The playback buffer is empty because there is no more data on the playlist.
1334
1335            If we use a simple buffer load computation, we will report that the MIDI diskstream
1336            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1337            are so low compared to audio, just give a pretend answer here.
1338         */
1339         
1340         return 1;
1341 }
1342
1343 float
1344 MidiDiskstream::capture_buffer_load () const
1345 {
1346         /* We don't report playback buffer load, so don't report capture load either */
1347         
1348         return 1;
1349 }
1350
1351 int
1352 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1353 {
1354         return 0;
1355 }
1356
1357 void
1358 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1359 {
1360         _playback_buf->flush (start, end);
1361         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1362 }
1363
1364 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1365  *  so that an event at playback_sample has time = 0
1366  */
1367 void
1368 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1369 {
1370         dst.clear();
1371
1372         Location* loc = loop_location;
1373
1374         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1375                              "%1 MDS pre-read read %8 @ %4..%5 from %2 write to %3, LOOPED ? %6-%7\n", _name,
1376                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes, 
1377                              (loc ? loc->start() : -1), (loc ? loc->end() : -1), nframes));
1378
1379         // cerr << "================\n";
1380         // _playback_buf->dump (cerr);
1381         // cerr << "----------------\n";
1382
1383         size_t events_read = 0; 
1384
1385         if (loc) {
1386                 framepos_t effective_start;
1387
1388                 if (playback_sample >= loc->end()) {
1389                         effective_start = loc->start() + ((playback_sample - loc->end()) % loc->length());
1390                 } else {
1391                         effective_start = playback_sample;
1392                 }
1393                 
1394                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("looped, effective start adjusted to %1\n", effective_start));
1395
1396                 if (effective_start == loc->start()) {
1397                         /* We need to turn off notes that may extend
1398                            beyond the loop end.
1399                         */
1400
1401                         _playback_buf->loop_resolve (dst, 0);
1402                 }
1403
1404                 if (loc->end() >= effective_start && loc->end() < effective_start + nframes) {
1405                         /* end of loop is within the range we are reading, so
1406                            split the read in two, and lie about the location
1407                            for the 2nd read
1408                         */
1409                         framecnt_t first, second;
1410
1411                         first = loc->end() - effective_start;
1412                         second = nframes - first;
1413
1414                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read for eff %1 end %2: %3 and %4\n",
1415                                                                               effective_start, loc->end(), first, second));
1416
1417                         if (first) {
1418                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #1, from %1 for %2\n",
1419                                                                                       effective_start, first));
1420                                 events_read = _playback_buf->read (dst, effective_start, first);
1421                         } 
1422
1423                         if (second) {
1424                                 DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #2, from %1 for %2\n",
1425                                                                                       loc->start(), second));
1426                                 events_read += _playback_buf->read (dst, loc->start(), second);
1427                         }
1428                                                                     
1429                 } else {
1430                         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose ("loop read #3, adjusted start as %1 for %2\n",
1431                                                                               effective_start, nframes));
1432                         events_read = _playback_buf->read (dst, effective_start, effective_start + nframes);
1433                 }
1434         } else {
1435                 events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1436         }
1437
1438         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1439                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1440                              _name, events_read, playback_sample, playback_sample + nframes,
1441                              _playback_buf->read_space(), _playback_buf->write_space(),
1442                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1443
1444         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1445 }
1446
1447 bool
1448 MidiDiskstream::set_name (string const & name)
1449 {
1450         if (_name == name) {
1451                 return true;
1452         }
1453         Diskstream::set_name (name);
1454
1455         /* get a new write source so that its name reflects the new diskstream name */
1456         use_new_write_source (0);
1457
1458         return true;
1459 }
1460
1461 bool
1462 MidiDiskstream::set_write_source_name (const std::string& str) {
1463         if (_write_source_name == str) {
1464                 return true;
1465         }
1466         Diskstream::set_write_source_name (str);
1467         if (_write_source_name == name()) {
1468                 return true;
1469         }
1470         use_new_write_source (0);
1471         return true;
1472 }
1473
1474 boost::shared_ptr<MidiBuffer>
1475 MidiDiskstream::get_gui_feed_buffer () const
1476 {
1477         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1478         
1479         Glib::Threads::Mutex::Lock lm (_gui_feed_buffer_mutex);
1480         b->copy (_gui_feed_buffer);
1481         return b;
1482 }
1483
1484 void
1485 MidiDiskstream::reset_tracker ()
1486 {
1487         _playback_buf->reset_tracker ();
1488
1489         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1490
1491         if (mp) {
1492                 mp->clear_note_trackers ();
1493         }
1494 }
1495
1496 boost::shared_ptr<MidiPlaylist>
1497 MidiDiskstream::midi_playlist ()
1498 {
1499         return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist);
1500 }