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