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