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