MIDI IO 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         seek (position, false);
150 }
151
152
153 void
154 MidiDiskstream::non_realtime_input_change ()
155 {
156         {
157                 Glib::Mutex::Lock lm (state_lock);
158
159                 if (input_change_pending.type == IOChange::NoChange) {
160                         return;
161                 }
162
163                 if (input_change_pending.type & IOChange::ConfigurationChanged) {
164                         uint32_t ni = _io->n_ports().n_midi();
165
166                         if (ni != _n_channels.n_midi()) {
167                                 error << string_compose (_("%1: I/O configuration change %4 requested to use %2, but channel setup is %3"),
168                                                          name(),
169                                                          _io->n_ports(),
170                                                          _n_channels, input_change_pending.type)
171                                       << endmsg;
172                         }
173
174                         if (ni == 0) {
175                                 _source_port = 0;
176                         } else {
177                                 _source_port = _io->midi(0);
178                         }
179                 }
180
181                 if (input_change_pending.type & IOChange::ConnectionsChanged) {
182                         set_capture_offset ();
183                         set_align_style_from_io ();
184                 }
185
186                 input_change_pending.type = IOChange::NoChange;
187
188                 /* implicit unlock */
189         }
190
191         /* unlike with audio, there is never any need to reset write sources
192            based on input configuration changes because ... a MIDI track
193            has just 1 MIDI port as input, always.
194         */
195
196         /* now refill channel buffers */
197
198         if (speed() != 1.0f || speed() != -1.0f) {
199                 seek ((framepos_t) (_session.transport_frame() * (double) speed()));
200         }
201         else {
202                 seek (_session.transport_frame());
203         }
204
205         _last_flush_frame = _session.transport_frame();
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         uint32_t to_write;
864         int32_t ret = 0;
865         framecnt_t total;
866
867         cerr << name() << " flushing to disk\n";
868
869         _write_data_count = 0;
870
871         total = _session.transport_frame() - _last_flush_frame;
872
873         if (_last_flush_frame > _session.transport_frame() || _last_flush_frame < capture_start_frame) {
874                 _last_flush_frame = _session.transport_frame();
875         }
876
877         if (total == 0 || _capture_buf->read_space() == 0
878                         || (!force_flush && (total < disk_io_chunk_frames && was_recording))) {
879                 cerr << "\tFlush shortcut because total = " << total
880                      << " capture read space = " << _capture_buf->read_space()
881                      << " force flush = " << force_flush 
882                      << " was recording = " << was_recording
883                      << endl;
884                 goto out;
885         }
886
887         /* if there are 2+ chunks of disk i/o possible for
888            this track, let the caller know so that it can arrange
889            for us to be called again, ASAP.
890
891            if we are forcing a flush, then if there is* any* extra
892            work, let the caller know.
893
894            if we are no longer recording and there is any extra work,
895            let the caller know too.
896            */
897
898         if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
899                 ret = 1;
900         }
901
902         to_write = disk_io_chunk_frames;
903
904         assert(!destructive());
905
906         if (record_enabled() &&
907             ((_session.transport_frame() - _last_flush_frame > disk_io_chunk_frames) ||
908              force_flush)) {
909                 if ((!_write_source) || _write_source->midi_write (*_capture_buf, get_capture_start_frame (0), to_write) != to_write) {
910                         error << string_compose(_("MidiDiskstream %1: cannot write to disk"), _id) << endmsg;
911                         return -1;
912                 } else {
913                         _last_flush_frame = _session.transport_frame();
914                 }
915         } else {
916                 cerr << "\tdidn't write to disk because recenabled = " << record_enabled()
917                      << " last flush @ " << _last_flush_frame << " disk io " << disk_io_chunk_frames << " TF @ " << _session.transport_frame()
918                      << " force = " << force_flush << endl;
919         }
920
921 out:
922         return ret;
923 }
924
925 void
926 MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen*/, bool abort_capture)
927 {
928         bool more_work = true;
929         int err = 0;
930         boost::shared_ptr<MidiRegion> region;
931         MidiRegion::SourceList srcs;
932         MidiRegion::SourceList::iterator src;
933         vector<CaptureInfo*>::iterator ci;
934
935         finish_capture (true);
936
937         /* butler is already stopped, but there may be work to do
938            to flush remaining data to disk.
939            */
940
941         while (more_work && !err) {
942                 switch (do_flush (TransportContext, true)) {
943                 case 0:
944                         more_work = false;
945                         break;
946                 case 1:
947                         break;
948                 case -1:
949                         error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
950                         err++;
951                 }
952         }
953
954         /* XXX is there anything we can do if err != 0 ? */
955         Glib::Mutex::Lock lm (capture_info_lock);
956
957         if (capture_info.empty()) {
958                 return;
959         }
960
961         if (abort_capture) {
962
963                 if (_write_source) {
964                         _write_source->mark_for_remove ();
965                         _write_source->drop_references ();
966                         _write_source.reset();
967                 }
968
969                 /* new source set up in "out" below */
970
971         } else {
972
973                 assert(_write_source);
974
975                 framecnt_t total_capture = 0;
976                 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
977                         total_capture += (*ci)->frames;
978                 }
979
980                 if (_write_source->length (capture_info.front()->start) != 0) {
981
982                         /* phew, we have data */
983
984                         /* figure out the name for this take */
985
986                         srcs.push_back (_write_source);
987
988                         _write_source->set_timeline_position (capture_info.front()->start);
989                         _write_source->set_captured_for (_name);
990
991                         /* flush to disk: this step differs from the audio path,
992                            where all the data is already on disk.
993                         */
994
995                         _write_source->mark_streaming_write_completed ();
996
997                         /* set length in beats to entire capture length */
998
999                         BeatsFramesConverter converter (_session.tempo_map(), capture_info.front()->start);
1000                         const double total_capture_beats = converter.from(total_capture);
1001                         _write_source->set_length_beats(total_capture_beats);
1002
1003                         /* we will want to be able to keep (over)writing the source
1004                            but we don't want it to be removable. this also differs
1005                            from the audio situation, where the source at this point
1006                            must be considered immutable. luckily, we can rely on
1007                            MidiSource::mark_streaming_write_completed() to have
1008                            already done the necessary work for that.
1009                         */
1010
1011                         string whole_file_region_name;
1012                         whole_file_region_name = region_name_from_path (_write_source->name(), true);
1013
1014                         /* Register a new region with the Session that
1015                            describes the entire source. Do this first
1016                            so that any sub-regions will obviously be
1017                            children of this one (later!)
1018                         */
1019
1020                         try {
1021                                 PropertyList plist;
1022
1023                                 plist.add (Properties::name, whole_file_region_name);
1024                                 plist.add (Properties::whole_file, true);
1025                                 plist.add (Properties::automatic, true);
1026                                 plist.add (Properties::start, 0);
1027                                 plist.add (Properties::length, total_capture);
1028                                 plist.add (Properties::layer, 0);
1029
1030                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1031
1032                                 region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1033                                 region->special_set_position (capture_info.front()->start);
1034                         }
1035
1036
1037                         catch (failed_constructor& err) {
1038                                 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1039                                 /* XXX what now? */
1040                         }
1041
1042                         _last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
1043
1044                         _playlist->clear_changes ();
1045                         _playlist->freeze ();
1046
1047                         /* Session frame time of the initial capture in this pass, which is where the source starts */
1048                         framepos_t initial_capture = 0;
1049                         if (!capture_info.empty()) {
1050                                 initial_capture = capture_info.front()->start;
1051                         }
1052
1053                         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1054
1055                                 string region_name;
1056
1057                                 RegionFactory::region_name (region_name, _write_source->name(), false);
1058
1059                                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1060
1061                                 try {
1062                                         PropertyList plist;
1063
1064                                         /* start of this region is the offset between the start of its capture and the start of the whole pass */
1065                                         plist.add (Properties::start, (*ci)->start - initial_capture);
1066                                         plist.add (Properties::length, (*ci)->frames);
1067                                         plist.add (Properties::length_beats, converter.from((*ci)->frames));
1068                                         plist.add (Properties::name, region_name);
1069
1070                                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1071                                         region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1072                                 }
1073
1074                                 catch (failed_constructor& err) {
1075                                         error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1076                                         continue; /* XXX is this OK? */
1077                                 }
1078
1079                                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1080
1081                                 i_am_the_modifier++;
1082                                 _playlist->add_region (region, (*ci)->start);
1083                                 i_am_the_modifier--;
1084                         }
1085
1086                         _playlist->thaw ();
1087                         _session.add_command (new StatefulDiffCommand(_playlist));
1088
1089                 } else {
1090
1091                         /* No data was recorded, so this capture will
1092                            effectively be aborted; do the same as we
1093                            do for an explicit abort.
1094                         */
1095
1096                         if (_write_source) {
1097                                 _write_source->mark_for_remove ();
1098                                 _write_source->drop_references ();
1099                                 _write_source.reset();
1100                         }
1101                 }
1102
1103         }
1104
1105         use_new_write_source (0);
1106
1107         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1108                 delete *ci;
1109         }
1110
1111         if (_playlist) {
1112                 midi_playlist()->clear_note_trackers ();
1113         }
1114
1115         capture_info.clear ();
1116         capture_start_frame = 0;
1117 }
1118
1119 void
1120 MidiDiskstream::transport_looped (framepos_t transport_frame)
1121 {
1122         if (was_recording) {
1123
1124                 // adjust the capture length knowing that the data will be recorded to disk
1125                 // only necessary after the first loop where we're recording
1126                 if (capture_info.size() == 0) {
1127                         capture_captured += _capture_offset;
1128
1129                         if (_alignment_style == ExistingMaterial) {
1130                                 capture_captured += _session.worst_output_latency();
1131                         } else {
1132                                 capture_captured += _roll_delay;
1133                         }
1134                 }
1135
1136                 finish_capture (true);
1137
1138                 // the next region will start recording via the normal mechanism
1139                 // we'll set the start position to the current transport pos
1140                 // no latency adjustment or capture offset needs to be made, as that already happened the first time
1141                 capture_start_frame = transport_frame;
1142                 first_recordable_frame = transport_frame; // mild lie
1143                 last_recordable_frame = max_framepos;
1144                 was_recording = true;
1145         }
1146 }
1147
1148 void
1149 MidiDiskstream::finish_capture (bool /*rec_monitors_input*/)
1150 {
1151         was_recording = false;
1152
1153         if (capture_captured == 0) {
1154                 return;
1155         }
1156
1157         // Why must we destroy?
1158         assert(!destructive());
1159
1160         CaptureInfo* ci = new CaptureInfo;
1161
1162         ci->start  = capture_start_frame;
1163         ci->frames = capture_captured;
1164
1165         /* XXX theoretical race condition here. Need atomic exchange ?
1166            However, the circumstances when this is called right
1167            now (either on record-disable or transport_stopped)
1168            mean that no actual race exists. I think ...
1169            We now have a capture_info_lock, but it is only to be used
1170            to synchronize in the transport_stop and the capture info
1171            accessors, so that invalidation will not occur (both non-realtime).
1172         */
1173
1174         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1175
1176         capture_info.push_back (ci);
1177         capture_captured = 0;
1178 }
1179
1180 void
1181 MidiDiskstream::set_record_enabled (bool yn)
1182 {
1183         if (!recordable() || !_session.record_enabling_legal()) {
1184                 return;
1185         }
1186
1187         assert(!destructive());
1188
1189         /* yes, i know that this not proof against race conditions, but its
1190            good enough. i think.
1191         */
1192
1193         if (record_enabled() != yn) {
1194                 if (yn) {
1195                         engage_record_enable ();
1196                 } else {
1197                         disengage_record_enable ();
1198                 }
1199         }
1200 }
1201
1202 void
1203 MidiDiskstream::engage_record_enable ()
1204 {
1205         bool const rolling = _session.transport_speed() != 0.0f;
1206
1207         g_atomic_int_set (&_record_enabled, 1);
1208
1209         if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) {
1210                 _source_port->request_monitor_input (!(_session.config.get_auto_input() && rolling));
1211         }
1212
1213         RecordEnableChanged (); /* EMIT SIGNAL */
1214 }
1215
1216 void
1217 MidiDiskstream::disengage_record_enable ()
1218 {
1219         g_atomic_int_set (&_record_enabled, 0);
1220         RecordEnableChanged (); /* EMIT SIGNAL */
1221 }
1222
1223 XMLNode&
1224 MidiDiskstream::get_state ()
1225 {
1226         XMLNode& node (Diskstream::get_state());
1227         char buf[64];
1228         LocaleGuard lg (X_("POSIX"));
1229
1230         node.add_property("channel-mode", enum_2_string(get_channel_mode()));
1231         snprintf (buf, sizeof(buf), "0x%x", get_channel_mask());
1232         node.add_property("channel-mask", buf);
1233
1234         if (_write_source && _session.get_record_enabled()) {
1235
1236                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1237                 XMLNode* cs_grandchild;
1238
1239                 cs_grandchild = new XMLNode (X_("file"));
1240                 cs_grandchild->add_property (X_("path"), _write_source->path());
1241                 cs_child->add_child_nocopy (*cs_grandchild);
1242
1243                 /* store the location where capture will start */
1244
1245                 Location* pi;
1246
1247                 if (_session.config.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1248                         snprintf (buf, sizeof (buf), "%" PRId64, pi->start());
1249                 } else {
1250                         snprintf (buf, sizeof (buf), "%" PRId64, _session.transport_frame());
1251                 }
1252
1253                 cs_child->add_property (X_("at"), buf);
1254                 node.add_child_nocopy (*cs_child);
1255         }
1256
1257         return node;
1258 }
1259
1260 int
1261 MidiDiskstream::set_state (const XMLNode& node, int version)
1262 {
1263         const XMLProperty* prop;
1264         XMLNodeList nlist = node.children();
1265         XMLNodeIterator niter;
1266         XMLNode* capture_pending_node = 0;
1267         LocaleGuard lg (X_("POSIX"));
1268
1269         /* prevent write sources from being created */
1270
1271         in_set_state = true;
1272
1273         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1274                 assert ((*niter)->name() != IO::state_node_name);
1275
1276                 if ((*niter)->name() == X_("CapturingSources")) {
1277                         capture_pending_node = *niter;
1278                 }
1279         }
1280
1281         if (Diskstream::set_state (node, version)) {
1282                 return -1;
1283         }
1284
1285         ChannelMode channel_mode = AllChannels;
1286         if ((prop = node.property ("channel-mode")) != 0) {
1287                 channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode));
1288         }
1289
1290         unsigned int channel_mask = 0xFFFF;
1291         if ((prop = node.property ("channel-mask")) != 0) {
1292                 sscanf (prop->value().c_str(), "0x%x", &channel_mask);
1293                 if (channel_mask & (~0xFFFF)) {
1294                         warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg;
1295                 }
1296         }
1297
1298
1299         if (capture_pending_node) {
1300                 use_pending_capture_data (*capture_pending_node);
1301         }
1302
1303         set_channel_mode (channel_mode, channel_mask);
1304
1305         in_set_state = false;
1306
1307         return 0;
1308 }
1309
1310 int
1311 MidiDiskstream::use_new_write_source (uint32_t n)
1312 {
1313         if (!_session.writable() || !recordable()) {
1314                 return 1;
1315         }
1316
1317         assert(n == 0);
1318
1319         _write_source.reset();
1320
1321         try {
1322                 _write_source = boost::dynamic_pointer_cast<SMFSource>(
1323                         _session.create_midi_source_for_session (0, name ()));
1324
1325                 if (!_write_source) {
1326                         throw failed_constructor();
1327                 }
1328         }
1329
1330         catch (failed_constructor &err) {
1331                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1332                 _write_source.reset();
1333                 return -1;
1334         }
1335
1336         return 0;
1337 }
1338
1339 list<boost::shared_ptr<Source> >
1340 MidiDiskstream::steal_write_sources()
1341 {
1342         list<boost::shared_ptr<Source> > ret;
1343
1344         /* put some data on the disk, even if its just a header for an empty file */
1345         boost::dynamic_pointer_cast<SMFSource> (_write_source)->ensure_disk_file ();
1346
1347         /* never let it go away */
1348         _write_source->mark_nonremovable ();
1349
1350         ret.push_back (_write_source);
1351
1352         /* get a new one */
1353
1354         use_new_write_source (0);
1355
1356         return ret;
1357 }
1358
1359 void
1360 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
1361 {
1362         if (!_session.writable() || !recordable()) {
1363                 return;
1364         }
1365
1366         if (_write_source && mark_write_complete) {
1367                 _write_source->mark_streaming_write_completed ();
1368         }
1369         use_new_write_source (0);
1370 }
1371
1372 void
1373 MidiDiskstream::set_block_size (pframes_t /*nframes*/)
1374 {
1375 }
1376
1377 void
1378 MidiDiskstream::allocate_temporary_buffers ()
1379 {
1380 }
1381
1382 void
1383 MidiDiskstream::monitor_input (bool yn)
1384 {
1385         if (_source_port)
1386                 _source_port->ensure_monitor_input (yn);
1387 }
1388
1389 void
1390 MidiDiskstream::set_align_style_from_io ()
1391 {
1392         if (_alignment_choice != Automatic) {
1393                 return;
1394         }
1395
1396         /* XXX Not sure what, if anything we can do with MIDI
1397            as far as capture alignment etc.
1398         */
1399
1400         set_align_style (ExistingMaterial);
1401 }
1402
1403
1404 float
1405 MidiDiskstream::playback_buffer_load () const
1406 {
1407         return (float) ((double) _playback_buf->read_space()/
1408                         (double) _playback_buf->capacity());
1409 }
1410
1411 float
1412 MidiDiskstream::capture_buffer_load () const
1413 {
1414         return (float) ((double) _capture_buf->write_space()/
1415                         (double) _capture_buf->capacity());
1416 }
1417
1418 int
1419 MidiDiskstream::use_pending_capture_data (XMLNode& /*node*/)
1420 {
1421         return 0;
1422 }
1423
1424 /** Writes playback events in the given range to \a dst, translating time stamps
1425  * so that an event at \a start has time = 0
1426  */
1427 void
1428 MidiDiskstream::get_playback (MidiBuffer& dst, framepos_t start, framepos_t end)
1429 {
1430         dst.clear();
1431         assert(dst.size() == 0);
1432
1433         // Reverse.  ... We just don't do reverse, ok?  Back off.
1434         if (end <= start) {
1435                 return;
1436         }
1437
1438         // Translate stamps to be relative to start
1439
1440
1441 #ifndef NDEBUG
1442         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1443                              "%1 MDS pre-read read %4..%5 from %2 write to %3\n", _name,
1444                              _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr(), start, end));
1445 //        cerr << "================\n";
1446 //        _playback_buf->dump (cerr);
1447 //        cerr << "----------------\n";
1448
1449         const size_t events_read = _playback_buf->read(dst, start, end);
1450         DEBUG_TRACE (DEBUG::MidiDiskstreamIO, string_compose (
1451                              "%1 MDS events read %2 range %3 .. %4 rspace %5 wspace %6 r@%7 w@%8\n",
1452                              _name, events_read, start, end,
1453                              _playback_buf->read_space(), _playback_buf->write_space(),
1454                          _playback_buf->get_read_ptr(), _playback_buf->get_write_ptr()));
1455 #else
1456         _playback_buf->read(dst, start, end);
1457 #endif
1458
1459         gint32 frames_read = end - start;
1460         g_atomic_int_add(&_frames_read_from_ringbuffer, frames_read);
1461 }
1462
1463 bool
1464 MidiDiskstream::set_name (string const & name)
1465 {
1466         Diskstream::set_name (name);
1467
1468         /* get a new write source so that its name reflects the new diskstream name */
1469         use_new_write_source (0);
1470
1471         return true;
1472 }
1473