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