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