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