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