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