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