Inrease the export "chunk size" to speed it up over 10% at least in some situations
[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 #include <sys/mman.h>
31
32 #include "pbd/error.h"
33 #include "pbd/basename.h"
34 #include <glibmm/thread.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/playlist_factory.h"
51 #include "ardour/region_factory.h"
52 #include "ardour/session.h"
53 #include "ardour/session_playlists.h"
54 #include "ardour/smf_source.h"
55 #include "ardour/types.h"
56 #include "ardour/utils.h"
57
58 #include "midi++/types.h"
59
60 #include "i18n.h"
61 #include <locale.h>
62
63 using namespace std;
64 using namespace ARDOUR;
65 using namespace PBD;
66
67 framecnt_t MidiDiskstream::midi_readahead = 4096;
68
69 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
70         : Diskstream(sess, name, flag)
71         , _playback_buf(0)
72         , _capture_buf(0)
73         , _note_mode(Sustained)
74         , _frames_written_to_ringbuffer(0)
75         , _frames_read_from_ringbuffer(0)
76         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
77 {
78         in_set_state = true;
79
80         init ();
81         use_new_playlist ();
82         use_new_write_source (0);
83
84         in_set_state = false;
85
86         assert(!destructive());
87 }
88
89 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
90         : Diskstream(sess, node)
91         , _playback_buf(0)
92         , _capture_buf(0)
93         , _note_mode(Sustained)
94         , _frames_written_to_ringbuffer(0)
95         , _frames_read_from_ringbuffer(0)
96         , _gui_feed_buffer(AudioEngine::instance()->raw_buffer_size (DataType::MIDI))
97 {
98         in_set_state = true;
99
100         init ();
101
102         if (set_state (node, Stateful::loading_state_version)) {
103                 in_set_state = false;
104                 throw failed_constructor();
105         }
106
107         use_new_write_source (0);
108
109         in_set_state = false;
110 }
111
112 void
113 MidiDiskstream::init ()
114 {
115         /* there are no channels at this point, so these
116            two calls just get speed_buffer_size and wrap_buffer
117            size setup without duplicating their code.
118         */
119
120         set_block_size (_session.get_block_size());
121         allocate_temporary_buffers ();
122
123         const size_t size = _session.butler()->midi_diskstream_buffer_size();
124         _playback_buf = new MidiRingBuffer<framepos_t>(size);
125         _capture_buf = new MidiRingBuffer<framepos_t>(size);
126
127         _n_channels = ChanCount(DataType::MIDI, 1);
128
129         assert(recordable());
130 }
131
132 MidiDiskstream::~MidiDiskstream ()
133 {
134         Glib::Mutex::Lock lm (state_lock);
135 }
136
137
138 void
139 MidiDiskstream::non_realtime_locate (framepos_t position)
140 {
141         if (_write_source) {
142                 _write_source->set_timeline_position (position);
143         }
144         seek (position, false);
145 }
146
147
148 void
149 MidiDiskstream::non_realtime_input_change ()
150 {
151         {
152                 Glib::Mutex::Lock lm (state_lock);
153
154                 if (input_change_pending.type == IOChange::NoChange) {
155                         return;
156                 }
157
158                 if (input_change_pending.type & IOChange::ConfigurationChanged) {
159                         uint32_t ni = _io->n_ports().n_midi();
160
161                         if (ni != _n_channels.n_midi()) {
162                                 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
163                                                          name(),
164                                                          _io->n_ports(),
165                                                          _n_channels, input_change_pending.type)
166                                       << endmsg;
167                         }
168
169                         if (ni == 0) {
170                                 _source_port.reset ();
171                         } else {
172                                 _source_port = _io->midi(0);
173                         }
174                 }
175
176                 if (input_change_pending.type & IOChange::ConnectionsChanged) {
177                         set_capture_offset ();
178                         set_align_style_from_io ();
179                 }
180
181                 input_change_pending.type = IOChange::NoChange;
182
183                 /* implicit unlock */
184         }
185
186         /* unlike with audio, there is never any need to reset write sources
187            based on input configuration changes because ... a MIDI track
188            has just 1 MIDI port as input, always.
189         */
190
191         /* now refill channel buffers */
192
193         if (speed() != 1.0f || speed() != -1.0f) {
194                 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
195         }
196         else {
197                 seek (_session.transport_frame());
198         }
199
200         if (_write_source) {
201                 _write_source->set_last_write_end (_session.transport_frame());
202         }
203 }
204
205 int
206 MidiDiskstream::find_and_use_playlist (const string& name)
207 {
208         boost::shared_ptr<MidiPlaylist> playlist;
209
210         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) == 0) {
211                 playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name));
212         }
213
214         if (!playlist) {
215                 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg;
216                 return -1;
217         }
218
219         return use_playlist (playlist);
220 }
221
222 int
223 MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
224 {
225         assert(boost::dynamic_pointer_cast<MidiPlaylist>(playlist));
226
227         Diskstream::use_playlist(playlist);
228
229         return 0;
230 }
231
232 int
233 MidiDiskstream::use_new_playlist ()
234 {
235         string newname;
236         boost::shared_ptr<MidiPlaylist> playlist;
237
238         if (!in_set_state && destructive()) {
239                 return 0;
240         }
241
242         if (_playlist) {
243                 newname = Playlist::bump_name (_playlist->name(), _session);
244         } else {
245                 newname = Playlist::bump_name (_name, _session);
246         }
247
248         if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
249                         DataType::MIDI, _session, newname, hidden()))) != 0) {
250
251                 return use_playlist (playlist);
252
253         } else {
254                 return -1;
255         }
256 }
257
258 int
259 MidiDiskstream::use_copy_playlist ()
260 {
261         assert(midi_playlist());
262
263         if (destructive()) {
264                 return 0;
265         }
266
267         if (_playlist == 0) {
268                 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
269                 return -1;
270         }
271
272         string newname;
273         boost::shared_ptr<MidiPlaylist> playlist;
274
275         newname = Playlist::bump_name (_playlist->name(), _session);
276
277         if ((playlist  = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
278                 return use_playlist (playlist);
279         } else {
280                 return -1;
281         }
282 }
283
284 /** Overloaded from parent to die horribly
285  */
286 int
287 MidiDiskstream::set_destructive (bool yn)
288 {
289         yn = 0; // stop pedantic gcc complaints about unused parameter
290         assert( ! destructive());
291         assert( ! yn);
292         return -1;
293 }
294
295 void
296 MidiDiskstream::set_note_mode (NoteMode m)
297 {
298         _note_mode = m;
299         midi_playlist()->set_note_mode(m);
300         if (_write_source && _write_source->model())
301                 _write_source->model()->set_note_mode(m);
302 }
303
304 int
305 MidiDiskstream::process (framepos_t transport_frame, pframes_t nframes, framecnt_t& playback_distance)
306 {
307         framecnt_t rec_offset = 0;
308         framecnt_t rec_nframes = 0;
309         bool      nominally_recording;
310         bool      re = record_enabled ();
311         bool      can_record = _session.actively_recording ();
312
313         playback_distance = 0;
314
315         check_record_status (transport_frame, can_record);
316
317         nominally_recording = (can_record && re);
318
319         if (nframes == 0) {
320                 return 0;
321         }
322
323         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
324
325         if (sp == 0) {
326                 return 1;
327         }
328
329         Glib::Mutex::Lock sm (state_lock, Glib::TRY_LOCK);
330
331         if (!sm.locked()) {
332                 return 1;
333         }
334
335         adjust_capture_position = 0;
336
337         if (nominally_recording || (re && was_recording && _session.get_record_enabled() && _session.config.get_punch_in())) {
338                 Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
339
340                 calculate_record_range(ot, transport_frame, nframes, rec_nframes, rec_offset);
341
342                 if (rec_nframes && !was_recording) {
343                         _write_source->mark_write_starting_now ();
344                         capture_captured = 0;
345                         was_recording = true;
346                 }
347         }
348
349         if (can_record && !_last_capture_sources.empty()) {
350                 _last_capture_sources.clear ();
351         }
352
353         if (nominally_recording || rec_nframes) {
354
355                 // Pump entire port buffer into the ring buffer (FIXME: split cycles?)
356                 MidiBuffer& buf = sp->get_midi_buffer(nframes);
357                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
358                         const Evoral::MIDIEvent<MidiBuffer::TimeType> ev(*i, false);
359                         assert(ev.buffer());
360 #ifndef NDEBUG
361                         if (DEBUG::MidiIO & PBD::debug_bits) {
362                                 const uint8_t* __data = ev.buffer();
363                                 DEBUG_STR_DECL(a);
364                                 DEBUG_STR_APPEND(a, string_compose ("mididiskstream %1 capture event @ %2 + %3 sz %4 ", this, ev.time(), transport_frame, ev.size()));
365                                 for (size_t i=0; i < ev.size(); ++i) {
366                                         DEBUG_STR_APPEND(a,hex);
367                                         DEBUG_STR_APPEND(a,"0x");
368                                         DEBUG_STR_APPEND(a,(int)__data[i]);
369                                         DEBUG_STR_APPEND(a,' ');
370                                 }
371                                 DEBUG_STR_APPEND(a,'\n');
372                                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
373                         }
374 #endif
375                         _capture_buf->write(ev.time() + transport_frame, ev.type(), ev.size(), ev.buffer());
376                 }
377
378                 if (buf.size() != 0) {
379                         Glib::Mutex::Lock lm (_gui_feed_buffer_mutex, Glib::TRY_LOCK);
380
381                         if (lm.locked ()) {
382                                 /* Copy this data into our GUI feed buffer and tell the GUI
383                                    that it can read it if it likes.
384                                 */
385                                 _gui_feed_buffer.clear ();
386                                 
387                                 for (MidiBuffer::iterator i = buf.begin(); i != buf.end(); ++i) {
388                                         /* This may fail if buf is larger than _gui_feed_buffer, but it's not really
389                                            the end of the world if it does.
390                                         */
391                                         _gui_feed_buffer.push_back ((*i).time() + transport_frame, (*i).size(), (*i).buffer());
392                                 }
393                         }
394
395                         DataRecorded (_write_source); /* EMIT SIGNAL */
396                 }
397
398         } else {
399
400                 if (was_recording) {
401                         finish_capture ();
402                 }
403
404         }
405
406         if (rec_nframes) {
407
408                 /* data will be written to disk */
409
410                 if (rec_nframes == nframes && rec_offset == 0) {
411                         playback_distance = nframes;
412                 }
413
414                 adjust_capture_position = rec_nframes;
415
416         } else if (nominally_recording) {
417
418                 /* XXXX do this for MIDI !!!
419                    can't do actual capture yet - waiting for latency effects to finish before we start
420                    */
421
422                 playback_distance = nframes;
423
424         } else {
425
426                 /* XXX: should be doing varispeed stuff here, similar to the code in AudioDiskstream::process */
427
428                 playback_distance = nframes;
429
430         }
431
432         return 0;
433 }
434
435 bool
436 MidiDiskstream::commit (framecnt_t playback_distance)
437 {
438         bool need_butler = false;
439
440         if (_actual_speed < 0.0) {
441                 playback_sample -= playback_distance;
442         } else {
443                 playback_sample += playback_distance;
444         }
445
446         if (adjust_capture_position != 0) {
447                 capture_captured += adjust_capture_position;
448                 adjust_capture_position = 0;
449         }
450
451         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
452         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
453
454         /*
455           cerr << name() << " MDS written: " << frames_written << " - read: " << frames_read <<
456           " = " << frames_written - frames_read
457           << " + " << playback_distance << " < " << midi_readahead << " = " << need_butler << ")" << endl;
458         */
459
460         /* frames_read will generally be less than frames_written, but
461          * immediately after an overwrite, we can end up having read some data
462          * before we've written any. we don't need to trip an assert() on this,
463          * but we do need to check so that the decision on whether or not we
464          * need the butler is done correctly.
465          */
466         
467         if (frames_read <= frames_written) {
468                 if ((frames_written - frames_read) + playback_distance < midi_readahead) {
469                         need_butler = true;
470                 }
471         }
472
473
474         return need_butler;
475 }
476
477 void
478 MidiDiskstream::set_pending_overwrite (bool yn)
479 {
480         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
481
482         _pending_overwrite = yn;
483         overwrite_frame = playback_sample;
484 }
485
486 int
487 MidiDiskstream::overwrite_existing_buffers ()
488 {
489         /* This is safe as long as the butler thread is suspended, which it should be */
490         _playback_buf->reset ();
491
492         g_atomic_int_set (&_frames_read_from_ringbuffer, 0);
493         g_atomic_int_set (&_frames_written_to_ringbuffer, 0);
494
495         read (overwrite_frame, disk_io_chunk_frames, false);
496         file_frame = overwrite_frame; // it was adjusted by ::read()
497         overwrite_queued = false;
498         _pending_overwrite = false;
499
500         return 0;
501 }
502
503 int
504 MidiDiskstream::seek (framepos_t frame, bool complete_refill)
505 {
506         Glib::Mutex::Lock lm (state_lock);
507         int ret = -1;
508
509         if (g_atomic_int_get (&_frames_read_from_ringbuffer) == 0) {
510                 /* we haven't read anything since the last seek,
511                    so flush all note trackers to prevent
512                    wierdness
513                 */
514                 reset_tracker ();
515         }
516
517         _playback_buf->reset();
518         _capture_buf->reset();
519         g_atomic_int_set(&_frames_read_from_ringbuffer, 0);
520         g_atomic_int_set(&_frames_written_to_ringbuffer, 0);
521
522         playback_sample = frame;
523         file_frame = frame;
524
525         if (complete_refill) {
526                 while ((ret = do_refill_with_alloc ()) > 0) ;
527         } else {
528                 ret = do_refill_with_alloc ();
529         }
530
531         return ret;
532 }
533
534 int
535 MidiDiskstream::can_internal_playback_seek (framecnt_t distance)
536 {
537         uint32_t frames_read    = g_atomic_int_get(&_frames_read_from_ringbuffer);
538         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
539         return ((frames_written - frames_read) < distance);
540 }
541
542 int
543 MidiDiskstream::internal_playback_seek (framecnt_t distance)
544 {
545         first_recordable_frame += distance;
546         playback_sample += distance;
547
548         return 0;
549 }
550
551 /** @a start is set to the new frame position (TIME) read up to */
552 int
553 MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
554 {
555         framecnt_t this_read = 0;
556         bool reloop = false;
557         framepos_t loop_end = 0;
558         framepos_t loop_start = 0;
559         Location *loc = 0;
560
561         if (!reversed) {
562
563                 framecnt_t loop_length = 0;
564
565                 /* Make the use of a Location atomic for this read operation.
566
567                    Note: Locations don't get deleted, so all we care about
568                    when I say "atomic" is that we are always pointing to
569                    the same one and using a start/length values obtained
570                    just once.
571                 */
572
573                 if ((loc = loop_location) != 0) {
574                         loop_start = loc->start();
575                         loop_end = loc->end();
576                         loop_length = loop_end - loop_start;
577                 }
578
579                 /* if we are looping, ensure that the first frame we read is at the correct
580                    position within the loop.
581                 */
582
583                 if (loc && (start >= loop_end)) {
584                         //cerr << "start adjusted from " << start;
585                         start = loop_start + ((start - loop_start) % loop_length);
586                         //cerr << "to " << start << endl;
587                 }
588                 // cerr << "start is " << start << " end " << start+dur << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
589         }
590
591         while (dur) {
592
593                 /* take any loop into account. we can't read past the end of the loop. */
594
595                 if (loc && (loop_end - start <= dur)) {
596                         this_read = loop_end - start;
597                         // cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
598                         reloop = true;
599                 } else {
600                         reloop = false;
601                         this_read = dur;
602                 }
603
604                 if (this_read == 0) {
605                         break;
606                 }
607
608                 this_read = min(dur,this_read);
609
610                 if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) {
611                         error << string_compose(
612                                         _("MidiDiskstream %1: cannot read %2 from playlist at frame %3"),
613                                         id(), this_read, start) << endmsg;
614                         return -1;
615                 }
616
617                 g_atomic_int_add (&_frames_written_to_ringbuffer, this_read);
618
619                 if (reversed) {
620
621                         // Swap note ons with note offs here.  etc?
622                         // Fully reversing MIDI requires look-ahead (well, behind) to find previous
623                         // CC values etc.  hard.
624
625                 } else {
626
627                         /* if we read to the end of the loop, go back to the beginning */
628
629                         if (reloop) {
630                                 // Synthesize LoopEvent here, because the next events
631                                 // written will have non-monotonic timestamps.
632                                 _playback_buf->write(loop_end - 1, LoopEventType, sizeof (framepos_t), (uint8_t *) &loop_start);
633                                 start = loop_start;
634                         } else {
635                                 start += this_read;
636                         }
637                 }
638
639                 dur -= this_read;
640                 //offset += this_read;
641         }
642
643         return 0;
644 }
645
646 int
647 MidiDiskstream::do_refill_with_alloc ()
648 {
649         return do_refill();
650 }
651
652 int
653 MidiDiskstream::do_refill ()
654 {
655         int     ret         = 0;
656         size_t  write_space = _playback_buf->write_space();
657         bool    reversed    = (_visible_speed * _session.transport_speed()) < 0.0f;
658
659         if (write_space == 0) {
660                 return 0;
661         }
662
663         if (reversed) {
664                 return 0;
665         }
666
667         /* at end: nothing to do */
668         if (file_frame == max_framepos) {
669                 return 0;
670         }
671
672         // At this point we...
673         assert(_playback_buf->write_space() > 0); // ... have something to write to, and
674         assert(file_frame <= max_framepos); // ... something to write
675
676         // now calculate how much time is in the ringbuffer.
677         // and lets write as much as we need to get this to be midi_readahead;
678         uint32_t frames_read = g_atomic_int_get(&_frames_read_from_ringbuffer);
679         uint32_t frames_written = g_atomic_int_get(&_frames_written_to_ringbuffer);
680         if ((frames_written - frames_read) >= midi_readahead) {
681                 return 0;
682         }
683
684         framecnt_t to_read = midi_readahead - (frames_written - frames_read);
685
686         //cout << "MDS read for midi_readahead " << to_read << "  rb_contains: "
687         //      << frames_written - frames_read << endl;
688
689         to_read = (framecnt_t) min ((framecnt_t) to_read, (framecnt_t) (max_framepos - file_frame));
690
691         if (read (file_frame, to_read, reversed)) {
692                 ret = -1;
693         }
694
695         return ret;
696 }
697
698 /** Flush pending data to disk.
699  *
700  * Important note: this function will write *AT MOST* disk_io_chunk_frames
701  * of data to disk. it will never write more than that.  If it writes that
702  * much and there is more than that waiting to be written, it will return 1,
703  * otherwise 0 on success or -1 on failure.
704  *
705  * If there is less than disk_io_chunk_frames to be written, no data will be
706  * written at all unless @a force_flush is true.
707  */
708 int
709 MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
710 {
711         framecnt_t to_write;
712         framecnt_t total;
713         int32_t ret = 0;
714
715         if (!_write_source) {
716                 return 0;
717         }
718
719         assert (!destructive());
720
721         total = _session.transport_frame() - _write_source->last_write_end();
722
723         if (total == 0 || 
724             _capture_buf->read_space() == 0 || 
725             (!force_flush && (total < disk_io_chunk_frames) && was_recording)) {
726                 goto out;
727         }
728
729         /* if there are 2+ chunks of disk i/o possible for
730            this track, let the caller know so that it can arrange
731            for us to be called again, ASAP.
732
733            if we are forcing a flush, then if there is* any* extra
734            work, let the caller know.
735
736            if we are no longer recording and there is any extra work,
737            let the caller know too.
738            */
739
740         if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
741                 ret = 1;
742         }
743
744         if (force_flush) {
745                 /* push out everything we have, right now */
746                 to_write = max_framecnt;
747         } else {
748                 to_write = disk_io_chunk_frames;
749         }
750
751         if (record_enabled() && ((total > disk_io_chunk_frames) || force_flush)) {
752                 if (_write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
753                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
754                         return -1;
755                 } 
756         }
757
758 out:
759         return ret;
760 }
761
762 void
763 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
764 {
765         bool more_work = true;
766         int err = 0;
767         boost::shared_ptr<MidiRegion> region;
768         MidiRegion::SourceList srcs;
769         MidiRegion::SourceList::iterator src;
770         vector<CaptureInfo*>::iterator ci;
771
772         finish_capture ();
773
774         /* butler is already stopped, but there may be work to do
775            to flush remaining data to disk.
776            */
777
778         while (more_work && !err) {
779                 switch (do_flush (TransportContext, true)) {
780                 case 0:
781                         more_work = false;
782                         break;
783                 case 1:
784                         break;
785                 case -1:
786                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
787                         err++;
788                 }
789         }
790
791         /* XXX is there anything we can do if err != 0 ? */
792         Glib::Mutex::Lock lm (capture_info_lock);
793
794         if (capture_info.empty()) {
795                 goto no_capture_stuff_to_do;
796         }
797
798         if (abort_capture) {
799
800                 if (_write_source) {
801                         _write_source->mark_for_remove ();
802                         _write_source->drop_references ();
803                         _write_source.reset();
804                 }
805
806                 /* new source set up in "out" below */
807
808         } else {
809
810                 assert(_write_source);
811
812                 framecnt_t total_capture = 0;
813                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
814                         total_capture += (*ci)->frames;
815                 }
816
817                 if (_write_source->length (capture_info.front()->start) != 0) {
818
819                         /* phew, we have data */
820
821                         /* figure out the name for this take */
822
823                         srcs.push_back (_write_source);
824
825                         _write_source->set_timeline_position (capture_info.front()->start);
826                         _write_source->set_captured_for (_name);
827
828                         /* set length in beats to entire capture length */
829
830                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
831                         const double total_capture_beats = converter.from (total_capture);
832                         _write_source->set_length_beats (total_capture_beats);
833
834                         /* flush to disk: this step differs from the audio path,
835                            where all the data is already on disk.
836                         */
837
838                         _write_source->mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::MusicalTime>::ResolveStuckNotes, total_capture_beats);
839
840                         /* we will want to be able to keep (over)writing the source
841                            but we don't want it to be removable. this also differs
842                            from the audio situation, where the source at this point
843                            must be considered immutable. luckily, we can rely on
844                            MidiSource::mark_streaming_write_completed() to have
845                            already done the necessary work for that.
846                         */
847
848                         string whole_file_region_name;
849                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
850
851                         /* Register a new region with the Session that
852                            describes the entire source. Do this first
853                            so that any sub-regions will obviously be
854                            children of this one (later!)
855                         */
856
857                         try {
858                                 PropertyList plist;
859
860                                 plist.add (Properties::name, whole_file_region_name);
861                                 plist.add (Properties::whole_file, true);
862                                 plist.add (Properties::automatic, true);
863                                 plist.add (Properties::start, 0);
864                                 plist.add (Properties::length, total_capture);
865                                 plist.add (Properties::layer, 0);
866
867                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
868
869                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
870                                 region->special_set_position (capture_info.front()->start);
871                         }
872
873
874                         catch (failed_constructor& err) {
875                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
876                                 /* XXX what now? */
877                         }
878
879                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
880
881                         _playlist->clear_changes ();
882                         _playlist->freeze ();
883
884                         /* Session frame time of the initial capture in this pass, which is where the source starts */
885                         framepos_t initial_capture = 0;
886                         if (!capture_info.empty()) {
887                                 initial_capture = capture_info.front()->start;
888                         }
889
890                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
891
892                                 string region_name;
893
894                                 RegionFactory::region_name (region_name, _write_source->name(), false);
895
896                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
897
898                                 try {
899                                         PropertyList plist;
900
901                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
902                                         plist.add (Properties::start, (*ci)->start - initial_capture);
903                                         plist.add (Properties::length, (*ci)->frames);
904                                         plist.add (Properties::length_beats, converter.from((*ci)->frames));
905                                         plist.add (Properties::name, region_name);
906
907                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
908                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
909                                 }
910
911                                 catch (failed_constructor& err) {
912                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
913                                         continue; /* XXX is this OK? */
914                                 }
915
916                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
917
918                                 i_am_the_modifier++;
919                                 _playlist->add_region (region, (*ci)->start);
920                                 i_am_the_modifier--;
921                         }
922
923                         _playlist->thaw ();
924                         _session.add_command (new StatefulDiffCommand(_playlist));
925
926                 } else {
927
928                         /* No data was recorded, so this capture will
929                            effectively be aborted; do the same as we
930                            do for an explicit abort.
931                         */
932
933                         if (_write_source) {
934                                 _write_source->mark_for_remove ();
935                                 _write_source->drop_references ();
936                                 _write_source.reset();
937                         }
938                 }
939
940         }
941
942         use_new_write_source (0);
943
944         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
945                 delete *ci;
946         }
947
948         capture_info.clear ();
949         capture_start_frame = 0;
950
951   no_capture_stuff_to_do:
952
953         reset_tracker ();
954 }
955
956 void
957 MidiDiskstream::transport_looped (framepos_t transport_frame)
958 {
959         if (was_recording) {
960
961                 // adjust the capture length knowing that the data will be recorded to disk
962                 // only necessary after the first loop where we're recording
963                 if (capture_info.size() == 0) {
964                         capture_captured += _capture_offset;
965
966                         if (_alignment_style == ExistingMaterial) {
967                                 capture_captured += _session.worst_output_latency();
968                         } else {
969                                 capture_captured += _roll_delay;
970                         }
971                 }
972
973                 finish_capture ();
974
975                 // the next region will start recording via the normal mechanism
976                 // we'll set the start position to the current transport pos
977                 // no latency adjustment or capture offset needs to be made, as that already happened the first time
978                 capture_start_frame = transport_frame;
979                 first_recordable_frame = transport_frame; // mild lie
980                 last_recordable_frame = max_framepos;
981                 was_recording = true;
982         }
983
984         if (!Config->get_seamless_loop()) {
985                 reset_tracker ();
986         }
987 }
988
989 void
990 MidiDiskstream::finish_capture ()
991 {
992         was_recording = false;
993
994         if (capture_captured == 0) {
995                 return;
996         }
997
998         // Why must we destroy?
999         assert(!destructive());
1000
1001         CaptureInfo* ci = new CaptureInfo;
1002
1003         ci->start  = capture_start_frame;
1004         ci->frames = capture_captured;
1005
1006         /* XXX theoretical race condition here. Need atomic exchange ?
1007            However, the circumstances when this is called right
1008            now (either on record-disable or transport_stopped)
1009            mean that no actual race exists. I think ...
1010            We now have a capture_info_lock, but it is only to be used
1011            to synchronize in the transport_stop and the capture info
1012            accessors, so that invalidation will not occur (both non-realtime).
1013         */
1014
1015         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1016
1017         capture_info.push_back (ci);
1018         capture_captured = 0;
1019 }
1020
1021 void
1022 MidiDiskstream::set_record_enabled (bool yn)
1023 {
1024         if (!recordable() || !_session.record_enabling_legal()) {
1025                 return;
1026         }
1027
1028         assert(!destructive());
1029
1030         /* yes, i know that this not proof against race conditions, but its
1031            good enough. i think.
1032         */
1033
1034         if (record_enabled() != yn) {
1035                 if (yn) {
1036                         engage_record_enable ();
1037                 } else {
1038                         disengage_record_enable ();
1039                 }
1040         }
1041 }
1042
1043 void
1044 MidiDiskstream::engage_record_enable ()
1045 {
1046         bool const rolling = _session.transport_speed() != 0.0f;
1047
1048         g_atomic_int_set (&_record_enabled, 1);
1049
1050         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1051         
1052         if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
1053                 sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
1054         }
1055
1056         RecordEnableChanged (); /* EMIT SIGNAL */
1057 }
1058
1059 void
1060 MidiDiskstream::disengage_record_enable ()
1061 {
1062         g_atomic_int_set (&_record_enabled, 0);
1063         RecordEnableChanged (); /* EMIT SIGNAL */
1064 }
1065
1066 XMLNode&
1067 MidiDiskstream::get_state ()
1068 {
1069         XMLNode& node (Diskstream::get_state());
1070         char buf[64];
1071         LocaleGuard lg (X_("POSIX"));
1072
1073         node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1074         snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1075         node.add_property("channel-mask", buf);
1076
1077         if (_write_source && _session.get_record_enabled()) {
1078
1079                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1080                 XMLNode* cs_grandchild;
1081
1082                 cs_grandchild = new XMLNode (X_("file"));
1083                 cs_grandchild->add_property (X_("path"), _write_source->path());
1084                 cs_child->add_child_nocopy (*cs_grandchild);
1085
1086                 /* store the location where capture will start */
1087
1088                 Location* pi;
1089
1090                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1091                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1092                 } else {
1093                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1094                 }
1095
1096                 cs_child->add_property (X_("at"), buf);
1097                 node.add_child_nocopy (*cs_child);
1098         }
1099
1100         return node;
1101 }
1102
1103 int
1104 MidiDiskstream::set_state (const XMLNode& node, int version)
1105 {
1106         const XMLProperty* prop;
1107         XMLNodeList nlist = node.children();
1108         XMLNodeIterator niter;
1109         XMLNode* capture_pending_node = 0;
1110         LocaleGuard lg (X_("POSIX"));
1111
1112         /* prevent write sources from being created */
1113
1114         in_set_state = true;
1115
1116         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1117                 assert ((*niter)->name() != IO::state_node_name);
1118
1119                 if ((*niter)->name() == X_("CapturingSources")) {
1120                         capture_pending_node = *niter;
1121                 }
1122         }
1123
1124         if (Diskstream::set_state (node, version)) {
1125                 return -1;
1126         }
1127
1128         ChannelMode channel_mode = AllChannels;
1129         if ((prop = node.property ("channel-mode")) != 0) {
1130                 channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
1131         }
1132
1133         unsigned int channel_mask = 0xFFFF;
1134         if ((prop = node.property ("channel-mask")) != 0) {
1135                 sscanf (prop->value().c_str(), "0x%x", &channel_mask);
1136                 if (channel_mask & (~0xFFFF)) {
1137                         warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
1138                 }
1139         }
1140
1141
1142         if (capture_pending_node) {
1143                 use_pending_capture_data (*capture_pending_node);
1144         }
1145
1146         set_channel_mode (channel_mode, channel_mask);
1147
1148         in_set_state = false;
1149
1150         return 0;
1151 }
1152
1153 int
1154 MidiDiskstream::use_new_write_source (uint32_t n)
1155 {
1156         if (!_session.writable() || !recordable()) {
1157                 return 1;
1158         }
1159
1160         assert(n == 0);
1161
1162         _write_source.reset();
1163
1164         try {
1165                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1166                         _session.create_midi_source_for_session (0, name ()));
1167
1168                 if (!_write_source) {
1169                         throw failed_constructor();
1170                 }
1171         }
1172
1173         catch (failed_constructor &err) {
1174                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1175                 _write_source.reset();
1176                 return -1;
1177         }
1178
1179         return 0;
1180 }
1181
1182 list<boost::shared_ptr<Source> >
1183 MidiDiskstream::steal_write_sources()
1184 {
1185         list<boost::shared_ptr<Source> > ret;
1186
1187         /* put some data on the disk, even if its just a header for an empty file */
1188         boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1189
1190         /* never let it go away */
1191         _write_source->mark_nonremovable ();
1192
1193         ret.push_back (_write_source);
1194
1195         /* get a new one */
1196
1197         use_new_write_source (0);
1198
1199         return ret;
1200 }
1201
1202 void
1203 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1204 {
1205         if (!_session.writable() || !recordable()) {
1206                 return;
1207         }
1208
1209         if (_write_source && mark_write_complete) {
1210                 _write_source->mark_streaming_write_completed ();
1211         }
1212         use_new_write_source (0);
1213 }
1214
1215 void
1216 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1217 {
1218 }
1219
1220 void
1221 MidiDiskstream::allocate_temporary_buffers ()
1222 {
1223 }
1224
1225 void
1226 MidiDiskstream::ensure_jack_monitors_input (bool yn)
1227 {
1228         boost::shared_ptr<MidiPort> sp = _source_port.lock ();
1229         
1230         if (sp) {
1231                 sp->ensure_jack_monitors_input (yn);
1232         }
1233 }
1234
1235 void
1236 MidiDiskstream::set_align_style_from_io ()
1237 {
1238         if (_alignment_choice != Automatic) {
1239                 return;
1240         }
1241
1242         /* XXX Not sure what, if anything we can do with MIDI
1243            as far as capture alignment etc.
1244         */
1245
1246         set_align_style (ExistingMaterial);
1247 }
1248
1249
1250 float
1251 MidiDiskstream::playback_buffer_load () const
1252 {
1253         /* For MIDI it's not trivial to differentiate the following two cases:
1254            
1255            1.  The playback buffer is empty because the system has run out of time to fill it.
1256            2.  The playback buffer is empty because there is no more data on the playlist.
1257
1258            If we use a simple buffer load computation, we will report that the MIDI diskstream
1259            cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
1260            are so low compared to audio, just give a pretend answer here.
1261         */
1262         
1263         return 1;
1264 }
1265
1266 float
1267 MidiDiskstream::capture_buffer_load () const
1268 {
1269         /* We don't report playback buffer load, so don't report capture load either */
1270         
1271         return 1;
1272 }
1273
1274 int
1275 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1276 {
1277         return 0;
1278 }
1279
1280 void
1281 MidiDiskstream::flush_playback (framepos_t start, framepos_t end)
1282 {
1283         _playback_buf->flush (start, end);
1284         g_atomic_int_add (&_frames_read_from_ringbuffer, end - start);
1285 }
1286
1287 /** Writes playback events from playback_sample for nframes to dst, translating time stamps
1288  *  so that an event at playback_sample has time = 0
1289  */
1290 void
1291 MidiDiskstream::get_playback (MidiBuffer& dst, framecnt_t nframes)
1292 {
1293         dst.clear();
1294         assert(dst.size() == 0);
1295
1296 #ifndef NDEBUG
1297         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1298                              "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
1299                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), playback_sample, playback_sample + nframes));
1300 //        cerr << "================\n";
1301 //        _playback_buf->dump (cerr);
1302 //        cerr << "----------------\n";
1303
1304         const size_t events_read = _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1305         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1306                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1307                              _name, events_read, playback_sample, playback_sample + nframes,
1308                              _playback_buf->read_space(), _playback_buf->write_space(),
1309                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1310 #else
1311         _playback_buf->read (dst, playback_sample, playback_sample + nframes);
1312 #endif
1313
1314         g_atomic_int_add (&_frames_read_from_ringbuffer, nframes);
1315 }
1316
1317 bool
1318 MidiDiskstream::set_name (string const & name)
1319 {
1320         Diskstream::set_name (name);
1321
1322         /* get a new write source so that its name reflects the new diskstream name */
1323         use_new_write_source (0);
1324
1325         return true;
1326 }
1327
1328 boost::shared_ptr<MidiBuffer>
1329 MidiDiskstream::get_gui_feed_buffer () const
1330 {
1331         boost::shared_ptr<MidiBuffer> b (new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI)));
1332         
1333         Glib::Mutex::Lock lm (_gui_feed_buffer_mutex);
1334         b->copy (_gui_feed_buffer);
1335         return b;
1336 }
1337
1338 void
1339 MidiDiskstream::reset_tracker ()
1340 {
1341         _playback_buf->reset_tracker ();
1342
1343         boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
1344
1345         if (mp) {
1346                 mp->clear_note_trackers ();
1347         }
1348 }