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