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