b5bb83ee7825a486762782899c90caf184236fc6
[ardour.git] / libs / ardour / 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$
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 <pbd/lockmonitor.h>
37 #include <pbd/xml++.h>
38
39 #include <ardour/ardour.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/diskstream.h>
42 #include <ardour/utils.h>
43 #include <ardour/configuration.h>
44 #include <ardour/filesource.h>
45 #include <ardour/destructive_filesource.h>
46 #include <ardour/send.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/cycle_timer.h>
49 #include <ardour/audioregion.h>
50
51 #include "i18n.h"
52 #include <locale.h>
53
54 using namespace std;
55 using namespace ARDOUR;
56
57 jack_nframes_t DiskStream::disk_io_chunk_frames;
58
59 sigc::signal<void,DiskStream*>    DiskStream::DiskStreamCreated;
60 sigc::signal<void,DiskStream*>    DiskStream::CannotRecordNoInput;
61 sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
62 sigc::signal<void>                DiskStream::DiskOverrun;
63 sigc::signal<void>                DiskStream::DiskUnderrun;
64
65 DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
66         : _name (name),
67           _session (sess)
68 {
69         /* prevent any write sources from being created */
70
71         in_set_state = true;
72
73         init (flag);
74         use_new_playlist ();
75
76         in_set_state = false;
77
78         DiskStreamCreated (this); /* EMIT SIGNAL */
79 }
80         
81 DiskStream::DiskStream (Session& sess, const XMLNode& node)
82         : _session (sess)
83         
84 {
85         in_set_state = true;
86         init (Recordable);
87
88         if (set_state (node)) {
89                 in_set_state = false;
90                 throw failed_constructor();
91         }
92
93         in_set_state = false;
94
95         if (destructive()) {
96                 use_destructive_playlist ();
97         }
98
99         DiskStreamCreated (this); /* EMIT SIGNAL */
100 }
101
102 void
103 DiskStream::init_channel (ChannelInfo &chan)
104 {
105         chan.playback_wrap_buffer = 0;
106         chan.capture_wrap_buffer = 0;
107         chan.speed_buffer = 0;
108         chan.peak_power = 0.0f;
109         chan.write_source = 0;
110         chan.source = 0;
111         chan.current_capture_buffer = 0;
112         chan.current_playback_buffer = 0;
113         chan.curr_capture_cnt = 0;
114         
115         chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
116         chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
117         chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
118         
119         
120         /* touch the ringbuffer buffers, which will cause
121            them to be mapped into locked physical RAM if
122            we're running with mlockall(). this doesn't do
123            much if we're not.  
124         */
125         memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
126         memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
127         memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
128 }
129
130
131 void
132 DiskStream::init (Flag f)
133 {
134         _id = new_id();
135         _refcnt = 0;
136         _flags = f;
137         _io = 0;
138         _alignment_style = ExistingMaterial;
139         _persistent_alignment_style = ExistingMaterial;
140         first_input_change = true;
141         _playlist = 0;
142         i_am_the_modifier = 0;
143         atomic_set (&_record_enabled, 0);
144         was_recording = false;
145         capture_start_frame = 0;
146         capture_captured = 0;
147         _visible_speed = 1.0f;
148         _actual_speed = 1.0f;
149         _buffer_reallocation_required = false;
150         _seek_required = false;
151         first_recordable_frame = max_frames;
152         last_recordable_frame = max_frames;
153         _roll_delay = 0;
154         _capture_offset = 0;
155         _processed = false;
156         _slaved = false;
157         adjust_capture_position = 0;
158         last_possibly_recording = 0;
159         loop_location = 0;
160         wrap_buffer_size = 0;
161         speed_buffer_size = 0;
162         last_phase = 0;
163         phi = (uint64_t) (0x1000000);
164         file_frame = 0;
165         playback_sample = 0;
166         playback_distance = 0;
167         _read_data_count = 0;
168         _write_data_count = 0;
169         deprecated_io_node = 0;
170
171         /* there are no channels at this point, so these
172            two calls just get speed_buffer_size and wrap_buffer
173            size setup without duplicating their code.
174         */
175
176         set_block_size (_session.get_block_size());
177         allocate_temporary_buffers ();
178
179         pending_overwrite = false;
180         overwrite_frame = 0;
181         overwrite_queued = false;
182         input_change_pending = NoChange;
183
184         add_channel ();
185         _n_channels = 1;
186 }
187
188 void
189 DiskStream::destroy_channel (ChannelInfo &chan)
190 {
191         if (chan.write_source) {
192                 chan.write_source->release ();
193                 chan.write_source = 0;
194         }
195                 
196         if (chan.speed_buffer) {
197                 delete [] chan.speed_buffer;
198         }
199
200         if (chan.playback_wrap_buffer) {
201                 delete [] chan.playback_wrap_buffer;
202         }
203         if (chan.capture_wrap_buffer) {
204                 delete [] chan.capture_wrap_buffer;
205         }
206         
207         delete chan.playback_buf;
208         delete chan.capture_buf;
209         delete chan.capture_transition_buf;
210         
211         chan.playback_buf = 0;
212         chan.capture_buf = 0;
213 }
214
215 DiskStream::~DiskStream ()
216 {
217         LockMonitor lm (state_lock, __LINE__, __FILE__);
218
219         if (_playlist) {
220                 _playlist->unref ();
221         }
222
223         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
224                 destroy_channel((*chan));
225         }
226         
227         channels.clear();
228 }
229
230 void
231 DiskStream::handle_input_change (IOChange change, void *src)
232 {
233         LockMonitor lm (state_lock, __LINE__, __FILE__);
234
235         if (!(input_change_pending & change)) {
236                 input_change_pending = IOChange (input_change_pending|change);
237                 _session.request_input_change_handling ();
238         }
239 }
240
241 void
242 DiskStream::non_realtime_input_change ()
243 {
244         { 
245                 LockMonitor lm (state_lock, __LINE__, __FILE__);
246
247                 if (input_change_pending == NoChange) {
248                         return;
249                 }
250
251                 if (input_change_pending & ConfigurationChanged) {
252
253                         if (_io->n_inputs() > _n_channels) {
254                                 
255                                 // we need to add new channel infos
256                                 
257                                 int diff = _io->n_inputs() - channels.size();
258                                 
259                                 for (int i = 0; i < diff; ++i) {
260                                         add_channel ();
261                                 }
262                                 
263                 } else if (_io->n_inputs() < _n_channels) {
264                                 
265                                 // we need to get rid of channels
266                                 
267                                 int diff = channels.size() - _io->n_inputs();
268                                 
269                                 for (int i = 0; i < diff; ++i) {
270                                         remove_channel ();
271                                 }
272                         }
273                 } 
274
275                 get_input_sources ();
276                 set_capture_offset ();
277                 
278                 if (first_input_change) {
279                         set_align_style (_persistent_alignment_style);
280                         first_input_change = false;
281                 } else {
282                         set_align_style_from_io ();
283                 }
284
285                 input_change_pending = NoChange;
286         }
287
288         /* reset capture files */
289
290         reset_write_sources (false);
291
292         /* now refill channel buffers */
293
294         if (speed() != 1.0f || speed() != -1.0f) {
295                 seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
296         }
297         else {
298                 seek (_session.transport_frame());
299         }
300 }
301
302 void
303 DiskStream::get_input_sources ()
304 {
305         uint32_t ni = _io->n_inputs();
306         
307         for (uint32_t n = 0; n < ni; ++n) {
308                 
309                 const char **connections = _io->input(n)->get_connections ();
310                 ChannelInfo& chan = channels[n];
311                 
312                 if (connections == 0 || connections[0] == 0) {
313                         
314                         if (chan.source) {
315                                 // _source->disable_metering ();
316                         }
317                         
318                         chan.source = 0;
319                         
320                 } else {
321                         chan.source = _session.engine().get_port_by_name (connections[0]);
322                 }
323                 
324                 if (connections) {
325                         free (connections);
326                 }
327         }
328 }               
329
330 int
331 DiskStream::find_and_use_playlist (const string& name)
332 {
333         Playlist* pl;
334         AudioPlaylist* playlist;
335                 
336         if ((pl = _session.get_playlist (name)) == 0) {
337                 error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
338                 return -1;
339         }
340
341         if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
342                 error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
343                 return -1;
344         }
345
346         return use_playlist (playlist);
347 }
348
349 int
350 DiskStream::use_playlist (AudioPlaylist* playlist)
351 {
352         {
353                 LockMonitor lm (state_lock, __LINE__, __FILE__);
354
355                 if (playlist == _playlist) {
356                         return 0;
357                 }
358
359                 plstate_connection.disconnect();
360                 plmod_connection.disconnect ();
361                 plgone_connection.disconnect ();
362
363                 if (_playlist) {
364                         _playlist->unref();
365                 }
366                         
367                 _playlist = playlist;
368                 _playlist->ref();
369
370                 if (!in_set_state && recordable()) {
371                         reset_write_sources (false);
372                 }
373                 
374                 plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
375                 plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
376                 plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
377         }
378
379         if (!overwrite_queued) {
380                 _session.request_overwrite_buffer (this);
381                 overwrite_queued = true;
382         }
383         
384         PlaylistChanged (); /* EMIT SIGNAL */
385         _session.set_dirty ();
386
387         return 0;
388 }
389
390 void
391 DiskStream::playlist_deleted (Playlist* pl)
392 {
393         /* this catches an ordering issue with session destruction. playlists 
394            are destroyed before diskstreams. we have to invalidate any handles
395            we have to the playlist.
396         */
397
398         _playlist = 0;
399 }
400
401 int
402 DiskStream::use_new_playlist ()
403 {
404         string newname;
405         AudioPlaylist* playlist;
406
407         if (!in_set_state && destructive()) {
408                 return 0;
409         }
410
411         if (_playlist) {
412                 newname = Playlist::bump_name (_playlist->name(), _session);
413         } else {
414                 newname = Playlist::bump_name (_name, _session);
415         }
416
417         if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
418                 playlist->set_orig_diskstream_id (id());
419                 return use_playlist (playlist);
420         } else { 
421                 return -1;
422         }
423 }
424
425 int
426 DiskStream::use_copy_playlist ()
427 {
428         if (destructive()) {
429                 return 0;
430         }
431
432         if (_playlist == 0) {
433                 error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
434                 return -1;
435         }
436
437         string newname;
438         AudioPlaylist* playlist;
439
440         newname = Playlist::bump_name (_playlist->name(), _session);
441         
442         if ((playlist  = new AudioPlaylist (*_playlist, newname)) != 0) {
443                 playlist->set_orig_diskstream_id (id());
444                 return use_playlist (playlist);
445         } else { 
446                 return -1;
447         }
448 }
449
450 void
451 DiskStream::setup_destructive_playlist ()
452 {
453         AudioRegion::SourceList srcs;
454
455         cerr << "setting up destructive playlist with " << channels.size() << " channels\n";
456
457         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
458                 srcs.push_back ((*chan).write_source);
459         }
460
461         /* a single full-sized region */
462
463         AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
464         _playlist->add_region (*region, 0);             
465 }
466
467 void
468 DiskStream::use_destructive_playlist ()
469 {
470         /* use the sources associated with the single full-extent region */
471         
472         Playlist::RegionList* rl = _playlist->regions_at (0);
473
474         if (rl->empty()) {
475                 throw failed_constructor();
476         }
477
478         AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
479
480         if (region == 0) {
481                 throw failed_constructor();
482         }
483
484         delete rl;
485
486         uint32_t n;
487         ChannelList::iterator chan;
488
489         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
490                 (*chan).write_source = dynamic_cast<FileSource*>(&region->source (n));
491                 (*chan).write_source->set_allow_remove_if_empty (false);
492         }
493
494         /* the source list will never be reset for a destructive track */
495 }
496
497 void
498 DiskStream::set_io (IO& io)
499 {
500         _io = &io;
501         set_align_style_from_io ();
502 }
503
504 int
505 DiskStream::set_name (string str, void *src)
506 {
507         if (str != _name) {
508                 _playlist->set_name (str);
509                 _name = str;
510                 
511                 if (!in_set_state && recordable()) {
512                         /* rename existing capture files so that they have the correct name */
513                         return rename_write_sources ();
514                 } else {
515                         return -1;
516                 }
517         }
518
519         return 0;
520 }
521
522 void
523 DiskStream::set_speed (double sp)
524 {
525         _session.request_diskstream_speed (*this, sp);
526
527         /* to force a rebuffering at the right place */
528         playlist_modified();
529 }
530
531 bool
532 DiskStream::realtime_set_speed (double sp, bool global)
533 {
534         bool changed = false;
535         double new_speed = sp * _session.transport_speed();
536         
537         if (_visible_speed != sp) {
538                 _visible_speed = sp;
539                 changed = true;
540         }
541         
542         if (new_speed != _actual_speed) {
543                 
544                 jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * 
545                                                                             fabs (new_speed)) + 1;
546                 
547                 if (required_wrap_size > wrap_buffer_size) {
548                         _buffer_reallocation_required = true;
549                 }
550                 
551                 _actual_speed = new_speed;
552                 phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
553         }
554
555         if (changed) {
556                 if (!global) {
557                         _seek_required = true;
558                 }
559                  speed_changed (); /* EMIT SIGNAL */
560         }
561
562         return _buffer_reallocation_required || _seek_required;
563 }
564
565 void
566 DiskStream::non_realtime_set_speed ()
567 {
568         if (_buffer_reallocation_required)
569         {
570                 LockMonitor lm (state_lock, __LINE__, __FILE__);
571                 allocate_temporary_buffers ();
572
573                 _buffer_reallocation_required = false;
574         }
575
576         if (_seek_required) {
577                 if (speed() != 1.0f || speed() != -1.0f) {
578                         seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
579                 }
580                 else {
581                         seek (_session.transport_frame(), true);
582                 }
583
584                 _seek_required = false;
585         }
586 }
587
588 void
589 DiskStream::prepare ()
590 {
591         _processed = false;
592         playback_distance = 0;
593 }
594
595 void
596 DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
597 {
598         int possibly_recording;
599         int rolling;
600         int change;
601         const int transport_rolling = 0x4;
602         const int track_rec_enabled = 0x2;
603         const int global_rec_enabled = 0x1;
604
605         /* merge together the 3 factors that affect record status, and compute
606            what has changed.
607         */
608
609         rolling = _session.transport_speed() != 0.0f;
610         possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
611         change = possibly_recording ^ last_possibly_recording;
612
613         if (possibly_recording == last_possibly_recording) {
614                 return;
615         }
616
617         /* change state */
618
619         /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
620
621         if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) || 
622             ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
623                 
624                 /* starting to record: compute first+last frames */
625
626                 first_recordable_frame = transport_frame + _capture_offset;
627                 last_recordable_frame = max_frames;
628                 capture_start_frame = transport_frame;
629
630                 if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
631
632                         /* was stopped, now rolling (and recording) */
633
634                         if (_alignment_style == ExistingMaterial) {
635                                 first_recordable_frame += _session.worst_output_latency();
636                         } else {
637                                 first_recordable_frame += _roll_delay;
638                         }
639
640                 } else {
641
642                         /* was rolling, but record state changed */
643
644                         if (_alignment_style == ExistingMaterial) {
645
646
647                                 if (!_session.get_punch_in()) {
648
649                                         /* manual punch in happens at the correct transport frame
650                                            because the user hit a button. but to get alignment correct 
651                                            we have to back up the position of the new region to the 
652                                            appropriate spot given the roll delay.
653                                         */
654
655                                         capture_start_frame -= _roll_delay;
656
657                                         /* XXX paul notes (august 2005): i don't know why
658                                            this is needed.
659                                         */
660
661                                         first_recordable_frame += _capture_offset;
662
663                                 } else {
664
665                                         /* autopunch toggles recording at the precise
666                                            transport frame, and then the DS waits
667                                            to start recording for a time that depends
668                                            on the output latency.
669                                         */
670
671                                         first_recordable_frame += _session.worst_output_latency();
672                                 }
673
674                         } else {
675
676                                 if (_session.get_punch_in()) {
677                                         first_recordable_frame += _roll_delay;
678                                 } else {
679                                         capture_start_frame -= _roll_delay;
680                                 }
681                         }
682                         
683                 }
684
685                 if (_flags & Recordable) {
686                         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
687                                 
688                                 RingBufferNPT<CaptureTransition>::rw_vector transvec;
689                                 (*chan).capture_transition_buf->get_write_vector(&transvec);
690                                 
691                                 if (transvec.len[0] > 0) {
692                                         transvec.buf[0]->type = CaptureStart;
693                                         transvec.buf[0]->capture_val = capture_start_frame;
694                                         (*chan).capture_transition_buf->increment_write_ptr(1);
695                                 }
696                                 else {
697                                         // bad!
698                                         fatal << X_("programming error: capture_transition_buf is full on rec start!  inconceivable!") 
699                                               << endmsg;
700                                 }
701                         }
702                 }
703
704         } else if (!record_enabled() || !can_record) {
705                 
706                 /* stop recording */
707
708                 last_recordable_frame = transport_frame + _capture_offset;
709                 
710                 if (_alignment_style == ExistingMaterial) {
711                         last_recordable_frame += _session.worst_output_latency();
712                 } else {
713                         last_recordable_frame += _roll_delay;
714                 }
715         }
716
717         last_possibly_recording = possibly_recording;
718 }
719
720 int
721 DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
722 {
723         uint32_t n;
724         ChannelList::iterator c;
725         int ret = -1;
726         jack_nframes_t rec_offset = 0;
727         jack_nframes_t rec_nframes = 0;
728         bool nominally_recording;
729         bool re = record_enabled ();
730         bool collect_playback = false;
731
732         /* if we've already processed the frames corresponding to this call,
733            just return. this allows multiple routes that are taking input
734            from this diskstream to call our ::process() method, but have
735            this stuff only happen once. more commonly, it allows both
736            the AudioTrack that is using this DiskStream *and* the Session
737            to call process() without problems.
738         */
739
740         if (_processed) {
741                 return 0;
742         }
743
744         check_record_status (transport_frame, nframes, can_record);
745
746         nominally_recording = (can_record && re);
747
748         if (nframes == 0) {
749                 _processed = true;
750                 return 0;
751         }
752
753         /* This lock is held until the end of DiskStream::commit, so these two functions
754            must always be called as a pair. The only exception is if this function
755            returns a non-zero value, in which case, ::commit should not be called.
756         */
757
758         if (pthread_mutex_trylock (state_lock.mutex())) {
759                 return 1;
760         }
761
762         adjust_capture_position = 0;
763
764         for (c = channels.begin(); c != channels.end(); ++c) {
765                 (*c).current_capture_buffer = 0;
766                 (*c).current_playback_buffer  = 0;
767         }
768
769         if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
770                 OverlapType ot;
771                 
772                 ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
773
774                 switch (ot) {
775                 case OverlapNone:
776                         rec_nframes = 0;
777                         break;
778                         
779                 case OverlapInternal:
780                 /*     ----------    recrange
781                          |---|       transrange
782                 */
783                         rec_nframes = nframes;
784                         rec_offset = 0;
785                         break;
786                         
787                 case OverlapStart:
788                         /*    |--------|    recrange
789                             -----|          transrange
790                         */
791                         rec_nframes = transport_frame + nframes - first_recordable_frame;
792                         if (rec_nframes) {
793                                 rec_offset = first_recordable_frame - transport_frame;
794                         }
795                         break;
796                         
797                 case OverlapEnd:
798                         /*    |--------|    recrange
799                                  |--------  transrange
800                         */
801                         rec_nframes = last_recordable_frame - transport_frame;
802                         rec_offset = 0;
803                         break;
804                         
805                 case OverlapExternal:
806                         /*    |--------|    recrange
807                             --------------  transrange
808                         */
809                         rec_nframes = last_recordable_frame - last_recordable_frame;
810                         rec_offset = first_recordable_frame - transport_frame;
811                         break;
812                 }
813
814                 if (rec_nframes && !was_recording) {
815                         capture_captured = 0;
816                         was_recording = true;
817                 }
818         }
819
820
821         if (can_record && !_last_capture_regions.empty()) {
822                 _last_capture_regions.clear ();
823         }
824
825         if (nominally_recording || rec_nframes) {
826
827                 for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
828                         
829                         ChannelInfo& chan (*c);
830                 
831                         chan.capture_buf->get_write_vector (&chan.capture_vector);
832
833                         if (rec_nframes <= chan.capture_vector.len[0]) {
834                                 
835                                 chan.current_capture_buffer = chan.capture_vector.buf[0];
836
837                                 /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
838                                    rec_offset
839                                 */
840
841                                 memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
842
843                         } else {
844
845                                 jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
846
847                                 if (rec_nframes > total) {
848                                         DiskOverrun ();
849                                         goto out;
850                                 }
851
852                                 Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
853                                 jack_nframes_t first = chan.capture_vector.len[0];
854
855                                 memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
856                                 memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
857                                 memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
858                                 memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
859                                 
860                                 chan.current_capture_buffer = chan.capture_wrap_buffer;
861                         }
862                 }
863
864         } else {
865
866                 if (was_recording) {
867                         finish_capture (rec_monitors_input);
868                 }
869
870         }
871         
872         if (rec_nframes) {
873                 
874                 /* data will be written to disk */
875
876                 if (rec_nframes == nframes && rec_offset == 0) {
877
878                         for (c = channels.begin(); c != channels.end(); ++c) {
879                                 (*c).current_playback_buffer = (*c).current_capture_buffer;
880                         }
881
882                         playback_distance = nframes;
883
884                 } else {
885
886
887                         /* we can't use the capture buffer as the playback buffer, because
888                            we recorded only a part of the current process' cycle data
889                            for capture.
890                         */
891
892                         collect_playback = true;
893                 }
894
895                 adjust_capture_position = rec_nframes;
896
897         } else if (nominally_recording) {
898
899                 /* can't do actual capture yet - waiting for latency effects to finish before we start*/
900
901                 for (c = channels.begin(); c != channels.end(); ++c) {
902                         (*c).current_playback_buffer = (*c).current_capture_buffer;
903                 }
904
905                 playback_distance = nframes;
906
907         } else {
908
909                 collect_playback = true;
910         }
911
912         if (collect_playback) {
913
914                 /* we're doing playback */
915
916                 jack_nframes_t necessary_samples;
917
918                 /* no varispeed playback if we're recording, because the output .... TBD */
919
920                 if (rec_nframes == 0 && _actual_speed != 1.0f) {
921                         necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
922                 } else {
923                         necessary_samples = nframes;
924                 }
925                 
926                 for (c = channels.begin(); c != channels.end(); ++c) {
927                         (*c).playback_buf->get_read_vector (&(*c).playback_vector);
928                 }
929
930                 n = 0;                  
931
932                 for (c = channels.begin(); c != channels.end(); ++c, ++n) {
933                 
934                         ChannelInfo& chan (*c);
935
936                         if (necessary_samples <= chan.playback_vector.len[0]) {
937
938                                 chan.current_playback_buffer = chan.playback_vector.buf[0];
939
940                         } else {
941                                 jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
942                                 
943                                 if (necessary_samples > total) {
944                                         DiskUnderrun ();
945                                         goto out;
946                                         
947                                 } else {
948                                         
949                                         memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
950                                                 chan.playback_vector.len[0] * sizeof (Sample));
951                                         memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1], 
952                                                 (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
953                                         
954                                         chan.current_playback_buffer = chan.playback_wrap_buffer;
955                                 }
956                         }
957                 } 
958
959                 if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
960                         
961                         uint64_t phase = last_phase;
962                         jack_nframes_t i = 0;
963
964                         // Linearly interpolate into the alt buffer
965                         // using 40.24 fixp maths (swh)
966
967                         for (c = channels.begin(); c != channels.end(); ++c) {
968
969                                 float fr;
970                                 ChannelInfo& chan (*c);
971
972                                 i = 0;
973                                 phase = last_phase;
974
975                                 for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
976                                         i = phase >> 24;
977                                         fr = (phase & 0xFFFFFF) / 16777216.0f;
978                                         chan.speed_buffer[outsample] = 
979                                                 chan.current_playback_buffer[i] * (1.0f - fr) +
980                                                 chan.current_playback_buffer[i+1] * fr;
981                                         phase += phi;
982                                 }
983                                 
984                                 chan.current_playback_buffer = chan.speed_buffer;
985                         }
986
987                         playback_distance = i + 1;
988                         last_phase = (phase & 0xFFFFFF);
989
990                 } else {
991                         playback_distance = nframes;
992                 }
993
994         }
995
996         ret = 0;
997
998   out:
999         _processed = true;
1000
1001         if (ret) {
1002
1003                 /* we're exiting with failure, so ::commit will not
1004                    be called. unlock the state lock.
1005                 */
1006                 
1007                 pthread_mutex_unlock (state_lock.mutex());
1008         } 
1009
1010         return ret;
1011 }
1012
1013 void
1014 DiskStream::recover ()
1015 {
1016         pthread_mutex_unlock (state_lock.mutex());
1017         _processed = false;
1018 }
1019
1020 bool
1021 DiskStream::commit (jack_nframes_t nframes)
1022 {
1023         bool need_butler = false;
1024
1025         if (_actual_speed < 0.0) {
1026                 playback_sample -= playback_distance;
1027         } else {
1028                 playback_sample += playback_distance;
1029         }
1030
1031         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1032
1033                 (*chan).playback_buf->increment_read_ptr (playback_distance);
1034                 
1035                 if (adjust_capture_position) {
1036                         (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
1037                 }
1038         }
1039         
1040         if (adjust_capture_position != 0) {
1041                 capture_captured += adjust_capture_position;
1042                 adjust_capture_position = 0;
1043         }
1044         
1045         if (_slaved) {
1046                 need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
1047         } else {
1048                 need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
1049                         || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
1050         }
1051
1052         pthread_mutex_unlock (state_lock.mutex());
1053
1054         _processed = false;
1055
1056         return need_butler;
1057 }
1058
1059 void
1060 DiskStream::set_pending_overwrite (bool yn)
1061 {
1062         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
1063         
1064         pending_overwrite = yn;
1065
1066         overwrite_frame = playback_sample;
1067         overwrite_offset = channels.front().playback_buf->get_read_ptr();
1068 }
1069
1070 int
1071 DiskStream::overwrite_existing_buffers ()
1072 {
1073         Sample* mixdown_buffer;
1074         float* gain_buffer;
1075         char * workbuf;
1076         int ret = -1;
1077         bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1078
1079         overwrite_queued = false;
1080
1081         /* assume all are the same size */
1082         jack_nframes_t size = channels[0].playback_buf->bufsize();
1083         
1084         mixdown_buffer = new Sample[size];
1085         gain_buffer = new float[size];
1086         workbuf = new char[size*4];
1087         
1088         /* reduce size so that we can fill the buffer correctly. */
1089         size--;
1090         
1091         uint32_t n=0;
1092         jack_nframes_t start;
1093
1094         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1095
1096                 start = overwrite_frame;
1097                 jack_nframes_t cnt = size;
1098                 
1099                 /* to fill the buffer without resetting the playback sample, we need to
1100                    do it one or two chunks (normally two).
1101
1102                    |----------------------------------------------------------------------|
1103
1104                                        ^
1105                                        overwrite_offset
1106                     |<- second chunk->||<----------------- first chunk ------------------>|
1107                    
1108                 */
1109                 
1110                 jack_nframes_t to_read = size - overwrite_offset;
1111
1112                 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
1113                           start, to_read, *chan, n, reversed)) {
1114                         error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1115                                          _id, size, playback_sample) << endmsg;
1116                         goto out;
1117                 }
1118                         
1119                 if (cnt > to_read) {
1120
1121                         cnt -= to_read;
1122                 
1123                         if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
1124                                   start, cnt, *chan, n, reversed)) {
1125                                 error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
1126                                                  _id, size, playback_sample) << endmsg;
1127                                 goto out;
1128                         }
1129                 }
1130         }
1131
1132         ret = 0;
1133  
1134   out:
1135         pending_overwrite = false;
1136         delete [] gain_buffer;
1137         delete [] mixdown_buffer;
1138         delete [] workbuf;
1139         return ret;
1140 }
1141
1142 int
1143 DiskStream::seek (jack_nframes_t frame, bool complete_refill)
1144 {
1145         LockMonitor lm (state_lock, __LINE__, __FILE__);
1146         uint32_t n;
1147         int ret;
1148         ChannelList::iterator chan;
1149
1150         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1151                 (*chan).playback_buf->reset ();
1152                 (*chan).capture_buf->reset ();
1153                 if ((*chan).write_source) {
1154                         (*chan).write_source->seek (frame);
1155                 }
1156         }
1157         
1158         playback_sample = frame;
1159         file_frame = frame;
1160
1161         if (complete_refill) {
1162                 while ((ret = do_refill (0, 0, 0)) > 0);
1163         } else {
1164                 ret = do_refill (0, 0, 0);
1165         }
1166
1167         return ret;
1168 }
1169
1170 int
1171 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1172 {
1173         ChannelList::iterator chan;
1174
1175         for (chan = channels.begin(); chan != channels.end(); ++chan) {
1176                 if ((*chan).playback_buf->read_space() < distance) {
1177                         return false;
1178                 } 
1179         }
1180         return true;
1181 }
1182
1183 int
1184 DiskStream::internal_playback_seek (jack_nframes_t distance)
1185 {
1186         ChannelList::iterator chan;
1187
1188         for (chan = channels.begin(); chan != channels.end(); ++chan) {
1189                 (*chan).playback_buf->increment_read_ptr (distance);
1190         }
1191
1192         first_recordable_frame += distance;
1193         playback_sample += distance;
1194         
1195         return 0;
1196 }
1197
1198 int
1199 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, 
1200                   ChannelInfo& channel_info, int channel, bool reversed)
1201 {
1202         jack_nframes_t this_read = 0;
1203         bool reloop = false;
1204         jack_nframes_t loop_end = 0;
1205         jack_nframes_t loop_start = 0;
1206         jack_nframes_t loop_length = 0;
1207         jack_nframes_t offset = 0;
1208         Location *loc = 0;
1209
1210         if (!reversed) {
1211                 /* Make the use of a Location atomic for this read operation.
1212                    
1213                    Note: Locations don't get deleted, so all we care about
1214                    when I say "atomic" is that we are always pointing to
1215                    the same one and using a start/length values obtained
1216                    just once.
1217                 */
1218                 
1219                 if ((loc = loop_location) != 0) {
1220                         loop_start = loc->start();
1221                         loop_end = loc->end();
1222                         loop_length = loop_end - loop_start;
1223                 }
1224                 
1225                 /* if we are looping, ensure that the first frame we read is at the correct
1226                    position within the loop.
1227                 */
1228                 
1229                 if (loc && start >= loop_end) {
1230                         //cerr << "start adjusted from " << start;
1231                         start = loop_start + ((start - loop_start) % loop_length);
1232                         //cerr << "to " << start << endl;
1233                 }
1234                 //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
1235         }
1236
1237         while (cnt) {
1238
1239                 /* take any loop into account. we can't read past the end of the loop. */
1240
1241                 if (loc && (loop_end - start < cnt)) {
1242                         this_read = loop_end - start;
1243                         //cerr << "reloop true: thisread: " << this_read << "  cnt: " << cnt << endl;
1244                         reloop = true;
1245                 } else {
1246                         reloop = false;
1247                         this_read = cnt;
1248                 }
1249
1250                 if (this_read == 0) {
1251                         break;
1252                 }
1253
1254                 this_read = min(cnt,this_read);
1255
1256                 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
1257                         error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read, 
1258                                          start) << endmsg;
1259                         return -1;
1260                 }
1261
1262                 _read_data_count = _playlist->read_data_count();
1263                 
1264                 if (reversed) {
1265
1266                         /* don't adjust start, since caller has already done that
1267                          */
1268
1269                         swap_by_ptr (buf, buf + this_read - 1);
1270                         
1271                 } else {
1272                         
1273                         /* if we read to the end of the loop, go back to the beginning */
1274                         
1275                         if (reloop) {
1276                                 start = loop_start;
1277                         } else {
1278                                 start += this_read;
1279                         }
1280                 } 
1281
1282                 cnt -= this_read;
1283                 offset += this_read;
1284         }
1285
1286         return 0;
1287 }
1288
1289 int
1290 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
1291 {
1292         int32_t ret = 0;
1293         jack_nframes_t to_read;
1294         RingBufferNPT<Sample>::rw_vector vector;
1295         bool free_mixdown;
1296         bool free_gain;
1297         bool free_workbuf;
1298         bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1299         jack_nframes_t total_space;
1300         jack_nframes_t zero_fill;
1301         uint32_t chan_n;
1302         ChannelList::iterator i;
1303         jack_nframes_t ts;
1304
1305         channels.front().playback_buf->get_write_vector (&vector);
1306         
1307         if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1308                 return 0;
1309         }
1310         
1311         /* if there are 2+ chunks of disk i/o possible for
1312            this track, let the caller know so that it can arrange
1313            for us to be called again, ASAP.
1314         */
1315         
1316         if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1317                 ret = 1;
1318         }
1319         
1320         /* if we're running close to normal speed and there isn't enough 
1321            space to do disk_io_chunk_frames of I/O, then don't bother.  
1322            
1323            at higher speeds, just do it because the sync between butler
1324            and audio thread may not be good enough.
1325         */
1326         
1327         if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1328                 return 0;
1329         }
1330         
1331         /* when slaved, don't try to get too close to the read pointer. this
1332            leaves space for the buffer reversal to have something useful to
1333            work with.
1334         */
1335         
1336         if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1337                 return 0;
1338         }
1339
1340         total_space = min (disk_io_chunk_frames, total_space);
1341
1342         if (reversed) {
1343
1344                 if (file_frame == 0) {
1345
1346                         /* at start: nothing to do but fill with silence */
1347
1348                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1349                                         
1350                                 ChannelInfo& chan (*i);
1351                                 chan.playback_buf->get_write_vector (&vector);
1352                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1353                                 if (vector.len[1]) {
1354                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1355                                 }
1356                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1357                         }
1358                         return 0;
1359                 }
1360
1361                 if (file_frame < total_space) {
1362
1363                         /* too close to the start: read what we can, 
1364                            and then zero fill the rest 
1365                         */
1366
1367                         zero_fill = total_space - file_frame;
1368                         total_space = file_frame;
1369                         file_frame = 0;
1370
1371                 } else {
1372                         
1373                         /* move read position backwards because we are going
1374                            to reverse the data.
1375                         */
1376                         
1377                         file_frame -= total_space;
1378                         zero_fill = 0;
1379                 }
1380
1381         } else {
1382
1383                 if (file_frame == max_frames) {
1384
1385                         /* at end: nothing to do but fill with silence */
1386                         
1387                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1388                                         
1389                                 ChannelInfo& chan (*i);
1390                                 chan.playback_buf->get_write_vector (&vector);
1391                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1392                                 if (vector.len[1]) {
1393                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1394                                 }
1395                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1396                         }
1397                         return 0;
1398                 }
1399                 
1400                 if (file_frame > max_frames - total_space) {
1401
1402                         /* to close to the end: read what we can, and zero fill the rest */
1403
1404                         zero_fill = total_space - (max_frames - file_frame);
1405                         total_space = max_frames - file_frame;
1406
1407                 } else {
1408                         zero_fill = 0;
1409                 }
1410         }
1411
1412         /* Please note: the code to allocate buffers isn't run
1413            during normal butler thread operation. Its there
1414            for other times when we need to call do_refill()
1415            from somewhere other than the butler thread.
1416         */
1417
1418         if (mixdown_buffer == 0) {
1419                 mixdown_buffer = new Sample[disk_io_chunk_frames];
1420                 free_mixdown = true;
1421         } else {
1422                 free_mixdown = false;
1423         }
1424
1425         if (gain_buffer == 0) {
1426                 gain_buffer = new float[disk_io_chunk_frames];
1427                 free_gain = true;
1428         } else {
1429                 free_gain = false;
1430         }
1431
1432         if (workbuf == 0) {
1433                 workbuf = new char[disk_io_chunk_frames * 4];
1434                 free_workbuf = true;
1435         } else {
1436                 free_workbuf = false;
1437         }
1438         
1439         jack_nframes_t file_frame_tmp = 0;
1440
1441         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1442
1443                 ChannelInfo& chan (*i);
1444                 Sample* buf1;
1445                 Sample* buf2;
1446                 jack_nframes_t len1, len2;
1447
1448                 chan.playback_buf->get_write_vector (&vector);
1449
1450                 ts = total_space;
1451                 file_frame_tmp = file_frame;
1452
1453                 if (reversed) {
1454                         buf1 = vector.buf[1];
1455                         len1 = vector.len[1];
1456                         buf2 = vector.buf[0];
1457                         len2 = vector.len[0];
1458                 } else {
1459                         buf1 = vector.buf[0];
1460                         len1 = vector.len[0];
1461                         buf2 = vector.buf[1];
1462                         len2 = vector.len[1];
1463                 }
1464
1465
1466                 to_read = min (ts, len1);
1467                 to_read = min (to_read, disk_io_chunk_frames);
1468
1469                 if (to_read) {
1470
1471                         if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1472                                 ret = -1;
1473                                 goto out;
1474                         }
1475                         
1476                         chan.playback_buf->increment_write_ptr (to_read);
1477                         ts -= to_read;
1478                 }
1479
1480                 to_read = min (ts, len2);
1481
1482                 if (to_read) {
1483
1484                         
1485                         /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1486                            so read some or all of vector.len[1] as well.
1487                         */
1488
1489                         if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1490                                 ret = -1;
1491                                 goto out;
1492                         }
1493                 
1494                         chan.playback_buf->increment_write_ptr (to_read);
1495                 }
1496
1497                 if (zero_fill) {
1498                         /* do something */
1499                 }
1500
1501         }
1502         
1503         file_frame = file_frame_tmp;
1504
1505   out:
1506         if (free_mixdown) {
1507                 delete [] mixdown_buffer;
1508         }
1509         if (free_gain) {
1510                 delete [] gain_buffer;
1511         }
1512         if (free_workbuf) {
1513                 delete [] workbuf;
1514         }
1515
1516         return ret;
1517 }       
1518
1519 int
1520 DiskStream::do_flush (char * workbuf, bool force_flush)
1521 {
1522         uint32_t to_write;
1523         int32_t ret = 0;
1524         RingBufferNPT<Sample>::rw_vector vector;
1525         RingBufferNPT<CaptureTransition>::rw_vector transvec;
1526         jack_nframes_t total;
1527         
1528         /* important note: this function will write *AT MOST* 
1529            disk_io_chunk_frames of data to disk. it will never 
1530            write more than that. if its writes that much and there 
1531            is more than that waiting to be written, it will return 1,
1532            otherwise 0 on success or -1 on failure.
1533
1534            if there is less than disk_io_chunk_frames to be written, 
1535            no data will be written at all unless `force_flush' is true.  
1536         */
1537
1538         _write_data_count = 0;
1539
1540         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1541         
1542                 (*chan).capture_buf->get_read_vector (&vector);
1543
1544                 total = vector.len[0] + vector.len[1];
1545
1546                 
1547                 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1548                         goto out;
1549                 }
1550
1551                 
1552                 /* if there are 2+ chunks of disk i/o possible for
1553                    this track, let the caller know so that it can arrange
1554                    for us to be called again, ASAP.
1555                    
1556                    if we are forcing a flush, then if there is* any* extra
1557                    work, let the caller know.
1558
1559                    if we are no longer recording and there is any extra work,
1560                    let the caller know too.
1561                 */
1562
1563                 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1564                         ret = 1;
1565                 } 
1566
1567                 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1568                 
1569                 
1570                 // check the transition buffer when recording destructive
1571                 // important that we get this after the capture buf
1572
1573                 if (destructive()) {
1574                         (*chan).capture_transition_buf->get_read_vector(&transvec);
1575                         size_t transcount = transvec.len[0] + transvec.len[1];
1576                         bool have_start = false;
1577                         size_t ti;
1578
1579                         for (ti=0; ti < transcount; ++ti) {
1580                                 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
1581                                 
1582                                 if (captrans.type == CaptureStart) {
1583                                         // by definition, the first data we got above represents the given capture pos
1584
1585                                         (*chan).write_source->mark_capture_start (captrans.capture_val);
1586                                         (*chan).curr_capture_cnt = 0;
1587
1588                                         have_start = true;
1589                                 }
1590                                 else if (captrans.type == CaptureEnd) {
1591
1592                                         // capture end, the capture_val represents total frames in capture
1593
1594                                         if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
1595
1596                                                 // shorten to make the write a perfect fit
1597                                                 uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt); 
1598
1599                                                 if (nto_write < to_write) {
1600                                                         ret = 1; // should we?
1601                                                 }
1602                                                 to_write = nto_write;
1603
1604                                                 (*chan).write_source->mark_capture_end ();
1605                                                 
1606                                                 // increment past this transition, but go no further
1607                                                 ++ti;
1608                                                 break;
1609                                         }
1610                                         else {
1611                                                 // actually ends just beyond this chunk, so force more work
1612                                                 ret = 1;
1613                                                 break;
1614                                         }
1615                                 }
1616                         }
1617
1618                         if (ti > 0) {
1619                                 (*chan).capture_transition_buf->increment_read_ptr(ti);
1620                         }
1621                 }
1622
1623                 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
1624                         error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1625                         return -1;
1626                 }
1627
1628                 (*chan).capture_buf->increment_read_ptr (to_write);
1629                 (*chan).curr_capture_cnt += to_write;
1630                 
1631                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
1632                 
1633                         /* we wrote all of vector.len[0] but it wasn't an entire
1634                            disk_io_chunk_frames of data, so arrange for some part 
1635                            of vector.len[1] to be flushed to disk as well.
1636                         */
1637                 
1638                         to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1639                 
1640                         if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
1641                                 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1642                                 return -1;
1643                         }
1644
1645                         _write_data_count += (*chan).write_source->write_data_count();
1646         
1647                         (*chan).capture_buf->increment_read_ptr (to_write);
1648                         (*chan).curr_capture_cnt += to_write;
1649                 }
1650         }
1651
1652   out:
1653         return ret;
1654 }
1655
1656 void
1657 DiskStream::playlist_changed (Change ignored)
1658 {
1659         playlist_modified ();
1660 }
1661
1662 void
1663 DiskStream::playlist_modified ()
1664 {
1665         if (!i_am_the_modifier && !overwrite_queued) {
1666                 _session.request_overwrite_buffer (this);
1667                 overwrite_queued = true;
1668         } 
1669 }
1670
1671 void
1672 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1673 {
1674         uint32_t buffer_position;
1675         bool more_work = true;
1676         int err = 0;
1677         AudioRegion* region = 0;
1678         jack_nframes_t total_capture;
1679         AudioRegion::SourceList srcs;
1680         AudioRegion::SourceList::iterator src;
1681         ChannelList::iterator chan;
1682         vector<CaptureInfo*>::iterator ci;
1683         uint32_t n = 0; 
1684         list<Source*>* deletion_list;
1685         bool mark_write_completed = false;
1686
1687         finish_capture (true);
1688
1689         /* butler is already stopped, but there may be work to do 
1690            to flush remaining data to disk.
1691         */
1692
1693         while (more_work && !err) {
1694                 switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
1695                 case 0:
1696                         more_work = false;
1697                         break;
1698                 case 1:
1699                         break;
1700                 case -1:
1701                         error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1702                         err++;
1703                 }
1704         }
1705
1706         /* XXX is there anything we can do if err != 0 ? */
1707         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1708         
1709         if (capture_info.empty()) {
1710                 return;
1711         }
1712
1713         if (abort_capture) {
1714                 
1715                 ChannelList::iterator chan;
1716                 
1717                 deletion_list = new list<Source*>;
1718
1719                 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1720
1721                         if ((*chan).write_source) {
1722                                 
1723                                 (*chan).write_source->mark_for_remove ();
1724                                 (*chan).write_source->release ();
1725                                 
1726                                 deletion_list->push_back ((*chan).write_source);
1727
1728                                 (*chan).write_source = 0;
1729                         }
1730                         
1731                         /* new source set up in "out" below */
1732                 }
1733                 
1734                 if (!deletion_list->empty()) {
1735                         DeleteSources (deletion_list);
1736                 } else {
1737                         delete deletion_list;
1738                 }
1739
1740                 goto out;
1741         } 
1742
1743         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1744                 total_capture += (*ci)->frames;
1745         }
1746
1747         /* figure out the name for this take */
1748
1749         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1750
1751                 Source* s = (*chan).write_source;
1752                 
1753                 if (s) {
1754
1755                         FileSource* fsrc;
1756
1757                         srcs.push_back (s);
1758
1759                         if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1760                                 fsrc->update_header (capture_info.front()->start, when, twhen);
1761                         }
1762
1763                         s->set_captured_for (_name);
1764                         
1765                 }
1766         }
1767
1768         /* destructive tracks have a single, never changing region */
1769
1770         if (destructive()) {
1771
1772                 /* send a signal that any UI can pick up to do the right thing. there is 
1773                    a small problem here in that a UI may need the peak data to be ready
1774                    for the data that was recorded and this isn't interlocked with that
1775                    process. this problem is deferred to the UI.
1776                  */
1777                 
1778                 _playlist->Modified();
1779
1780         } else {
1781
1782                 /* Register a new region with the Session that
1783                    describes the entire source. Do this first
1784                    so that any sub-regions will obviously be
1785                    children of this one (later!)
1786                 */
1787                 
1788                 try {
1789                         region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, 
1790                                                   region_name_from_path (channels[0].write_source->name()), 
1791                                                   0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1792                         
1793                         region->special_set_position (capture_info.front()->start);
1794                 }
1795                 
1796                 
1797                 catch (failed_constructor& err) {
1798                         error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1799                         /* XXX what now? */
1800                 }
1801                 
1802                 _last_capture_regions.push_back (region);
1803
1804                 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1805                 
1806                 _session.add_undo (_playlist->get_memento());
1807                 _playlist->freeze ();
1808                 
1809                 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1810                         
1811                         string region_name;
1812                         _session.region_name (region_name, _name, false);
1813                         
1814                         // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1815                         
1816                         try {
1817                                 region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1818                         }
1819                         
1820                         catch (failed_constructor& err) {
1821                                 error << _("DiskStream: could not create region for captured audio!") << endmsg;
1822                                 continue; /* XXX is this OK? */
1823                         }
1824                         
1825                         _last_capture_regions.push_back (region);
1826                         
1827                         // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1828                         
1829                         i_am_the_modifier++;
1830                         _playlist->add_region (*region, (*ci)->start);
1831                         i_am_the_modifier--;
1832                         
1833                         buffer_position += (*ci)->frames;
1834                 }
1835
1836                 _playlist->thaw ();
1837                 _session.add_redo_no_execute (_playlist->get_memento());
1838         }
1839
1840         mark_write_completed = true;
1841
1842         reset_write_sources (mark_write_completed);
1843
1844   out:
1845         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1846                 delete *ci;
1847         }
1848
1849         capture_info.clear ();
1850         capture_start_frame = 0;
1851 }
1852
1853 void
1854 DiskStream::finish_capture (bool rec_monitors_input)
1855 {
1856         was_recording = false;
1857         
1858         if (capture_captured == 0) {
1859                 return;
1860         }
1861
1862         if (recordable() && destructive()) {
1863                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1864                         
1865                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
1866                         (*chan).capture_transition_buf->get_write_vector(&transvec);
1867                         
1868                         
1869                         if (transvec.len[0] > 0) {
1870                                 transvec.buf[0]->type = CaptureEnd;
1871                                 transvec.buf[0]->capture_val = capture_captured;
1872                                 (*chan).capture_transition_buf->increment_write_ptr(1);
1873                         }
1874                         else {
1875                                 // bad!
1876                                 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
1877                         }
1878                 }
1879         }
1880         
1881         
1882         CaptureInfo* ci = new CaptureInfo;
1883         
1884         ci->start =  capture_start_frame;
1885         ci->frames = capture_captured;
1886         
1887         /* XXX theoretical race condition here. Need atomic exchange ? 
1888            However, the circumstances when this is called right 
1889            now (either on record-disable or transport_stopped)
1890            mean that no actual race exists. I think ...
1891            We now have a capture_info_lock, but it is only to be used
1892            to synchronize in the transport_stop and the capture info
1893            accessors, so that invalidation will not occur (both non-realtime).
1894         */
1895
1896         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1897
1898         capture_info.push_back (ci);
1899         capture_captured = 0;
1900 }
1901
1902 void
1903 DiskStream::set_record_enabled (bool yn, void* src)
1904 {
1905         bool rolling = _session.transport_speed() != 0.0f;
1906
1907         if (!recordable() || !_session.record_enabling_legal()) {
1908                 return;
1909         }
1910         
1911         /* if we're turning on rec-enable, there needs to be an
1912            input connection.
1913          */
1914
1915         if (yn && channels[0].source == 0) {
1916
1917                 /* pick up connections not initiated *from* the IO object
1918                    we're associated with.
1919                 */
1920
1921                 get_input_sources ();
1922
1923                 if (channels[0].source == 0) {
1924                 
1925                         if (yn) {
1926                                 CannotRecordNoInput (this); /* emit signal */
1927                         }
1928                         return;
1929                 }
1930         }
1931
1932         /* yes, i know that this not proof against race conditions, but its
1933            good enough. i think.
1934         */
1935
1936         if (record_enabled() != yn) {
1937                 if (yn) {
1938                         atomic_set (&_record_enabled, 1);
1939                         capturing_sources.clear ();
1940                         if (Config->get_use_hardware_monitoring())  {
1941                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1942                                         if ((*chan).source) {
1943                                                 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1944                                         }
1945                                         capturing_sources.push_back ((*chan).write_source);
1946                                 }
1947                         } else {
1948                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1949                                         capturing_sources.push_back ((*chan).write_source);
1950                                 }
1951                         }
1952
1953                 } else {
1954                         atomic_set (&_record_enabled, 0);
1955                         if (Config->get_use_hardware_monitoring()) {
1956                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1957                                         if ((*chan).source) {
1958                                                 (*chan).source->request_monitor_input (false);
1959                                         }
1960                                 }
1961                         }
1962                         capturing_sources.clear ();
1963                 }
1964
1965                 record_enable_changed (src); /* EMIT SIGNAL */
1966         }
1967 }
1968
1969 XMLNode&
1970 DiskStream::get_state ()
1971 {
1972         XMLNode* node = new XMLNode ("DiskStream");
1973         char buf[64];
1974         LocaleGuard lg (X_("POSIX"));
1975
1976         snprintf (buf, sizeof(buf), "0x%x", _flags);
1977         node->add_property ("flags", buf);
1978
1979         snprintf (buf, sizeof(buf), "%zd", channels.size());
1980         node->add_property ("channels", buf);
1981
1982         node->add_property ("playlist", _playlist->name());
1983         
1984         snprintf (buf, sizeof(buf), "%f", _visible_speed);
1985         node->add_property ("speed", buf);
1986
1987         node->add_property("name", _name);
1988         snprintf (buf, sizeof(buf), "%" PRIu64, id());
1989         node->add_property("id", buf);
1990
1991         if (!capturing_sources.empty() && _session.get_record_enabled()) {
1992
1993                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1994                 XMLNode* cs_grandchild;
1995
1996                 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1997                         cs_grandchild = new XMLNode (X_("file"));
1998                         cs_grandchild->add_property (X_("path"), (*i)->path());
1999                         cs_child->add_child_nocopy (*cs_grandchild);
2000                 }
2001
2002                 /* store the location where capture will start */
2003
2004                 Location* pi;
2005
2006                 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
2007                         snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
2008                 } else {
2009                         snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
2010                 }
2011
2012                 cs_child->add_property (X_("at"), buf);
2013                 node->add_child_nocopy (*cs_child);
2014         }
2015
2016         if (_extra_xml) {
2017                 node->add_child_copy (*_extra_xml);
2018         }
2019
2020         return* node;
2021 }
2022
2023 int
2024 DiskStream::set_state (const XMLNode& node)
2025 {
2026         const XMLProperty* prop;
2027         XMLNodeList nlist = node.children();
2028         XMLNodeIterator niter;
2029         uint32_t nchans = 1;
2030         XMLNode* capture_pending_node = 0;
2031         LocaleGuard lg (X_("POSIX"));
2032
2033         in_set_state = true;
2034
2035         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2036                 if ((*niter)->name() == IO::state_node_name) {
2037                         deprecated_io_node = new XMLNode (**niter);
2038                 }
2039
2040                 if ((*niter)->name() == X_("CapturingSources")) {
2041                         capture_pending_node = *niter;
2042                 }
2043         }
2044
2045         /* prevent write sources from being created */
2046         
2047         in_set_state = true;
2048         
2049         if ((prop = node.property ("name")) != 0) {
2050                 _name = prop->value();
2051         } 
2052
2053         if (deprecated_io_node) {
2054                 if ((prop = deprecated_io_node->property ("id")) != 0) {
2055                         sscanf (prop->value().c_str(), "%" PRIu64, &_id);
2056                 }
2057         } else {
2058                 if ((prop = node.property ("id")) != 0) {
2059                         sscanf (prop->value().c_str(), "%" PRIu64, &_id);
2060                 }
2061         }
2062
2063         if ((prop = node.property ("flags")) != 0) {
2064                 _flags = strtol (prop->value().c_str(), 0, 0);
2065         }
2066
2067         if ((prop = node.property ("channels")) != 0) {
2068                 nchans = atoi (prop->value().c_str());
2069         }
2070         
2071         // create necessary extra channels
2072         // we are always constructed with one
2073         // and we always need one
2074
2075         if (nchans > _n_channels) {
2076
2077                 // we need to add new channel infos
2078                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
2079
2080                 int diff = nchans - channels.size();
2081
2082                 for (int i=0; i < diff; ++i) {
2083                         add_channel ();
2084                 }
2085
2086         } else if (nchans < _n_channels) {
2087
2088                 // we need to get rid of channels
2089                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
2090
2091                 int diff = channels.size() - nchans;
2092                 
2093                 for (int i = 0; i < diff; ++i) {
2094                         remove_channel ();
2095                 }
2096         }
2097
2098         if ((prop = node.property ("playlist")) == 0) {
2099                 return -1;
2100         }
2101
2102         {
2103                 bool had_playlist = (_playlist != 0);
2104         
2105                 if (find_and_use_playlist (prop->value())) {
2106                         return -1;
2107                 }
2108
2109                 if (!had_playlist) {
2110                         _playlist->set_orig_diskstream_id (_id);
2111                 }
2112                 
2113                 if (!destructive() && capture_pending_node) {
2114                         /* destructive streams have one and only one source per channel,
2115                            and so they never end up in pending capture in any useful
2116                            sense.
2117                         */
2118                         use_pending_capture_data (*capture_pending_node);
2119                 }
2120
2121         }
2122
2123         if ((prop = node.property ("speed")) != 0) {
2124                 double sp = atof (prop->value().c_str());
2125
2126                 if (realtime_set_speed (sp, false)) {
2127                         non_realtime_set_speed ();
2128                 }
2129         }
2130
2131         _n_channels = channels.size();
2132
2133         in_set_state = false;
2134
2135         /* make sure this is clear before we do anything else */
2136
2137         capturing_sources.clear ();
2138
2139         /* write sources are handled when we handle the input set 
2140            up of the IO that owns this DS (::non_realtime_input_change())
2141         */
2142                 
2143         in_set_state = false;
2144
2145         return 0;
2146 }
2147
2148 int
2149 DiskStream::use_new_write_source (uint32_t n)
2150 {
2151         if (!recordable()) {
2152                 return 1;
2153         }
2154
2155         if (n >= channels.size()) {
2156                 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
2157                 return -1;
2158         }
2159
2160         ChannelInfo &chan = channels[n];
2161         
2162         if (chan.write_source) {
2163
2164                 if (FileSource::is_empty (chan.write_source->path())) {
2165                         chan.write_source->mark_for_remove ();
2166                         chan.write_source->release();
2167                         delete chan.write_source;
2168                 } else {
2169                         chan.write_source->release();
2170                         chan.write_source = 0;
2171                 }
2172         }
2173
2174         try {
2175                 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
2176                         throw failed_constructor();
2177                 }
2178         } 
2179
2180         catch (failed_constructor &err) {
2181                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
2182                 chan.write_source = 0;
2183                 return -1;
2184         }
2185
2186         chan.write_source->use ();
2187
2188         /* do not remove destructive files even if they are empty */
2189
2190         chan.write_source->set_allow_remove_if_empty (!destructive());
2191
2192         return 0;
2193 }
2194
2195 void
2196 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2197 {
2198         ChannelList::iterator chan;
2199         uint32_t n;
2200
2201         if (!recordable()) {
2202                 return;
2203         }
2204         
2205         capturing_sources.clear ();
2206         
2207         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2208                 if (!destructive()) {
2209
2210                         if ((*chan).write_source && mark_write_complete) {
2211                                 (*chan).write_source->mark_streaming_write_completed ();
2212                         }
2213                         use_new_write_source (n);
2214
2215                         if (record_enabled()) {
2216                                 capturing_sources.push_back ((*chan).write_source);
2217                         }
2218
2219                 } else {
2220                         if ((*chan).write_source == 0) {
2221                                 use_new_write_source (n);
2222                         }
2223                 }
2224         }
2225
2226         if (destructive()) {
2227
2228                 /* we now have all our write sources set up, so create the
2229                    playlist's single region.
2230                 */
2231
2232                 if (_playlist->empty()) {
2233                         setup_destructive_playlist ();
2234                 }
2235         }
2236 }
2237
2238 int
2239 DiskStream::rename_write_sources ()
2240 {
2241         ChannelList::iterator chan;
2242         uint32_t n;
2243
2244         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2245                 if ((*chan).write_source != 0) {
2246                         (*chan).write_source->set_name (_name, destructive());
2247                         /* XXX what to do if one of them fails ? */
2248                 }
2249         }
2250
2251         return 0;
2252 }
2253
2254 void
2255 DiskStream::set_block_size (jack_nframes_t nframes)
2256 {
2257         if (_session.get_block_size() > speed_buffer_size) {
2258                 speed_buffer_size = _session.get_block_size();
2259
2260                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2261                         if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2262                         (*chan).speed_buffer = new Sample[speed_buffer_size];
2263                 }
2264         }
2265         allocate_temporary_buffers ();
2266 }
2267
2268 void
2269 DiskStream::allocate_temporary_buffers ()
2270 {
2271         /* make sure the wrap buffer is at least large enough to deal
2272            with the speeds up to 1.2, to allow for micro-variation
2273            when slaving to MTC, SMPTE etc.
2274         */
2275
2276         double sp = max (fabsf (_actual_speed), 1.2f);
2277         jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2278
2279         if (required_wrap_size > wrap_buffer_size) {
2280
2281                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2282                         if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2283                         (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
2284                         if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2285                         (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
2286                 }
2287
2288                 wrap_buffer_size = required_wrap_size;
2289         }
2290 }
2291
2292 void
2293 DiskStream::monitor_input (bool yn)
2294 {
2295         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2296                 
2297                 if ((*chan).source) {
2298                         (*chan).source->request_monitor_input (yn);
2299                 }
2300         }
2301 }
2302
2303 void
2304 DiskStream::set_capture_offset ()
2305 {
2306         if (_io == 0) {
2307                 /* can't capture, so forget it */
2308                 return;
2309         }
2310
2311         _capture_offset = _io->input_latency();
2312 }
2313
2314 void
2315 DiskStream::set_persistent_align_style (AlignStyle a)
2316 {
2317         _persistent_alignment_style = a;
2318 }
2319
2320 void
2321 DiskStream::set_align_style_from_io ()
2322 {
2323         bool have_physical = false;
2324
2325         if (_io == 0) {
2326                 return;
2327         }
2328
2329         get_input_sources ();
2330         
2331         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2332                 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2333                         have_physical = true;
2334                         break;
2335                 }
2336         }
2337
2338         if (have_physical) {
2339                 set_align_style (ExistingMaterial);
2340         } else {
2341                 set_align_style (CaptureTime);
2342         }
2343 }
2344
2345 void
2346 DiskStream::set_align_style (AlignStyle a)
2347 {
2348         if (record_enabled() && _session.actively_recording()) {
2349                 return;
2350         }
2351
2352
2353         if (a != _alignment_style) {
2354                 _alignment_style = a;
2355                 AlignmentStyleChanged ();
2356         }
2357 }
2358
2359 int
2360 DiskStream::add_channel ()
2361 {
2362         /* XXX need to take lock??? */
2363
2364         ChannelInfo chan;
2365
2366         init_channel (chan);
2367
2368         chan.speed_buffer = new Sample[speed_buffer_size];
2369         chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2370         chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2371
2372         channels.push_back (chan);
2373
2374         _n_channels = channels.size();
2375
2376         return 0;
2377 }
2378
2379 int
2380 DiskStream::remove_channel ()
2381 {
2382         if (channels.size() > 1) {
2383                 /* XXX need to take lock??? */
2384                 ChannelInfo & chan = channels.back();
2385                 destroy_channel (chan);
2386                 channels.pop_back();
2387
2388                 _n_channels = channels.size();
2389                 return 0;
2390         }
2391
2392         return -1;
2393 }
2394
2395 float
2396 DiskStream::playback_buffer_load () const
2397 {
2398         return (float) ((double) channels.front().playback_buf->read_space()/
2399                         (double) channels.front().playback_buf->bufsize());
2400 }
2401
2402 float
2403 DiskStream::capture_buffer_load () const
2404 {
2405         return (float) ((double) channels.front().capture_buf->write_space()/
2406                         (double) channels.front().capture_buf->bufsize());
2407 }
2408
2409 int
2410 DiskStream::set_loop (Location *location)
2411 {
2412         if (location) {
2413                 if (location->start() >= location->end()) {
2414                         error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2415                         return -1;
2416                 }
2417         }
2418
2419         loop_location = location;
2420
2421          LoopSet (location); /* EMIT SIGNAL */
2422         return 0;
2423 }
2424
2425 jack_nframes_t
2426 DiskStream::get_capture_start_frame (uint32_t n)
2427 {
2428         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2429
2430         if (capture_info.size() > n) {
2431                 return capture_info[n]->start;
2432         }
2433         else {
2434                 return capture_start_frame;
2435         }
2436 }
2437
2438 jack_nframes_t
2439 DiskStream::get_captured_frames (uint32_t n)
2440 {
2441         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2442
2443         if (capture_info.size() > n) {
2444                 return capture_info[n]->frames;
2445         }
2446         else {
2447                 return capture_captured;
2448         }
2449 }
2450
2451 void
2452 DiskStream::punch_in ()
2453 {
2454 }
2455
2456 void
2457 DiskStream::punch_out ()
2458 {
2459 }
2460
2461 int
2462 DiskStream::use_pending_capture_data (XMLNode& node)
2463 {
2464         const XMLProperty* prop;
2465         XMLNodeList nlist = node.children();
2466         XMLNodeIterator niter;
2467         FileSource* fs;
2468         FileSource* first_fs = 0;
2469         AudioRegion::SourceList pending_sources;
2470         jack_nframes_t position;
2471
2472         if ((prop = node.property (X_("at"))) == 0) {
2473                 return -1;
2474         }
2475
2476         if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2477                 return -1;
2478         }
2479
2480         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2481                 if ((*niter)->name() == X_("file")) {
2482
2483                         if ((prop = (*niter)->property (X_("path"))) == 0) {
2484                                 continue;
2485                         }
2486
2487                         try {
2488                                 fs = new FileSource (prop->value(), _session.frame_rate(), true, Config->get_native_file_data_format());
2489                         }
2490
2491                         catch (failed_constructor& err) {
2492                                 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2493                                                   _name, prop->value())
2494                                       << endmsg;
2495                                 return -1;
2496                         }
2497
2498                         pending_sources.push_back (fs);
2499                         
2500                         if (first_fs == 0) {
2501                                 first_fs = fs;
2502                         }
2503
2504                         fs->set_captured_for (_name);
2505                 }
2506         }
2507
2508         if (pending_sources.size() == 0) {
2509                 /* nothing can be done */
2510                 return 1;
2511         }
2512
2513         if (pending_sources.size() != _n_channels) {
2514                 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2515                       << endmsg;
2516                 return -1;
2517         }
2518
2519         AudioRegion* region;
2520         
2521         try {
2522                 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2523                                           region_name_from_path (first_fs->name()), 
2524                                           0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2525                 
2526                 region->special_set_position (0);
2527         }
2528
2529         catch (failed_constructor& err) {
2530                 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2531                                   _name)
2532                       << endmsg;
2533                 
2534                 return -1;
2535         }
2536
2537         try {
2538                 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2539         }
2540
2541         catch (failed_constructor& err) {
2542                 error << string_compose (_("%1: cannot create region from pending capture sources"),
2543                                   _name)
2544                       << endmsg;
2545                 
2546                 return -1;
2547         }
2548
2549         _playlist->add_region (*region, position);
2550
2551         return 0;
2552 }
2553
2554 void
2555 DiskStream::set_roll_delay (jack_nframes_t nframes)
2556 {
2557         _roll_delay = nframes;
2558 }
2559
2560 void
2561 DiskStream::set_destructive (bool yn)
2562 {
2563         if (yn != destructive()) {
2564                 reset_write_sources (true, true);
2565                 if (yn) {
2566                         _flags |= Destructive;
2567                 } else {
2568                         _flags &= ~Destructive;
2569                 }
2570         }
2571 }