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