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