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