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