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