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