b19f25be72ba1fed9c91c89db6ef9cf71045fe19
[ardour.git] / libs / ardour / diskstream.cc
1 /*
2     Copyright (C) 2000-2003 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <fstream>
22 #include <cstdio>
23 #include <unistd.h>
24 #include <cmath>
25 #include <cerrno>
26 #include <string>
27 #include <climits>
28 #include <fcntl.h>
29 #include <cstdlib>
30 #include <ctime>
31 #include <sys/stat.h>
32 #include <sys/mman.h>
33
34 #include <pbd/error.h>
35 #include <pbd/basename.h>
36 #include <pbd/lockmonitor.h>
37 #include <pbd/xml++.h>
38
39 #include <ardour/ardour.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/diskstream.h>
42 #include <ardour/utils.h>
43 #include <ardour/configuration.h>
44 #include <ardour/filesource.h>
45 #include <ardour/destructive_filesource.h>
46 #include <ardour/send.h>
47 #include <ardour/audioplaylist.h>
48 #include <ardour/cycle_timer.h>
49 #include <ardour/audioregion.h>
50
51 #include "i18n.h"
52 #include <locale.h>
53
54 using namespace std;
55 using namespace ARDOUR;
56
57 jack_nframes_t DiskStream::disk_io_chunk_frames;
58
59 sigc::signal<void,DiskStream*>    DiskStream::DiskStreamCreated;
60 sigc::signal<void,DiskStream*>    DiskStream::CannotRecordNoInput;
61 sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
62 sigc::signal<void>                DiskStream::DiskOverrun;
63 sigc::signal<void>                DiskStream::DiskUnderrun;
64
65 DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
66         : _name (name),
67           _session (sess)
68 {
69         /* prevent any write sources from being created */
70
71         in_set_state = true;
72         init (flag);
73         use_new_playlist ();
74         in_set_state = false;
75
76         DiskStreamCreated (this); /* EMIT SIGNAL */
77 }
78         
79 DiskStream::DiskStream (Session& sess, const XMLNode& node)
80         : _session (sess)
81         
82 {
83         in_set_state = true;
84         init (Recordable);
85
86         if (set_state (node)) {
87                 in_set_state = false;
88                 throw failed_constructor();
89         }
90
91         in_set_state = false;
92
93         DiskStreamCreated (this); /* EMIT SIGNAL */
94 }
95
96 void
97 DiskStream::init_channel (ChannelInfo &chan)
98 {
99         chan.playback_wrap_buffer = 0;
100         chan.capture_wrap_buffer = 0;
101         chan.speed_buffer = 0;
102         chan.peak_power = 0.0f;
103         chan.write_source = 0;
104         chan.source = 0;
105         chan.current_capture_buffer = 0;
106         chan.current_playback_buffer = 0;
107         
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                 if (destructive()) {
1064                         DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> ((*chan).write_source);
1065                         dfs->seek (frame);
1066                 }
1067         }
1068         
1069         playback_sample = frame;
1070         file_frame = frame;
1071
1072         if (complete_refill) {
1073                 while ((ret = do_refill (0, 0)) > 0);
1074         } else {
1075                 ret = do_refill (0, 0);
1076         }
1077
1078         return ret;
1079 }
1080
1081 int
1082 DiskStream::can_internal_playback_seek (jack_nframes_t distance)
1083 {
1084         ChannelList::iterator chan;
1085
1086         for (chan = channels.begin(); chan != channels.end(); ++chan) {
1087                 if ((*chan).playback_buf->read_space() < distance) {
1088                         return false;
1089                 } 
1090         }
1091         return true;
1092 }
1093
1094 int
1095 DiskStream::internal_playback_seek (jack_nframes_t distance)
1096 {
1097         ChannelList::iterator chan;
1098
1099         for (chan = channels.begin(); chan != channels.end(); ++chan) {
1100                 (*chan).playback_buf->increment_read_ptr (distance);
1101         }
1102
1103         first_recordable_frame += distance;
1104         playback_sample += distance;
1105         
1106         return 0;
1107 }
1108
1109 int
1110 DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt, 
1111
1112                   ChannelInfo& channel_info, int channel, bool reversed)
1113 {
1114         jack_nframes_t this_read = 0;
1115         bool reloop = false;
1116         jack_nframes_t loop_end = 0;
1117         jack_nframes_t loop_start = 0;
1118         jack_nframes_t loop_length = 0;
1119         jack_nframes_t offset = 0;
1120         Location *loc = 0;
1121
1122         if (!reversed) {
1123                 /* Make the use of a Location atomic for this read operation.
1124                    
1125                    Note: Locations don't get deleted, so all we care about
1126                    when I say "atomic" is that we are always pointing to
1127                    the same one and using a start/length values obtained
1128                    just once.
1129                 */
1130                 
1131                 if ((loc = loop_location) != 0) {
1132                         loop_start = loc->start();
1133                         loop_end = loc->end();
1134                         loop_length = loop_end - loop_start;
1135                 }
1136                 
1137                 /* if we are looping, ensure that the first frame we read is at the correct
1138                    position within the loop.
1139                 */
1140                 
1141                 if (loc && start >= loop_end) {
1142                         //cerr << "start adjusted from " << start;
1143                         start = loop_start + ((start - loop_start) % loop_length);
1144                         //cerr << "to " << start << endl;
1145                 }
1146                 //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
1147         }
1148
1149         while (cnt) {
1150
1151                 /* take any loop into account. we can't read past the end of the loop. */
1152
1153                 if (loc && (loop_end - start < cnt)) {
1154                         this_read = loop_end - start;
1155                         //cerr << "reloop true: thisread: " << this_read << "  cnt: " << cnt << endl;
1156                         reloop = true;
1157                 } else {
1158                         reloop = false;
1159                         this_read = cnt;
1160                 }
1161
1162                 if (this_read == 0) {
1163                         break;
1164                 }
1165
1166                 this_read = min(cnt,this_read);
1167
1168                 if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
1169                         error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read, 
1170                                          start) << endmsg;
1171                         return -1;
1172                 }
1173
1174                 _read_data_count = _playlist->read_data_count();
1175                 
1176                 if (reversed) {
1177
1178                         /* don't adjust start, since caller has already done that
1179                          */
1180
1181                         swap_by_ptr (buf, buf + this_read - 1);
1182                         
1183                 } else {
1184                         
1185                         /* if we read to the end of the loop, go back to the beginning */
1186                         
1187                         if (reloop) {
1188                                 start = loop_start;
1189                         } else {
1190                                 start += this_read;
1191                         }
1192                 } 
1193
1194                 cnt -= this_read;
1195                 offset += this_read;
1196         }
1197
1198         return 0;
1199 }
1200
1201 int
1202 DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
1203 {
1204         int32_t ret = 0;
1205         jack_nframes_t to_read;
1206         RingBufferNPT<Sample>::rw_vector vector;
1207         bool free_mixdown;
1208         bool free_gain;
1209         bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1210         jack_nframes_t total_space;
1211         jack_nframes_t zero_fill;
1212         uint32_t chan_n;
1213         ChannelList::iterator i;
1214         jack_nframes_t ts;
1215
1216         channels.front().playback_buf->get_write_vector (&vector);
1217         
1218         if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1219                 return 0;
1220         }
1221         
1222         /* if there are 2+ chunks of disk i/o possible for
1223            this track, let the caller know so that it can arrange
1224            for us to be called again, ASAP.
1225         */
1226         
1227         if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1228                 ret = 1;
1229         }
1230         
1231         /* if we're running close to normal speed and there isn't enough 
1232            space to do disk_io_chunk_frames of I/O, then don't bother.  
1233            
1234            at higher speeds, just do it because the sync between butler
1235            and audio thread may not be good enough.
1236         */
1237         
1238         if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1239                 return 0;
1240         }
1241         
1242         /* when slaved, don't try to get too close to the read pointer. this
1243            leaves space for the buffer reversal to have something useful to
1244            work with.
1245         */
1246         
1247         if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1248                 return 0;
1249         }
1250
1251         total_space = min (disk_io_chunk_frames, total_space);
1252
1253         if (reversed) {
1254
1255                 if (file_frame == 0) {
1256
1257                         /* at start: nothing to do but fill with silence */
1258
1259                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1260                                         
1261                                 ChannelInfo& chan (*i);
1262                                 chan.playback_buf->get_write_vector (&vector);
1263                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1264                                 if (vector.len[1]) {
1265                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1266                                 }
1267                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1268                         }
1269                         return 0;
1270                 }
1271
1272                 if (file_frame < total_space) {
1273
1274                         /* too close to the start: read what we can, 
1275                            and then zero fill the rest 
1276                         */
1277
1278                         zero_fill = total_space - file_frame;
1279                         total_space = file_frame;
1280                         file_frame = 0;
1281
1282                 } else {
1283                         
1284                         /* move read position backwards because we are going
1285                            to reverse the data.
1286                         */
1287                         
1288                         file_frame -= total_space;
1289                         zero_fill = 0;
1290                 }
1291
1292         } else {
1293
1294                 if (file_frame == max_frames) {
1295
1296                         /* at end: nothing to do but fill with silence */
1297                         
1298                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1299                                         
1300                                 ChannelInfo& chan (*i);
1301                                 chan.playback_buf->get_write_vector (&vector);
1302                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1303                                 if (vector.len[1]) {
1304                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1305                                 }
1306                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1307                         }
1308                         return 0;
1309                 }
1310                 
1311                 if (file_frame > max_frames - total_space) {
1312
1313                         /* to close to the end: read what we can, and zero fill the rest */
1314
1315                         zero_fill = total_space - (max_frames - file_frame);
1316                         total_space = max_frames - file_frame;
1317
1318                 } else {
1319                         zero_fill = 0;
1320                 }
1321         }
1322
1323         /* Please note: the code to allocate buffers isn't run
1324            during normal butler thread operation. Its there
1325            for other times when we need to call do_refill()
1326            from somewhere other than the butler thread.
1327         */
1328
1329         if (mixdown_buffer == 0) {
1330                 mixdown_buffer = new Sample[disk_io_chunk_frames];
1331                 free_mixdown = true;
1332         } else {
1333                 free_mixdown = false;
1334         }
1335
1336         if (gain_buffer == 0) {
1337                 gain_buffer = new float[disk_io_chunk_frames];
1338                 free_gain = true;
1339         } else {
1340                 free_gain = false;
1341         }
1342
1343         jack_nframes_t file_frame_tmp = 0;
1344
1345         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1346
1347                 ChannelInfo& chan (*i);
1348                 Sample* buf1;
1349                 Sample* buf2;
1350                 jack_nframes_t len1, len2;
1351
1352                 chan.playback_buf->get_write_vector (&vector);
1353
1354                 ts = total_space;
1355                 file_frame_tmp = file_frame;
1356
1357                 if (reversed) {
1358                         buf1 = vector.buf[1];
1359                         len1 = vector.len[1];
1360                         buf2 = vector.buf[0];
1361                         len2 = vector.len[0];
1362                 } else {
1363                         buf1 = vector.buf[0];
1364                         len1 = vector.len[0];
1365                         buf2 = vector.buf[1];
1366                         len2 = vector.len[1];
1367                 }
1368
1369
1370                 to_read = min (ts, len1);
1371                 to_read = min (to_read, disk_io_chunk_frames);
1372
1373                 if (to_read) {
1374
1375                         if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1376                                 ret = -1;
1377                                 goto out;
1378                         }
1379                         
1380                         chan.playback_buf->increment_write_ptr (to_read);
1381                         ts -= to_read;
1382                 }
1383
1384                 to_read = min (ts, len2);
1385
1386                 if (to_read) {
1387
1388                         
1389                         /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1390                            so read some or all of vector.len[1] as well.
1391                         */
1392
1393                         if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1394                                 ret = -1;
1395                                 goto out;
1396                         }
1397                 
1398                         chan.playback_buf->increment_write_ptr (to_read);
1399                 }
1400
1401                 if (zero_fill) {
1402                         /* do something */
1403                 }
1404
1405         }
1406         
1407         file_frame = file_frame_tmp;
1408
1409   out:
1410         if (free_mixdown) {
1411                 delete [] mixdown_buffer;
1412         }
1413         if (free_gain) {
1414                 delete [] gain_buffer;
1415         }
1416
1417         return ret;
1418 }       
1419
1420 int
1421 DiskStream::do_flush (bool force_flush)
1422 {
1423         uint32_t to_write;
1424         int32_t ret = 0;
1425         RingBufferNPT<Sample>::rw_vector vector;
1426         jack_nframes_t total;
1427         
1428         /* important note: this function will write *AT MOST* 
1429            disk_io_chunk_frames of data to disk. it will never 
1430            write more than that. if its writes that much and there 
1431            is more than that waiting to be written, it will return 1,
1432            otherwise 0 on success or -1 on failure.
1433
1434            if there is less than disk_io_chunk_frames to be written, 
1435            no data will be written at all unless `force_flush' is true.  
1436         */
1437
1438         _write_data_count = 0;
1439
1440         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1441         
1442                 (*chan).capture_buf->get_read_vector (&vector);
1443
1444                 total = vector.len[0] + vector.len[1];
1445
1446                 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1447                         goto out;
1448                 }
1449
1450                 /* if there are 2+ chunks of disk i/o possible for
1451                    this track, let the caller know so that it can arrange
1452                    for us to be called again, ASAP.
1453                    
1454                    if we are forcing a flush, then if there is* any* extra
1455                    work, let the caller know.
1456
1457                    if we are no longer recording and there is any extra work,
1458                    let the caller know too.
1459                 */
1460
1461                 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1462                         ret = 1;
1463                 } 
1464
1465                 to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
1466         
1467                 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
1468                         error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1469                         return -1;
1470                 }
1471
1472                 (*chan).capture_buf->increment_read_ptr (to_write);
1473
1474                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames)) {
1475                 
1476                         /* we wrote all of vector.len[0] but it wasn't an entire
1477                            disk_io_chunk_frames of data, so arrange for some part 
1478                            of vector.len[1] to be flushed to disk as well.
1479                         */
1480                 
1481                         to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
1482                 
1483                         if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
1484                                 error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
1485                                 return -1;
1486                         }
1487
1488                         _write_data_count += (*chan).write_source->write_data_count();
1489         
1490                         (*chan).capture_buf->increment_read_ptr (to_write);
1491                 }
1492         }
1493
1494   out:
1495         return ret;
1496 }
1497
1498 void
1499 DiskStream::playlist_changed (Change ignored)
1500 {
1501         playlist_modified ();
1502 }
1503
1504 void
1505 DiskStream::playlist_modified ()
1506 {
1507         if (!i_am_the_modifier && !overwrite_queued) {
1508                 _session.request_overwrite_buffer (this);
1509                 overwrite_queued = true;
1510         } 
1511 }
1512
1513 void
1514 DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1515 {
1516         uint32_t buffer_position;
1517         bool more_work = true;
1518         int err = 0;
1519         AudioRegion* region = 0;
1520         jack_nframes_t total_capture;
1521         AudioRegion::SourceList srcs;
1522         AudioRegion::SourceList::iterator src;
1523         ChannelList::iterator chan;
1524         vector<CaptureInfo*>::iterator ci;
1525         uint32_t n = 0; 
1526         list<Source*>* deletion_list;
1527         bool mark_write_completed = false;
1528
1529         finish_capture (true);
1530
1531         /* butler is already stopped, but there may be work to do 
1532            to flush remaining data to disk.
1533         */
1534
1535         while (more_work && !err) {
1536                 switch (do_flush (true)) {
1537                 case 0:
1538                         more_work = false;
1539                         break;
1540                 case 1:
1541                         break;
1542                 case -1:
1543                         error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1544                         err++;
1545                 }
1546         }
1547
1548         /* XXX is there anything we can do if err != 0 ? */
1549         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
1550         
1551         if (capture_info.empty()) {
1552                 return;
1553         }
1554
1555         if (abort_capture) {
1556                 
1557                 ChannelList::iterator chan;
1558                 
1559                 deletion_list = new list<Source*>;
1560
1561                 for ( chan = channels.begin(); chan != channels.end(); ++chan) {
1562
1563                         if ((*chan).write_source) {
1564                                 
1565                                 (*chan).write_source->mark_for_remove ();
1566                                 (*chan).write_source->release ();
1567                                 
1568                                 deletion_list->push_back ((*chan).write_source);
1569
1570                                 (*chan).write_source = 0;
1571                         }
1572                         
1573                         /* new source set up in "out" below */
1574                 }
1575                 
1576                 if (!deletion_list->empty()) {
1577                         DeleteSources (deletion_list);
1578                 } else {
1579                         delete deletion_list;
1580                 }
1581
1582                 goto out;
1583         } 
1584
1585         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1586                 total_capture += (*ci)->frames;
1587         }
1588
1589         /* figure out the name for this take */
1590
1591         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1592
1593                 Source* s = (*chan).write_source;
1594                 
1595                 if (s) {
1596
1597                         FileSource* fsrc;
1598
1599                         srcs.push_back (s);
1600
1601                         if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
1602                                 fsrc->update_header (capture_info.front()->start, when, twhen);
1603                         }
1604
1605                         s->set_captured_for (_name);
1606                         
1607                 }
1608         }
1609
1610         /* Register a new region with the Session that
1611            describes the entire source. Do this first
1612            so that any sub-regions will obviously be
1613            children of this one (later!)
1614         */
1615
1616         try {
1617                 region = new AudioRegion (srcs, 0, total_capture, 
1618                                           region_name_from_path (channels[0].write_source->name()), 
1619                                           0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
1620
1621                 region->special_set_position (capture_info.front()->start);
1622         }
1623         
1624         catch (failed_constructor& err) {
1625                 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1626                 /* XXX what now? */
1627         }
1628
1629         _last_capture_regions.push_back (region);
1630
1631         // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1632
1633         _session.add_undo (_playlist->get_memento());
1634         _playlist->freeze ();
1635                 
1636         for (buffer_position = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1637
1638                 string region_name;
1639                 _session.region_name (region_name, _name, false);
1640
1641                 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
1642
1643                 try {
1644                         region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
1645                 }
1646                 
1647                 catch (failed_constructor& err) {
1648                         error << _("DiskStream: could not create region for captured audio!") << endmsg;
1649                         continue; /* XXX is this OK? */
1650                 }
1651
1652                 _last_capture_regions.push_back (region);
1653                 
1654                 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1655
1656                 i_am_the_modifier++;
1657                 _playlist->add_region (*region, (*ci)->start);
1658                 i_am_the_modifier--;
1659
1660                 buffer_position += (*ci)->frames;
1661         }
1662
1663         _playlist->thaw ();
1664         _session.add_redo_no_execute (_playlist->get_memento());
1665
1666         mark_write_completed = true;
1667
1668         reset_write_sources (mark_write_completed);
1669
1670   out:
1671         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1672                 delete *ci;
1673         }
1674
1675         capture_info.clear ();
1676         capture_start_frame = 0;
1677 }
1678
1679 void
1680 DiskStream::finish_capture (bool rec_monitors_input)
1681 {
1682         was_recording = false;
1683         
1684         if (capture_captured == 0) {
1685                 return;
1686         }
1687                 
1688         CaptureInfo* ci = new CaptureInfo;
1689         
1690         ci->start =  capture_start_frame;
1691         ci->frames = capture_captured;
1692         
1693         /* XXX theoretical race condition here. Need atomic exchange ? 
1694            However, the circumstances when this is called right 
1695            now (either on record-disable or transport_stopped)
1696            mean that no actual race exists. I think ...
1697            We now have a capture_info_lock, but it is only to be used
1698            to synchronize in the transport_stop and the capture info
1699            accessors, so that invalidation will not occur (both non-realtime).
1700         */
1701
1702         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1703
1704         capture_info.push_back (ci);
1705         capture_captured = 0;
1706 }
1707
1708 void
1709 DiskStream::set_record_enabled (bool yn, void* src)
1710 {
1711         bool rolling = _session.transport_speed() != 0.0f;
1712
1713         if (!recordable() || !_session.record_enabling_legal()) {
1714                 return;
1715         }
1716         
1717         /* if we're turning on rec-enable, there needs to be an
1718            input connection.
1719          */
1720
1721         if (yn && channels[0].source == 0) {
1722
1723                 /* pick up connections not initiated *from* the IO object
1724                    we're associated with.
1725                 */
1726
1727                 get_input_sources ();
1728
1729                 if (channels[0].source == 0) {
1730                 
1731                         if (yn) {
1732                                 CannotRecordNoInput (this); /* emit signal */
1733                         }
1734                         return;
1735                 }
1736         }
1737
1738         /* yes, i know that this not proof against race conditions, but its
1739            good enough. i think.
1740         */
1741
1742         if (record_enabled() != yn) {
1743                 if (yn) {
1744                         atomic_set (&_record_enabled, 1);
1745                         capturing_sources.clear ();
1746                         if (Config->get_use_hardware_monitoring())  {
1747                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1748                                         if ((*chan).source) {
1749                                                 (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
1750                                         }
1751                                         capturing_sources.push_back ((*chan).write_source);
1752                                 }
1753                         } else {
1754                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1755                                         capturing_sources.push_back ((*chan).write_source);
1756                                 }
1757                         }
1758
1759                 } else {
1760                         atomic_set (&_record_enabled, 0);
1761                         if (Config->get_use_hardware_monitoring()) {
1762                                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1763                                         if ((*chan).source) {
1764                                                 (*chan).source->request_monitor_input (false);
1765                                         }
1766                                 }
1767                         }
1768                         capturing_sources.clear ();
1769                 }
1770
1771                 record_enable_changed (src); /* EMIT SIGNAL */
1772         }
1773 }
1774
1775 XMLNode&
1776 DiskStream::get_state ()
1777 {
1778         XMLNode* node = new XMLNode ("DiskStream");
1779         char buf[64];
1780         LocaleGuard lg (X_("POSIX"));
1781
1782         if (destructive()) {
1783                 node->add_property ("destructive", "true");
1784         }
1785
1786         snprintf (buf, sizeof(buf), "%zd", channels.size());
1787         node->add_property ("channels", buf);
1788
1789         node->add_property ("playlist", _playlist->name());
1790         
1791         snprintf (buf, sizeof(buf), "%f", _visible_speed);
1792         node->add_property ("speed", buf);
1793
1794         node->add_property("name", _name);
1795         snprintf (buf, sizeof(buf), "%" PRIu64, id());
1796         node->add_property("id", buf);
1797
1798         if (!capturing_sources.empty() && _session.get_record_enabled()) {
1799
1800                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1801                 XMLNode* cs_grandchild;
1802
1803                 for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1804                         cs_grandchild = new XMLNode (X_("file"));
1805                         cs_grandchild->add_property (X_("path"), (*i)->path());
1806                         cs_child->add_child_nocopy (*cs_grandchild);
1807                 }
1808
1809                 /* store the location where capture will start */
1810
1811                 Location* pi;
1812
1813                 if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1814                         snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1815                 } else {
1816                         snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1817                 }
1818
1819                 cs_child->add_property (X_("at"), buf);
1820                 node->add_child_nocopy (*cs_child);
1821         }
1822
1823         if (_extra_xml) {
1824                 node->add_child_copy (*_extra_xml);
1825         }
1826
1827         return* node;
1828 }
1829
1830 int
1831 DiskStream::set_state (const XMLNode& node)
1832 {
1833         const XMLProperty* prop;
1834         XMLNodeList nlist = node.children();
1835         XMLNodeIterator niter;
1836         uint32_t nchans = 1;
1837         XMLNode* capture_pending_node = 0;
1838         LocaleGuard lg (X_("POSIX"));
1839
1840         in_set_state = true;
1841
1842         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1843                 if ((*niter)->name() == IO::state_node_name) {
1844                         deprecated_io_node = new XMLNode (**niter);
1845                 }
1846
1847                 if ((*niter)->name() == X_("CapturingSources")) {
1848                         capture_pending_node = *niter;
1849                 }
1850         }
1851
1852         /* prevent write sources from being created */
1853         
1854         in_set_state = true;
1855         
1856         if ((prop = node.property ("name")) != 0) {
1857                 _name = prop->value();
1858         } 
1859
1860         if ((prop = node.property ("destructive")) != 0) {
1861                 if (prop->value() == "true") {
1862                         _flags |= Destructive;
1863                 }
1864         } 
1865
1866         if (deprecated_io_node) {
1867                 if ((prop = deprecated_io_node->property ("id")) != 0) {
1868                         sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1869                 }
1870         } else {
1871                 if ((prop = node.property ("id")) != 0) {
1872                         sscanf (prop->value().c_str(), "%" PRIu64, &_id);
1873                 }
1874         }
1875
1876         if ((prop = node.property ("channels")) != 0) {
1877                 nchans = atoi (prop->value().c_str());
1878         }
1879         
1880         // create necessary extra channels
1881         // we are always constructed with one
1882         // and we always need one
1883
1884         if (nchans > _n_channels) {
1885
1886                 // we need to add new channel infos
1887                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1888
1889                 int diff = nchans - channels.size();
1890
1891                 for (int i=0; i < diff; ++i) {
1892                         add_channel ();
1893                 }
1894
1895         } else if (nchans < _n_channels) {
1896
1897                 // we need to get rid of channels
1898                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1899
1900                 int diff = channels.size() - nchans;
1901                 
1902                 for (int i = 0; i < diff; ++i) {
1903                         remove_channel ();
1904                 }
1905         }
1906
1907         if ((prop = node.property ("playlist")) == 0) {
1908                 return -1;
1909         }
1910
1911         {
1912                 bool had_playlist = (_playlist != 0);
1913         
1914                 if (find_and_use_playlist (prop->value())) {
1915                         return -1;
1916                 }
1917
1918                 if (!had_playlist) {
1919                         _playlist->set_orig_diskstream_id (_id);
1920                 }
1921
1922                 if (capture_pending_node) {
1923                         use_pending_capture_data (*capture_pending_node);
1924                 }
1925
1926         }
1927
1928         if ((prop = node.property ("speed")) != 0) {
1929                 double sp = atof (prop->value().c_str());
1930
1931                 if (realtime_set_speed (sp, false)) {
1932                         non_realtime_set_speed ();
1933                 }
1934         }
1935
1936         _n_channels = channels.size();
1937
1938         in_set_state = false;
1939
1940         /* now that we're all done with playlist+channel set up,
1941            go ahead and create write sources.
1942         */
1943
1944
1945         capturing_sources.clear ();
1946
1947         if (recordable()) {
1948                 reset_write_sources (false);
1949         }
1950                 
1951         in_set_state = false;
1952
1953         return 0;
1954 }
1955
1956 int
1957 DiskStream::use_new_write_source (uint32_t n)
1958 {
1959         if (!recordable()) {
1960                 return 1;
1961         }
1962
1963         if (n >= channels.size()) {
1964                 error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
1965                 return -1;
1966         }
1967
1968         ChannelInfo &chan = channels[n];
1969         
1970         if (chan.write_source) {
1971
1972                 if (FileSource::is_empty (chan.write_source->path())) {
1973                         chan.write_source->mark_for_remove ();
1974                         chan.write_source->release();
1975                         delete chan.write_source;
1976                 } else {
1977                         chan.write_source->release();
1978                         chan.write_source = 0;
1979                 }
1980         }
1981
1982         try {
1983                 if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
1984                         throw failed_constructor();
1985                 }
1986         } 
1987
1988         catch (failed_constructor &err) {
1989                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1990                 chan.write_source = 0;
1991                 return -1;
1992         }
1993
1994         chan.write_source->use ();
1995
1996         return 0;
1997 }
1998
1999 void
2000 DiskStream::reset_write_sources (bool mark_write_complete, bool force)
2001 {
2002         ChannelList::iterator chan;
2003         uint32_t n;
2004
2005         if (!recordable()) {
2006                 return;
2007         }
2008         
2009         if (!force && destructive()) {
2010                 return;
2011         }
2012
2013         capturing_sources.clear ();
2014         
2015         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
2016                 if (mark_write_complete) {
2017                         (*chan).write_source->mark_streaming_write_completed ();
2018                 }
2019                 use_new_write_source (n);
2020                 if (record_enabled()) {
2021                         capturing_sources.push_back ((*chan).write_source);
2022                 }
2023         }
2024 }
2025
2026 void
2027 DiskStream::set_block_size (jack_nframes_t nframes)
2028 {
2029         if (_session.get_block_size() > speed_buffer_size) {
2030                 speed_buffer_size = _session.get_block_size();
2031
2032                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2033                         if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2034                         (*chan).speed_buffer = new Sample[speed_buffer_size];
2035                 }
2036         }
2037         allocate_temporary_buffers ();
2038 }
2039
2040 void
2041 DiskStream::allocate_temporary_buffers ()
2042 {
2043         /* make sure the wrap buffer is at least large enough to deal
2044            with the speeds up to 1.2, to allow for micro-variation
2045            when slaving to MTC, SMPTE etc.
2046         */
2047
2048         double sp = max (fabsf (_actual_speed), 1.2f);
2049         jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
2050
2051         if (required_wrap_size > wrap_buffer_size) {
2052
2053                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2054                         if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2055                         (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
2056                         if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2057                         (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
2058                 }
2059
2060                 wrap_buffer_size = required_wrap_size;
2061         }
2062 }
2063
2064 void
2065 DiskStream::monitor_input (bool yn)
2066 {
2067         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2068                 
2069                 if ((*chan).source) {
2070                         (*chan).source->request_monitor_input (yn);
2071                 }
2072         }
2073 }
2074
2075 void
2076 DiskStream::set_capture_offset ()
2077 {
2078         if (_io == 0) {
2079                 /* can't capture, so forget it */
2080                 return;
2081         }
2082
2083         _capture_offset = _io->input_latency();
2084 }
2085
2086 void
2087 DiskStream::set_persistent_align_style (AlignStyle a)
2088 {
2089         _persistent_alignment_style = a;
2090 }
2091
2092 void
2093 DiskStream::set_align_style_from_io ()
2094 {
2095         bool have_physical = false;
2096
2097         if (_io == 0) {
2098                 return;
2099         }
2100
2101         get_input_sources ();
2102         
2103         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2104                 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2105                         have_physical = true;
2106                         break;
2107                 }
2108         }
2109
2110         if (have_physical) {
2111                 set_align_style (ExistingMaterial);
2112         } else {
2113                 set_align_style (CaptureTime);
2114         }
2115 }
2116
2117 void
2118 DiskStream::set_align_style (AlignStyle a)
2119 {
2120         if (record_enabled() && _session.actively_recording()) {
2121                 return;
2122         }
2123
2124
2125         if (a != _alignment_style) {
2126                 _alignment_style = a;
2127                 AlignmentStyleChanged ();
2128         }
2129 }
2130
2131 int
2132 DiskStream::add_channel ()
2133 {
2134         /* XXX need to take lock??? */
2135
2136         ChannelInfo chan;
2137
2138         init_channel (chan);
2139
2140         chan.speed_buffer = new Sample[speed_buffer_size];
2141         chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
2142         chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
2143
2144         channels.push_back (chan);
2145
2146         _n_channels = channels.size();
2147
2148         return 0;
2149 }
2150
2151 int
2152 DiskStream::remove_channel ()
2153 {
2154         if (channels.size() > 1) {
2155                 /* XXX need to take lock??? */
2156                 ChannelInfo & chan = channels.back();
2157                 destroy_channel (chan);
2158                 channels.pop_back();
2159
2160                 _n_channels = channels.size();
2161                 return 0;
2162         }
2163
2164         return -1;
2165 }
2166
2167 float
2168 DiskStream::playback_buffer_load () const
2169 {
2170         return (float) ((double) channels.front().playback_buf->read_space()/
2171                         (double) channels.front().playback_buf->bufsize());
2172 }
2173
2174 float
2175 DiskStream::capture_buffer_load () const
2176 {
2177         return (float) ((double) channels.front().capture_buf->write_space()/
2178                         (double) channels.front().capture_buf->bufsize());
2179 }
2180
2181 int
2182 DiskStream::set_loop (Location *location)
2183 {
2184         if (location) {
2185                 if (location->start() >= location->end()) {
2186                         error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
2187                         return -1;
2188                 }
2189         }
2190
2191         loop_location = location;
2192
2193          LoopSet (location); /* EMIT SIGNAL */
2194         return 0;
2195 }
2196
2197 jack_nframes_t
2198 DiskStream::get_capture_start_frame (uint32_t n)
2199 {
2200         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2201
2202         if (capture_info.size() > n) {
2203                 return capture_info[n]->start;
2204         }
2205         else {
2206                 return capture_start_frame;
2207         }
2208 }
2209
2210 jack_nframes_t
2211 DiskStream::get_captured_frames (uint32_t n)
2212 {
2213         LockMonitor lm (capture_info_lock, __LINE__, __FILE__);
2214
2215         if (capture_info.size() > n) {
2216                 return capture_info[n]->frames;
2217         }
2218         else {
2219                 return capture_captured;
2220         }
2221 }
2222
2223 void
2224 DiskStream::punch_in ()
2225 {
2226 }
2227
2228 void
2229 DiskStream::punch_out ()
2230 {
2231 }
2232
2233 int
2234 DiskStream::use_pending_capture_data (XMLNode& node)
2235 {
2236         const XMLProperty* prop;
2237         XMLNodeList nlist = node.children();
2238         XMLNodeIterator niter;
2239         FileSource* fs;
2240         FileSource* first_fs = 0;
2241         AudioRegion::SourceList pending_sources;
2242         jack_nframes_t position;
2243
2244         if ((prop = node.property (X_("at"))) == 0) {
2245                 return -1;
2246         }
2247
2248         if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2249                 return -1;
2250         }
2251
2252         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2253                 if ((*niter)->name() == X_("file")) {
2254
2255                         if ((prop = (*niter)->property (X_("path"))) == 0) {
2256                                 continue;
2257                         }
2258
2259                         try {
2260                                 fs = new FileSource (prop->value(), _session.frame_rate(), true);
2261                         }
2262
2263                         catch (failed_constructor& err) {
2264                                 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2265                                                   _name, prop->value())
2266                                       << endmsg;
2267                                 return -1;
2268                         }
2269
2270                         pending_sources.push_back (fs);
2271                         
2272                         if (first_fs == 0) {
2273                                 first_fs = fs;
2274                         }
2275
2276                         fs->set_captured_for (_name);
2277                 }
2278         }
2279
2280         if (pending_sources.size() == 0) {
2281                 /* nothing can be done */
2282                 return 1;
2283         }
2284
2285         if (pending_sources.size() != _n_channels) {
2286                 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2287                       << endmsg;
2288                 return -1;
2289         }
2290
2291         AudioRegion* region;
2292         
2293         try {
2294                 region = new AudioRegion (pending_sources, 0, first_fs->length(),
2295                                           region_name_from_path (first_fs->name()), 
2296                                           0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
2297                 
2298                 region->special_set_position (0);
2299         }
2300
2301         catch (failed_constructor& err) {
2302                 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2303                                   _name)
2304                       << endmsg;
2305                 
2306                 return -1;
2307         }
2308
2309         try {
2310                 region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
2311         }
2312
2313         catch (failed_constructor& err) {
2314                 error << string_compose (_("%1: cannot create region from pending capture sources"),
2315                                   _name)
2316                       << endmsg;
2317                 
2318                 return -1;
2319         }
2320
2321         _playlist->add_region (*region, position);
2322
2323         return 0;
2324 }
2325
2326 void
2327 DiskStream::set_roll_delay (jack_nframes_t nframes)
2328 {
2329         _roll_delay = nframes;
2330 }
2331
2332 void
2333 DiskStream::set_destructive (bool yn)
2334 {
2335         if (yn != destructive()) {
2336                 reset_write_sources (true, true);
2337                 if (yn) {
2338                         _flags |= Destructive;
2339                 } else {
2340                         _flags &= ~Destructive;
2341                 }
2342         }
2343 }