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