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