86a95a3cc0ccc1fb60f54c820d0b833d9819d110
[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     $Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
19 */
20
21 #include <fstream>
22 #include <cstdio>
23 #include <unistd.h>
24 #include <cmath>
25 #include <cerrno>
26 #include <string>
27 #include <climits>
28 #include <fcntl.h>
29 #include <cstdlib>
30 #include <ctime>
31 #include <sys/stat.h>
32 #include <sys/mman.h>
33
34 #include <pbd/error.h>
35 #include <pbd/basename.h>
36 #include <glibmm/thread.h>
37 #include <pbd/xml++.h>
38 #include <pbd/memento_command.h>
39
40 #include <ardour/ardour.h>
41 #include <ardour/audioengine.h>
42 #include <ardour/midi_diskstream.h>
43 #include <ardour/utils.h>
44 #include <ardour/configuration.h>
45 #include <ardour/smf_source.h>
46 #include <ardour/destructive_filesource.h>
47 #include <ardour/send.h>
48 #include <ardour/midi_playlist.h>
49 #include <ardour/cycle_timer.h>
50 #include <ardour/midi_region.h>
51 #include <ardour/midi_port.h>
52
53 #include "i18n.h"
54 #include <locale.h>
55
56 using namespace std;
57 using namespace ARDOUR;
58 using namespace PBD;
59
60 MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
61         : Diskstream(sess, name, flag)
62         , _playback_buf(0)
63         , _capture_buf(0)
64         , _current_playback_buffer(0)
65         , _current_capture_buffer(0)
66         , _playback_wrap_buffer(0)
67         , _capture_wrap_buffer(0)
68         , _source_port(0)
69         , _write_source(0)
70         , _capture_transition_buf(0)
71 {
72         /* prevent any write sources from being created */
73
74         in_set_state = true;
75
76         init(flag);
77         use_new_playlist ();
78
79         in_set_state = false;
80
81         assert(!destructive());
82         DiskstreamCreated (this); /* EMIT SIGNAL */
83 }
84         
85 MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
86         : Diskstream(sess, node)
87         , _playback_buf(0)
88         , _capture_buf(0)
89         , _current_playback_buffer(0)
90         , _current_capture_buffer(0)
91         , _playback_wrap_buffer(0)
92         , _capture_wrap_buffer(0)
93         , _source_port(0)
94         , _write_source(0)
95         , _capture_transition_buf(0)
96 {
97         in_set_state = true;
98         init (Recordable);
99
100         if (set_state (node)) {
101                 in_set_state = false;
102                 throw failed_constructor();
103         }
104
105         in_set_state = false;
106
107         if (destructive()) {
108                 use_destructive_playlist ();
109         }
110
111         DiskstreamCreated (this); /* EMIT SIGNAL */
112 }
113
114 void
115 MidiDiskstream::init (Diskstream::Flag f)
116 {
117         Diskstream::init(f);
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         _playback_wrap_buffer = new RawMidi[wrap_buffer_size];
128         _capture_wrap_buffer = new RawMidi[wrap_buffer_size];
129         _playback_buf = new RingBufferNPT<RawMidi> (_session.diskstream_buffer_size());
130         _capture_buf = new RingBufferNPT<RawMidi> (_session.diskstream_buffer_size());
131         _capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
132         
133         _n_channels = ChanCount(DataType::MIDI, 1);
134
135         assert(recordable());
136 }
137
138 MidiDiskstream::~MidiDiskstream ()
139 {
140         Glib::Mutex::Lock lm (state_lock);
141 }
142
143 void
144 MidiDiskstream::non_realtime_input_change ()
145 {
146         { 
147                 Glib::Mutex::Lock lm (state_lock);
148
149                 if (input_change_pending == NoChange) {
150                         return;
151                 }
152
153                 if (input_change_pending & ConfigurationChanged) {
154
155                         assert(_io->n_inputs() == _n_channels);
156                 } 
157
158                 get_input_sources ();
159                 set_capture_offset ();
160
161                 if (first_input_change) {
162                         set_align_style (_persistent_alignment_style);
163                         first_input_change = false;
164                 } else {
165                         set_align_style_from_io ();
166                 }
167
168                 input_change_pending = NoChange;
169         }
170
171         /* reset capture files */
172
173         reset_write_sources (false);
174
175         /* now refill channel buffers */
176
177         if (speed() != 1.0f || speed() != -1.0f) {
178                 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
179         }
180         else {
181                 seek (_session.transport_frame());
182         }
183 }
184
185 void
186 MidiDiskstream::get_input_sources ()
187 {
188         uint32_t ni = _io->n_inputs().get(DataType::MIDI);
189
190         if (ni == 0) {
191                 return;
192         }
193
194         // This is all we do for now at least
195         assert(ni == 1);
196
197         _source_port = _io->midi_input(0);
198
199         /* I don't get it....
200         const char **connections = _io->input(0)->get_connections ();
201
202         if (connections == 0 || connections[0] == 0) {
203
204                 if (_source_port) {
205                         // _source_port->disable_metering ();
206                 }
207
208                 _source_port = 0;
209
210         } else {
211                 _source_port = dynamic_cast<MidiPort*>(
212                         _session.engine().get_port_by_name (connections[0]) );
213         }
214
215         if (connections) {
216                 free (connections);
217         }*/
218 }               
219
220 int
221 MidiDiskstream::find_and_use_playlist (const string& name)
222 {
223         Playlist* pl;
224         MidiPlaylist* playlist;
225                 
226         if ((pl = _session.playlist_by_name (name)) == 0) {
227                 playlist = new MidiPlaylist(_session, name);
228                 pl = playlist;
229         }
230
231         if ((playlist = dynamic_cast<MidiPlaylist*> (pl)) == 0) {
232                 error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't a midi playlist"), name) << endmsg;
233                 return -1;
234         }
235
236         return use_playlist (playlist);
237 }
238
239 int
240 MidiDiskstream::use_playlist (Playlist* playlist)
241 {
242         assert(dynamic_cast<MidiPlaylist*>(playlist));
243
244         return Diskstream::use_playlist(playlist);
245 }
246
247 int
248 MidiDiskstream::use_new_playlist ()
249 {
250         string newname;
251         MidiPlaylist* playlist;
252
253         if (!in_set_state && destructive()) {
254                 return 0;
255         }
256
257         if (_playlist) {
258                 newname = Playlist::bump_name (_playlist->name(), _session);
259         } else {
260                 newname = Playlist::bump_name (_name, _session);
261         }
262
263         if ((playlist = new MidiPlaylist (_session, newname, hidden())) != 0) {
264                 playlist->set_orig_diskstream_id (id());
265                 return use_playlist (playlist);
266         } else { 
267                 return -1;
268         }
269 }
270
271 int
272 MidiDiskstream::use_copy_playlist ()
273 {
274         if (destructive()) {
275                 return 0;
276         }
277
278         if (_playlist == 0) {
279                 error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
280                 return -1;
281         }
282
283         string newname;
284         MidiPlaylist* playlist;
285
286         newname = Playlist::bump_name (_playlist->name(), _session);
287         
288         if ((playlist  = new MidiPlaylist (*midi_playlist(), newname)) != 0) {
289                 playlist->set_orig_diskstream_id (id());
290                 return use_playlist (playlist);
291         } else { 
292                 return -1;
293         }
294 }
295
296 /** Overloaded from parent to die horribly
297  */
298 void
299 MidiDiskstream::set_destructive (bool yn)
300 {
301         assert( ! destructive());
302         assert( ! yn);
303 }
304
305 void
306 MidiDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
307 {
308         // FIXME: waaay too much code to duplicate (AudioDiskstream)
309         
310         int possibly_recording;
311         int rolling;
312         int change;
313         const int transport_rolling = 0x4;
314         const int track_rec_enabled = 0x2;
315         const int global_rec_enabled = 0x1;
316
317         /* merge together the 3 factors that affect record status, and compute
318            what has changed.
319         */
320
321         rolling = _session.transport_speed() != 0.0f;
322         possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
323         change = possibly_recording ^ last_possibly_recording;
324
325         if (possibly_recording == last_possibly_recording) {
326                 return;
327         }
328
329         /* change state */
330
331         /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
332
333         if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) || 
334             ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
335                 
336                 /* starting to record: compute first+last frames */
337
338                 first_recordable_frame = transport_frame + _capture_offset;
339                 last_recordable_frame = max_frames;
340                 capture_start_frame = transport_frame;
341
342                 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
343
344                         /* was stopped, now rolling (and recording) */
345
346                         if (_alignment_style == ExistingMaterial) {
347                                 first_recordable_frame += _session.worst_output_latency();
348                         } else {
349                                 first_recordable_frame += _roll_delay;
350                         }
351
352                 } else {
353
354                         /* was rolling, but record state changed */
355
356                         if (_alignment_style == ExistingMaterial) {
357
358
359                                 if (!_session.get_punch_in()) {
360
361                                         /* manual punch in happens at the correct transport frame
362                                            because the user hit a button. but to get alignment correct 
363                                            we have to back up the position of the new region to the 
364                                            appropriate spot given the roll delay.
365                                         */
366
367                                         capture_start_frame -= _roll_delay;
368
369                                         /* XXX paul notes (august 2005): i don't know why
370                                            this is needed.
371                                         */
372
373                                         first_recordable_frame += _capture_offset;
374
375                                 } else {
376
377                                         /* autopunch toggles recording at the precise
378                                            transport frame, and then the DS waits
379                                            to start recording for a time that depends
380                                            on the output latency.
381                                         */
382
383                                         first_recordable_frame += _session.worst_output_latency();
384                                 }
385
386                         } else {
387
388                                 if (_session.get_punch_in()) {
389                                         first_recordable_frame += _roll_delay;
390                                 } else {
391                                         capture_start_frame -= _roll_delay;
392                                 }
393                         }
394                         
395                 }
396
397                 if (_flags & Recordable) {
398                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
399                         _capture_transition_buf->get_write_vector(&transvec);
400
401                         if (transvec.len[0] > 0) {
402                                 transvec.buf[0]->type = CaptureStart;
403                                 transvec.buf[0]->capture_val = capture_start_frame;
404                                 _capture_transition_buf->increment_write_ptr(1);
405                         } else {
406                                 // bad!
407                                 fatal << X_("programming error: capture_transition_buf is full on rec start!  inconceivable!") 
408                                         << endmsg;
409                         }
410                 }
411
412         } else if (!record_enabled() || !can_record) {
413                 
414                 /* stop recording */
415
416                 last_recordable_frame = transport_frame + _capture_offset;
417                 
418                 if (_alignment_style == ExistingMaterial) {
419                         last_recordable_frame += _session.worst_output_latency();
420                 } else {
421                         last_recordable_frame += _roll_delay;
422                 }
423         }
424
425         last_possibly_recording = possibly_recording;
426 }
427
428 int
429 MidiDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
430 {
431         // FIXME: waay too much code to duplicate (AudioDiskstream::process)
432         int            ret = -1;
433         jack_nframes_t rec_offset = 0;
434         jack_nframes_t rec_nframes = 0;
435         bool           nominally_recording;
436         bool           re = record_enabled ();
437         bool           collect_playback = false;
438         
439         _current_capture_buffer = 0;
440         _current_playback_buffer = 0;
441
442         /* if we've already processed the frames corresponding to this call,
443            just return. this allows multiple routes that are taking input
444            from this diskstream to call our ::process() method, but have
445            this stuff only happen once. more commonly, it allows both
446            the AudioTrack that is using this AudioDiskstream *and* the Session
447            to call process() without problems.
448         */
449
450         if (_processed) {
451                 return 0;
452         }
453
454         check_record_status (transport_frame, nframes, can_record);
455
456         nominally_recording = (can_record && re);
457
458         if (nframes == 0) {
459                 _processed = true;
460                 return 0;
461         }
462
463         /* This lock is held until the end of AudioDiskstream::commit, so these two functions
464            must always be called as a pair. The only exception is if this function
465            returns a non-zero value, in which case, ::commit should not be called.
466         */
467
468         // If we can't take the state lock return.
469         if (!state_lock.trylock()) {
470                 return 1;
471         }
472         
473         adjust_capture_position = 0;
474
475         if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
476                 OverlapType ot;
477                 
478                 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
479
480                 switch (ot) {
481                 case OverlapNone:
482                         rec_nframes = 0;
483                         break;
484                         
485                 case OverlapInternal:
486                 /*     ----------    recrange
487                          |---|       transrange
488                 */
489                         rec_nframes = nframes;
490                         rec_offset = 0;
491                         break;
492                         
493                 case OverlapStart:
494                         /*    |--------|    recrange
495                             -----|          transrange
496                         */
497                         rec_nframes = transport_frame + nframes - first_recordable_frame;
498                         if (rec_nframes) {
499                                 rec_offset = first_recordable_frame - transport_frame;
500                         }
501                         break;
502                         
503                 case OverlapEnd:
504                         /*    |--------|    recrange
505                                  |--------  transrange
506                         */
507                         rec_nframes = last_recordable_frame - transport_frame;
508                         rec_offset = 0;
509                         break;
510                         
511                 case OverlapExternal:
512                         /*    |--------|    recrange
513                             --------------  transrange
514                         */
515                         rec_nframes = last_recordable_frame - last_recordable_frame;
516                         rec_offset = first_recordable_frame - transport_frame;
517                         break;
518                 }
519
520                 if (rec_nframes && !was_recording) {
521                         capture_captured = 0;
522                         was_recording = true;
523                 }
524         }
525
526
527         if (can_record && !_last_capture_regions.empty()) {
528                 _last_capture_regions.clear ();
529         }
530
531         if (nominally_recording || rec_nframes) {
532                 _capture_buf->get_write_vector (&_capture_vector);
533
534                 if (rec_nframes <= _capture_vector.len[0]) {
535
536                         _current_capture_buffer = _capture_vector.buf[0];
537
538                         /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
539                            rec_offset
540                            */
541
542                         // FIXME: midi buffer size?
543
544                         // FIXME: reading from a MIDI port is different, can't just memcpy
545                         //memcpy (_current_capture_buffer, _io->input(0)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (RawMidi) * rec_nframes);
546                         assert(_source_port);
547                         
548                         /*for (size_t i=0; i < _source_port->size(); ++i) {
549                                 cerr << "DISKSTREAM GOT EVENT(1) " << i << "!!\n";
550                         }
551
552                         if (_source_port->size() == 0)
553                                 cerr << "No events :/ (1)\n";
554                         */
555
556
557                 } else {
558
559                         jack_nframes_t total = _capture_vector.len[0] + _capture_vector.len[1];
560
561                         if (rec_nframes > total) {
562                                 cerr << "DiskOverrun\n";
563                                 //DiskOverrun (); // FIXME
564                                 goto out;
565                         }
566
567                         // FIXME (see above)
568                         //RawMidi* buf = _io->input (0)->get_buffer (nframes) + offset;
569                         assert(_source_port);
570
571                         /*
572                         for (size_t i=0; i < _source_port->size(); ++i) {
573                                 cerr << "DISKSTREAM GOT EVENT(2) " << i << "!!\n";
574                         }
575                         if (_source_port->size() == 0)
576                                 cerr << "No events :/ (2)\n";
577                         */
578
579                         RawMidi* buf = NULL; // FIXME FIXME FIXME (make it compile)
580                         assert(false);
581                         jack_nframes_t first = _capture_vector.len[0];
582
583                         memcpy (_capture_wrap_buffer, buf, sizeof (RawMidi) * first);
584                         memcpy (_capture_vector.buf[0], buf, sizeof (RawMidi) * first);
585                         memcpy (_capture_wrap_buffer+first, buf + first, sizeof (RawMidi) * (rec_nframes - first));
586                         memcpy (_capture_vector.buf[1], buf + first, sizeof (RawMidi) * (rec_nframes - first));
587
588                         _current_capture_buffer = _capture_wrap_buffer;
589                 }
590         } else {
591
592                 if (was_recording) {
593                         finish_capture (rec_monitors_input);
594                 }
595
596         }
597         
598         if (rec_nframes) {
599                 
600                 // FIXME: filthy hack to fool the GUI into thinking we're doing something
601                 //if (_write_source)
602                 //      _write_source->ViewDataRangeReady (transport_frame, rec_nframes); /* EMIT SIGNAL */
603
604                 /* data will be written to disk */
605
606                 if (rec_nframes == nframes && rec_offset == 0) {
607
608                         _current_playback_buffer = _current_capture_buffer;
609                         playback_distance = nframes;
610
611                 } else {
612
613
614                         /* we can't use the capture buffer as the playback buffer, because
615                            we recorded only a part of the current process' cycle data
616                            for capture.
617                         */
618
619                         collect_playback = true;
620                 }
621
622                 adjust_capture_position = rec_nframes;
623
624         } else if (nominally_recording) {
625
626                 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
627
628                 _current_playback_buffer = _current_capture_buffer;
629
630                 playback_distance = nframes;
631
632         } else {
633
634                 collect_playback = true;
635         }
636
637         if (collect_playback) {
638
639                 /* we're doing playback */
640
641                 jack_nframes_t necessary_samples;
642
643                 /* no varispeed playback if we're recording, because the output .... TBD */
644
645                 if (rec_nframes == 0 && _actual_speed != 1.0f) {
646                         necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
647                 } else {
648                         necessary_samples = nframes;
649                 }
650                 
651                 _playback_buf->get_read_vector (&_playback_vector);
652                 
653                 if (necessary_samples <= _playback_vector.len[0]) {
654
655                         _current_playback_buffer = _playback_vector.buf[0];
656
657                 } else {
658                         jack_nframes_t total = _playback_vector.len[0] + _playback_vector.len[1];
659                         
660                         if (necessary_samples > total) {
661                                 //cerr << "DiskUnderrun\n";
662                                 //DiskUnderrun (); // FIXME
663                                 //goto out;
664                                 
665                         } else {
666                                 
667                                 memcpy (_playback_wrap_buffer, _playback_vector.buf[0],
668                                         _playback_vector.len[0] * sizeof (RawMidi));
669                                 memcpy (_playback_wrap_buffer + _playback_vector.len[0], _playback_vector.buf[1], 
670                                         (necessary_samples - _playback_vector.len[0]) * sizeof (RawMidi));
671                                 
672                                 _current_playback_buffer = _playback_wrap_buffer;
673                         }
674                 }
675
676 #if 0
677                 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
678                         
679                         uint64_t phase = last_phase;
680                         jack_nframes_t i = 0;
681
682                         // Linearly interpolate into the alt buffer
683                         // using 40.24 fixp maths (swh)
684
685                         for (c = channels.begin(); c != channels.end(); ++c) {
686
687                                 float fr;
688                                 ChannelInfo& chan (*c);
689
690                                 i = 0;
691                                 phase = last_phase;
692
693                                 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
694                                         i = phase >> 24;
695                                         fr = (phase & 0xFFFFFF) / 16777216.0f;
696                                         chan.speed_buffer[outsample] = 
697                                                 chan._current_playback_buffer[i] * (1.0f - fr) +
698                                                 chan._current_playback_buffer[i+1] * fr;
699                                         phase += phi;
700                                 }
701                                 
702                                 chan._current_playback_buffer = chan.speed_buffer;
703                         }
704
705                         playback_distance = i + 1;
706                         last_phase = (phase & 0xFFFFFF);
707
708                 } else {
709                         playback_distance = nframes;
710                 }
711 #endif
712
713                 playback_distance = nframes;
714
715         }
716
717         ret = 0;
718
719   out:
720         _processed = true;
721
722         if (ret) {
723
724                 /* we're exiting with failure, so ::commit will not
725                    be called. unlock the state lock.
726                 */
727                 
728                 state_lock.unlock();
729         } 
730
731         return ret;
732
733         _processed = true;
734
735         return 0;
736 }
737
738 bool
739 MidiDiskstream::commit (jack_nframes_t nframes)
740 {
741         bool need_butler = false;
742
743         if (_actual_speed < 0.0) {
744                 playback_sample -= playback_distance;
745         } else {
746                 playback_sample += playback_distance;
747         }
748
749                 _playback_buf->increment_read_ptr (playback_distance);
750                 
751                 if (adjust_capture_position) {
752                         _capture_buf->increment_write_ptr (adjust_capture_position);
753                 }
754         
755         if (adjust_capture_position != 0) {
756                 capture_captured += adjust_capture_position;
757                 adjust_capture_position = 0;
758         }
759         
760         if (_slaved) {
761                 need_butler = _playback_buf->write_space() >= _playback_buf->bufsize() / 2;
762         } else {
763                 need_butler = _playback_buf->write_space() >= disk_io_chunk_frames
764                         || _capture_buf->read_space() >= disk_io_chunk_frames;
765         }
766
767         state_lock.unlock();
768
769         _processed = false;
770
771         return need_butler;
772 }
773
774 void
775 MidiDiskstream::set_pending_overwrite (bool yn)
776 {
777         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
778         
779         pending_overwrite = yn;
780
781         overwrite_frame = playback_sample;
782         //overwrite_offset = channels.front().playback_buf->get_read_ptr();
783 }
784
785 int
786 MidiDiskstream::overwrite_existing_buffers ()
787 {
788         return 0;
789 }
790
791 int
792 MidiDiskstream::seek (jack_nframes_t frame, bool complete_refill)
793 {
794         Glib::Mutex::Lock lm (state_lock);
795         return 0;
796 }
797
798 int
799 MidiDiskstream::can_internal_playback_seek (jack_nframes_t distance)
800 {
801         return 0;
802 }
803
804 int
805 MidiDiskstream::internal_playback_seek (jack_nframes_t distance)
806 {
807         return 0;
808 }
809
810 int
811 MidiDiskstream::read (MidiBuffer& dst, jack_nframes_t& start, jack_nframes_t cnt, bool reversed)
812 {
813         return 0;
814 }
815
816 int
817 MidiDiskstream::do_refill_with_alloc ()
818 {
819         return do_refill();
820 }
821
822 int
823 MidiDiskstream::do_refill ()
824 {
825         // yeah, the data's ready.  promise.
826         return 0;
827 }
828
829 /** Flush pending data to disk.
830  *
831  * Important note: this function will write *AT MOST* disk_io_chunk_frames
832  * of data to disk. it will never write more than that.  If it writes that
833  * much and there is more than that waiting to be written, it will return 1,
834  * otherwise 0 on success or -1 on failure.
835  * 
836  * If there is less than disk_io_chunk_frames to be written, no data will be
837  * written at all unless @a force_flush is true.
838  */
839 int
840 MidiDiskstream::do_flush (Session::RunContext context, bool force_flush)
841 {
842         /* hey, so did you write that data? */
843
844         // oh yeah, you bet.  wrote it good.  honest.
845         
846         return 0;
847 }
848
849 void
850 MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
851 {
852         uint32_t buffer_position;
853         bool more_work = true;
854         int err = 0;
855         MidiRegion* region = 0;
856         jack_nframes_t total_capture;
857         MidiRegion::SourceList srcs;
858         MidiRegion::SourceList::iterator src;
859         vector<CaptureInfo*>::iterator ci;
860         bool mark_write_completed = false;
861
862         finish_capture (true);
863
864         /* butler is already stopped, but there may be work to do 
865            to flush remaining data to disk.
866            */
867
868         while (more_work && !err) {
869                 switch (do_flush (Session::TransportContext, true)) {
870                         case 0:
871                                 more_work = false;
872                                 break;
873                         case 1:
874                                 break;
875                         case -1:
876                                 error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
877                                 err++;
878                 }
879         }
880
881         /* XXX is there anything we can do if err != 0 ? */
882         Glib::Mutex::Lock lm (capture_info_lock);
883
884         if (capture_info.empty()) {
885                 return;
886         }
887
888         if (abort_capture) {
889
890                 list<Source*>* deletion_list = new list<Source*>;
891
892                 if (_write_source) {
893                         _write_source->mark_for_remove ();
894                         _write_source->release ();
895
896                         deletion_list->push_back (_write_source);
897
898                         _write_source = 0;
899                 }
900
901                 /* new source set up in "out" below */
902
903                 if (!deletion_list->empty()) {
904                         DeleteSources (deletion_list);
905                 } else {
906                         delete deletion_list;
907                 }
908
909         } else {
910
911                 assert(_write_source);
912
913                 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
914                         total_capture += (*ci)->frames;
915                 }
916
917                 /* figure out the name for this take */
918
919                 SMFSource* s = _write_source;
920
921                 if (s) {
922
923                         srcs.push_back (s);
924
925                         cerr << "MidiDiskstream: updating source after capture\n";
926                         s->update_header (capture_info.front()->start, when, twhen);
927
928                         s->set_captured_for (_name);
929
930                 }
931
932                 /* Register a new region with the Session that
933                    describes the entire source. Do this first
934                    so that any sub-regions will obviously be
935                    children of this one (later!)
936                    */
937                 try {
938                         assert(_write_source);
939                         region = new MidiRegion (srcs, _write_source->last_capture_start_frame(), total_capture, 
940                                         region_name_from_path (_write_source->name()), 
941                                         0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile));
942
943                         region->special_set_position (capture_info.front()->start);
944                 }
945
946
947                 catch (failed_constructor& err) {
948                         error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
949                         /* XXX what now? */
950                 }
951
952                 _last_capture_regions.push_back (region);
953
954                 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
955
956                 XMLNode &before = _playlist->get_state();
957                 _playlist->freeze ();
958
959                 for (buffer_position = _write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
960
961                         string region_name;
962                         _session.region_name (region_name, _write_source->name(), false);
963
964                         // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
965
966                         try {
967                                 region = new MidiRegion (srcs, buffer_position, (*ci)->frames, region_name);
968                         }
969
970                         catch (failed_constructor& err) {
971                                 error << _("MidiDiskstream: could not create region for captured audio!") << endmsg;
972                                 continue; /* XXX is this OK? */
973                         }
974
975                         _last_capture_regions.push_back (region);
976
977                         // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
978
979                         i_am_the_modifier++;
980                         _playlist->add_region (*region, (*ci)->start);
981                         i_am_the_modifier--;
982
983                         buffer_position += (*ci)->frames;
984                 }
985
986                 _playlist->thaw ();
987                 XMLNode &after = _playlist->get_state();
988                 _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
989
990                 mark_write_completed = true;
991
992                 reset_write_sources (mark_write_completed);
993
994         }
995
996         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
997                 delete *ci;
998         }
999
1000         capture_info.clear ();
1001         capture_start_frame = 0;
1002 }
1003
1004 void
1005 MidiDiskstream::finish_capture (bool rec_monitors_input)
1006 {
1007         was_recording = false;
1008         
1009         if (capture_captured == 0) {
1010                 return;
1011         }
1012
1013         // Why must we destroy?
1014         assert(!destructive());
1015
1016         CaptureInfo* ci = new CaptureInfo;
1017         
1018         ci->start  =  capture_start_frame;
1019         ci->frames = capture_captured;
1020         
1021         /* XXX theoretical race condition here. Need atomic exchange ? 
1022            However, the circumstances when this is called right 
1023            now (either on record-disable or transport_stopped)
1024            mean that no actual race exists. I think ...
1025            We now have a capture_info_lock, but it is only to be used
1026            to synchronize in the transport_stop and the capture info
1027            accessors, so that invalidation will not occur (both non-realtime).
1028         */
1029
1030         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1031
1032         capture_info.push_back (ci);
1033         capture_captured = 0;
1034 }
1035
1036 void
1037 MidiDiskstream::set_record_enabled (bool yn)
1038 {
1039         if (!recordable() || !_session.record_enabling_legal()) {
1040                 return;
1041         }
1042
1043         assert(!destructive());
1044         
1045         if (yn && _source_port == 0) {
1046
1047                 /* pick up connections not initiated *from* the IO object
1048                    we're associated with.
1049                 */
1050
1051                 get_input_sources ();
1052         }
1053
1054         /* yes, i know that this not proof against race conditions, but its
1055            good enough. i think.
1056         */
1057
1058         if (record_enabled() != yn) {
1059                 if (yn) {
1060                         engage_record_enable ();
1061                 } else {
1062                         disengage_record_enable ();
1063                 }
1064         }
1065 }
1066
1067 void
1068 MidiDiskstream::engage_record_enable ()
1069 {
1070     bool rolling = _session.transport_speed() != 0.0f;
1071
1072         g_atomic_int_set (&_record_enabled, 1);
1073         
1074         if (Config->get_use_hardware_monitoring() && _source_port) {
1075                 _source_port->request_monitor_input (!(_session.get_auto_input() && rolling));
1076         }
1077
1078         RecordEnableChanged (); /* EMIT SIGNAL */
1079 }
1080
1081 void
1082 MidiDiskstream::disengage_record_enable ()
1083 {
1084         g_atomic_int_set (&_record_enabled, 0);
1085         if (Config->get_use_hardware_monitoring()) {
1086                 if (_source_port) {
1087                         _source_port->request_monitor_input (false);
1088                 }
1089         }
1090
1091         RecordEnableChanged (); /* EMIT SIGNAL */
1092 }
1093
1094 XMLNode&
1095 MidiDiskstream::get_state ()
1096 {
1097         XMLNode* node = new XMLNode ("MidiDiskstream");
1098         char buf[64];
1099         LocaleGuard lg (X_("POSIX"));
1100
1101         snprintf (buf, sizeof(buf), "0x%x", _flags);
1102         node->add_property ("flags", buf);
1103
1104         node->add_property ("playlist", _playlist->name());
1105         
1106         snprintf (buf, sizeof(buf), "%f", _visible_speed);
1107         node->add_property ("speed", buf);
1108
1109         node->add_property("name", _name);
1110         id().print(buf);
1111         node->add_property("id", buf);
1112
1113         if (_write_source && _session.get_record_enabled()) {
1114
1115                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1116                 XMLNode* cs_grandchild;
1117
1118                 cs_grandchild = new XMLNode (X_("file"));
1119                 cs_grandchild->add_property (X_("path"), _write_source->path());
1120                 cs_child->add_child_nocopy (*cs_grandchild);
1121
1122                 /* store the location where capture will start */
1123
1124                 Location* pi;
1125
1126                 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1127                         snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1128                 } else {
1129                         snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1130                 }
1131
1132                 cs_child->add_property (X_("at"), buf);
1133                 node->add_child_nocopy (*cs_child);
1134         }
1135
1136         if (_extra_xml) {
1137                 node->add_child_copy (*_extra_xml);
1138         }
1139
1140         return* node;
1141 }
1142
1143 int
1144 MidiDiskstream::set_state (const XMLNode& node)
1145 {
1146         const XMLProperty* prop;
1147         XMLNodeList nlist = node.children();
1148         XMLNodeIterator niter;
1149         uint32_t nchans = 1;
1150         XMLNode* capture_pending_node = 0;
1151         LocaleGuard lg (X_("POSIX"));
1152
1153         in_set_state = true;
1154
1155         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1156                 /*if ((*niter)->name() == IO::state_node_name) {
1157                         deprecated_io_node = new XMLNode (**niter);
1158                 }*/
1159                 assert ((*niter)->name() != IO::state_node_name);
1160
1161                 if ((*niter)->name() == X_("CapturingSources")) {
1162                         capture_pending_node = *niter;
1163                 }
1164         }
1165
1166         /* prevent write sources from being created */
1167         
1168         in_set_state = true;
1169         
1170         if ((prop = node.property ("name")) != 0) {
1171                 _name = prop->value();
1172         } 
1173
1174         if ((prop = node.property ("id")) != 0) {
1175                 _id = prop->value ();
1176         }
1177
1178         if ((prop = node.property ("flags")) != 0) {
1179                 _flags = strtol (prop->value().c_str(), 0, 0);
1180         }
1181
1182         if ((prop = node.property ("channels")) != 0) {
1183                 nchans = atoi (prop->value().c_str());
1184         }
1185         
1186         if ((prop = node.property ("playlist")) == 0) {
1187                 return -1;
1188         }
1189
1190         {
1191                 bool had_playlist = (_playlist != 0);
1192         
1193                 if (find_and_use_playlist (prop->value())) {
1194                         return -1;
1195                 }
1196
1197                 if (!had_playlist) {
1198                         _playlist->set_orig_diskstream_id (_id);
1199                 }
1200                 
1201                 if (capture_pending_node) {
1202                         use_pending_capture_data (*capture_pending_node);
1203                 }
1204
1205         }
1206
1207         if ((prop = node.property ("speed")) != 0) {
1208                 double sp = atof (prop->value().c_str());
1209
1210                 if (realtime_set_speed (sp, false)) {
1211                         non_realtime_set_speed ();
1212                 }
1213         }
1214
1215         in_set_state = false;
1216
1217         /* make sure this is clear before we do anything else */
1218
1219         // FIXME?
1220         //_capturing_source = 0;
1221
1222         /* write sources are handled when we handle the input set 
1223            up of the IO that owns this DS (::non_realtime_input_change())
1224         */
1225                 
1226         in_set_state = false;
1227
1228         return 0;
1229 }
1230
1231 int
1232 MidiDiskstream::use_new_write_source (uint32_t n)
1233 {
1234         if (!recordable()) {
1235                 return 1;
1236         }
1237
1238         assert(n == 0);
1239
1240         if (_write_source) {
1241
1242                 if (SMFSource::is_empty (_write_source->path())) {
1243                         _write_source->mark_for_remove ();
1244                         _write_source->release();
1245                         delete _write_source;
1246                 } else {
1247                         _write_source->release();
1248                         _write_source = 0;
1249                 }
1250         }
1251
1252         try {
1253                 _write_source = dynamic_cast<SMFSource*>(_session.create_midi_source_for_session (*this));
1254                 if (!_write_source) {
1255                         throw failed_constructor();
1256                 }
1257         } 
1258
1259         catch (failed_constructor &err) {
1260                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1261                 _write_source = 0;
1262                 return -1;
1263         }
1264
1265         _write_source->use ();
1266         _write_source->set_allow_remove_if_empty (true);
1267
1268         return 0;
1269 }
1270
1271 void
1272 MidiDiskstream::reset_write_sources (bool mark_write_complete, bool force)
1273 {
1274         if (!recordable()) {
1275                 return;
1276         }
1277
1278         if (_write_source && mark_write_complete) {
1279                 _write_source->mark_streaming_write_completed ();
1280         }
1281         use_new_write_source ();
1282         assert(_write_source);
1283 }
1284
1285 int
1286 MidiDiskstream::rename_write_sources ()
1287 {
1288         if (_write_source != 0) {
1289                 _write_source->set_name (_name, destructive());
1290                 /* XXX what to do if this fails ? */
1291         }
1292         return 0;
1293 }
1294
1295 void
1296 MidiDiskstream::set_block_size (jack_nframes_t nframes)
1297 {
1298 }
1299
1300 void
1301 MidiDiskstream::allocate_temporary_buffers ()
1302 {
1303 }
1304
1305 void
1306 MidiDiskstream::monitor_input (bool yn)
1307 {
1308         if (_source_port)
1309                 _source_port->request_monitor_input (yn);
1310         else
1311                 cerr << "MidiDiskstream NO SOURCE PORT TO MONITOR\n";
1312 }
1313
1314 void
1315 MidiDiskstream::set_align_style_from_io ()
1316 {
1317         bool have_physical = false;
1318
1319         if (_io == 0) {
1320                 return;
1321         }
1322
1323         get_input_sources ();
1324         
1325         if (_source_port && _source_port->flags() & JackPortIsPhysical) {
1326                 have_physical = true;
1327         }
1328
1329         if (have_physical) {
1330                 set_align_style (ExistingMaterial);
1331         } else {
1332                 set_align_style (CaptureTime);
1333         }
1334 }
1335
1336
1337 float
1338 MidiDiskstream::playback_buffer_load () const
1339 {
1340         return (float) ((double) _playback_buf->read_space()/
1341                         (double) _playback_buf->bufsize());
1342 }
1343
1344 float
1345 MidiDiskstream::capture_buffer_load () const
1346 {
1347         return (float) ((double) _capture_buf->write_space()/
1348                         (double) _capture_buf->bufsize());
1349 }
1350
1351
1352 int
1353 MidiDiskstream::use_pending_capture_data (XMLNode& node)
1354 {
1355         return 0;
1356 }