fix a couple uninitialized variable messages
[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         transvec.buf[0] = 0;
1309         transvec.buf[1] = 0;
1310         vector.buf[0] = 0;
1311         vector.buf[1] = 0;
1312
1313         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1314         
1315                 (*chan).capture_buf->get_read_vector (&vector);
1316
1317                 total = vector.len[0] + vector.len[1];
1318
1319                 
1320                 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1321                         goto out;
1322                 }
1323
1324                 /* if there are 2+ chunks of disk i/o possible for
1325                    this track, let the caller know so that it can arrange
1326                    for us to be called again, ASAP.
1327                    
1328                    if we are forcing a flush, then if there is* any* extra
1329                    work, let the caller know.
1330
1331                    if we are no longer recording and there is any extra work,
1332                    let the caller know too.
1333                 */
1334
1335                 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1336                         ret = 1;
1337                 } 
1338
1339                 to_write = min (disk_io_chunk_frames, (nframes_t) vector.len[0]);
1340                 
1341                 // check the transition buffer when recording destructive
1342                 // important that we get this after the capture buf
1343
1344                 if (destructive()) {
1345                         (*chan).capture_transition_buf->get_read_vector(&transvec);
1346                         size_t transcount = transvec.len[0] + transvec.len[1];
1347                         bool have_start = false;
1348                         size_t ti;
1349
1350                         for (ti=0; ti < transcount; ++ti) {
1351                                 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
1352                                 
1353                                 if (captrans.type == CaptureStart) {
1354                                         // by definition, the first data we got above represents the given capture pos
1355
1356                                         (*chan).write_source->mark_capture_start (captrans.capture_val);
1357                                         (*chan).curr_capture_cnt = 0;
1358
1359                                         have_start = true;
1360                                 }
1361                                 else if (captrans.type == CaptureEnd) {
1362
1363                                         // capture end, the capture_val represents total frames in capture
1364
1365                                         if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
1366
1367                                                 // shorten to make the write a perfect fit
1368                                                 uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt); 
1369
1370                                                 if (nto_write < to_write) {
1371                                                         ret = 1; // should we?
1372                                                 }
1373                                                 to_write = nto_write;
1374
1375                                                 (*chan).write_source->mark_capture_end ();
1376                                                 
1377                                                 // increment past this transition, but go no further
1378                                                 ++ti;
1379                                                 break;
1380                                         }
1381                                         else {
1382                                                 // actually ends just beyond this chunk, so force more work
1383                                                 ret = 1;
1384                                                 break;
1385                                         }
1386                                 }
1387                         }
1388
1389                         if (ti > 0) {
1390                                 (*chan).capture_transition_buf->increment_read_ptr(ti);
1391                         }
1392                 }
1393
1394                 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
1395                         error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
1396                         return -1;
1397                 }
1398
1399                 (*chan).capture_buf->increment_read_ptr (to_write);
1400                 (*chan).curr_capture_cnt += to_write;
1401                 
1402                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
1403                 
1404                         /* we wrote all of vector.len[0] but it wasn't an entire
1405                            disk_io_chunk_frames of data, so arrange for some part 
1406                            of vector.len[1] to be flushed to disk as well.
1407                         */
1408                 
1409                         to_write = min ((nframes_t)(disk_io_chunk_frames - to_write), (nframes_t) vector.len[1]);
1410                 
1411                         if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
1412                                 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
1413                                 return -1;
1414                         }
1415
1416                         _write_data_count += (*chan).write_source->write_data_count();
1417         
1418                         (*chan).capture_buf->increment_read_ptr (to_write);
1419                         (*chan).curr_capture_cnt += to_write;
1420                 }
1421         }
1422
1423   out:
1424         return ret;
1425 }
1426
1427 void
1428 AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1429 {
1430         uint32_t buffer_position;
1431         bool more_work = true;
1432         int err = 0;
1433         boost::shared_ptr<AudioRegion> region;
1434         nframes_t total_capture;
1435         SourceList srcs;
1436         SourceList::iterator src;
1437         ChannelList::iterator chan;
1438         vector<CaptureInfo*>::iterator ci;
1439         uint32_t n = 0; 
1440         bool mark_write_completed = false;
1441
1442         finish_capture (true);
1443
1444         /* butler is already stopped, but there may be work to do 
1445            to flush remaining data to disk.
1446         */
1447
1448         while (more_work && !err) {
1449                 switch (do_flush (Session::TransportContext, true)) {
1450                 case 0:
1451                         more_work = false;
1452                         break;
1453                 case 1:
1454                         break;
1455                 case -1:
1456                         error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1457                         err++;
1458                 }
1459         }
1460
1461         /* XXX is there anything we can do if err != 0 ? */
1462         Glib::Mutex::Lock lm (capture_info_lock);
1463         
1464         if (capture_info.empty()) {
1465                 return;
1466         }
1467
1468         if (abort_capture) {
1469                 
1470                 if (destructive()) {
1471                         goto outout;
1472                 }
1473
1474                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1475
1476                         if ((*chan).write_source) {
1477                                 
1478                                 (*chan).write_source->mark_for_remove ();
1479                                 (*chan).write_source->drop_references ();
1480                                 (*chan).write_source.reset ();
1481                         }
1482                         
1483                         /* new source set up in "out" below */
1484                 }
1485
1486                 goto out;
1487         } 
1488
1489         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1490                 total_capture += (*ci)->frames;
1491         }
1492
1493         /* figure out the name for this take */
1494
1495         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1496
1497                 boost::shared_ptr<AudioFileSource> s = (*chan).write_source;
1498                 
1499                 if (s) {
1500                         srcs.push_back (s);
1501                         s->update_header (capture_info.front()->start, when, twhen);
1502                         s->set_captured_for (_name);
1503                         s->mark_immutable ();
1504                 }
1505         }
1506
1507         /* destructive tracks have a single, never changing region */
1508
1509         if (destructive()) {
1510
1511                 /* send a signal that any UI can pick up to do the right thing. there is 
1512                    a small problem here in that a UI may need the peak data to be ready
1513                    for the data that was recorded and this isn't interlocked with that
1514                    process. this problem is deferred to the UI.
1515                  */
1516                 
1517                 _playlist->Modified();
1518
1519         } else {
1520
1521                 string whole_file_region_name;
1522                 whole_file_region_name = region_name_from_path (channels[0].write_source->name(), true);
1523
1524                 /* Register a new region with the Session that
1525                    describes the entire source. Do this first
1526                    so that any sub-regions will obviously be
1527                    children of this one (later!)
1528                 */
1529                 
1530                 try {
1531                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, 
1532                                                                              whole_file_region_name,
1533                                                                              0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
1534
1535                         region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1536                         region->special_set_position (capture_info.front()->start);
1537                 }
1538                 
1539                 
1540                 catch (failed_constructor& err) {
1541                         error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1542                         /* XXX what now? */
1543                 }
1544                 
1545                 _last_capture_regions.push_back (region);
1546
1547                 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1548                 
1549                 XMLNode &before = _playlist->get_state();
1550                 _playlist->freeze ();
1551                 
1552                 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1553                         
1554                         string region_name;
1555
1556                         _session.region_name (region_name, whole_file_region_name, false);
1557                         
1558                         // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
1559                         
1560                         try {
1561                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
1562                                 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1563                         }
1564                         
1565                         catch (failed_constructor& err) {
1566                                 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1567                                 continue; /* XXX is this OK? */
1568                         }
1569                         
1570                         region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region)));
1571                         
1572                         _last_capture_regions.push_back (region);
1573                         
1574                         i_am_the_modifier++;
1575                         _playlist->add_region (region, (*ci)->start);
1576                         i_am_the_modifier--;
1577                         
1578                         buffer_position += (*ci)->frames;
1579                 }
1580
1581                 _playlist->thaw ();
1582                 XMLNode &after = _playlist->get_state();
1583                 _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
1584         }
1585
1586         mark_write_completed = true;
1587
1588   out:
1589         reset_write_sources (mark_write_completed);
1590
1591   outout:
1592
1593         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1594                 delete *ci;
1595         }
1596
1597         capture_info.clear ();
1598         capture_start_frame = 0;
1599 }
1600
1601 void
1602 AudioDiskstream::finish_capture (bool rec_monitors_input)
1603 {
1604         was_recording = false;
1605         
1606         if (capture_captured == 0) {
1607                 return;
1608         }
1609
1610         if (recordable() && destructive()) {
1611                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1612                         
1613                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
1614                         (*chan).capture_transition_buf->get_write_vector(&transvec);
1615                         
1616                         
1617                         if (transvec.len[0] > 0) {
1618                                 transvec.buf[0]->type = CaptureEnd;
1619                                 transvec.buf[0]->capture_val = capture_captured;
1620                                 (*chan).capture_transition_buf->increment_write_ptr(1);
1621                         }
1622                         else {
1623                                 // bad!
1624                                 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
1625                         }
1626                 }
1627         }
1628         
1629         
1630         CaptureInfo* ci = new CaptureInfo;
1631         
1632         ci->start =  capture_start_frame;
1633         ci->frames = capture_captured;
1634         
1635         /* XXX theoretical race condition here. Need atomic exchange ? 
1636            However, the circumstances when this is called right 
1637            now (either on record-disable or transport_stopped)
1638            mean that no actual race exists. I think ...
1639            We now have a capture_info_lock, but it is only to be used
1640            to synchronize in the transport_stop and the capture info
1641            accessors, so that invalidation will not occur (both non-realtime).
1642         */
1643
1644         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1645
1646         capture_info.push_back (ci);
1647         capture_captured = 0;
1648 }
1649
1650 void
1651 AudioDiskstream::set_record_enabled (bool yn)
1652 {
1653         if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs() == 0) {
1654                 return;
1655         }
1656
1657         /* can't rec-enable in destructive mode if transport is before start */
1658
1659         if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
1660                 return;
1661         }
1662
1663         if (yn && channels[0].source == 0) {
1664
1665                 /* pick up connections not initiated *from* the IO object
1666                    we're associated with.
1667                 */
1668
1669                 get_input_sources ();
1670         }
1671
1672         /* yes, i know that this not proof against race conditions, but its
1673            good enough. i think.
1674         */
1675
1676         if (record_enabled() != yn) {
1677                 if (yn) {
1678                         engage_record_enable ();
1679                 } else {
1680                         disengage_record_enable ();
1681                 }
1682         }
1683 }
1684
1685 void
1686 AudioDiskstream::engage_record_enable ()
1687 {
1688     bool rolling = _session.transport_speed() != 0.0f;
1689
1690         g_atomic_int_set (&_record_enabled, 1);
1691         capturing_sources.clear ();
1692         if (Config->get_monitoring_model() == HardwareMonitoring) {
1693                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1694                         if ((*chan).source) {
1695                                 (*chan).source->ensure_monitor_input (!(Config->get_auto_input() && rolling));
1696                         }
1697                         capturing_sources.push_back ((*chan).write_source);
1698                 }
1699         } else {
1700                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1701                         capturing_sources.push_back ((*chan).write_source);
1702                 }
1703         }
1704
1705         RecordEnableChanged (); /* EMIT SIGNAL */
1706 }
1707
1708 void
1709 AudioDiskstream::disengage_record_enable ()
1710 {
1711         g_atomic_int_set (&_record_enabled, 0);
1712         if (Config->get_monitoring_model() == HardwareMonitoring) {
1713                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1714                         if ((*chan).source) {
1715                                 (*chan).source->ensure_monitor_input (false);
1716                         }
1717                 }
1718         }
1719         capturing_sources.clear ();
1720         RecordEnableChanged (); /* EMIT SIGNAL */
1721 }
1722                 
1723
1724 XMLNode&
1725 AudioDiskstream::get_state ()
1726 {
1727         XMLNode* node = new XMLNode ("AudioDiskstream");
1728         char buf[64] = "";
1729         LocaleGuard lg (X_("POSIX"));
1730
1731         node->add_property ("flags", enum_2_string (_flags));
1732
1733         snprintf (buf, sizeof(buf), "%zd", channels.size());
1734         node->add_property ("channels", buf);
1735
1736         node->add_property ("playlist", _playlist->name());
1737         
1738         snprintf (buf, sizeof(buf), "%.12g", _visible_speed);
1739         node->add_property ("speed", buf);
1740
1741         node->add_property("name", _name);
1742         id().print (buf, sizeof (buf));
1743         node->add_property("id", buf);
1744
1745         if (!capturing_sources.empty() && _session.get_record_enabled()) {
1746
1747                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1748                 XMLNode* cs_grandchild;
1749
1750                 for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1751                         cs_grandchild = new XMLNode (X_("file"));
1752                         cs_grandchild->add_property (X_("path"), (*i)->path());
1753                         cs_child->add_child_nocopy (*cs_grandchild);
1754                 }
1755
1756                 /* store the location where capture will start */
1757
1758                 Location* pi;
1759
1760                 if (Config->get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1761                         snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1762                 } else {
1763                         snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1764                 }
1765
1766                 cs_child->add_property (X_("at"), buf);
1767                 node->add_child_nocopy (*cs_child);
1768         }
1769
1770         if (_extra_xml) {
1771                 node->add_child_copy (*_extra_xml);
1772         }
1773
1774         return* node;
1775 }
1776
1777 int
1778 AudioDiskstream::set_state (const XMLNode& node)
1779 {
1780         const XMLProperty* prop;
1781         XMLNodeList nlist = node.children();
1782         XMLNodeIterator niter;
1783         uint32_t nchans = 1;
1784         XMLNode* capture_pending_node = 0;
1785         LocaleGuard lg (X_("POSIX"));
1786
1787         in_set_state = true;
1788
1789         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1790                 if ((*niter)->name() == IO::state_node_name) {
1791                         deprecated_io_node = new XMLNode (**niter);
1792                 }
1793
1794                 if ((*niter)->name() == X_("CapturingSources")) {
1795                         capture_pending_node = *niter;
1796                 }
1797         }
1798
1799         /* prevent write sources from being created */
1800         
1801         in_set_state = true;
1802         
1803         if ((prop = node.property ("name")) != 0) {
1804                 _name = prop->value();
1805         } 
1806
1807         if (deprecated_io_node) {
1808                 if ((prop = deprecated_io_node->property ("id")) != 0) {
1809                         _id = prop->value ();
1810                 }
1811         } else {
1812                 if ((prop = node.property ("id")) != 0) {
1813                         _id = prop->value ();
1814                 }
1815         }
1816
1817         if ((prop = node.property ("flags")) != 0) {
1818                 _flags = Flag (string_2_enum (prop->value(), _flags));
1819         }
1820
1821         if ((prop = node.property ("channels")) != 0) {
1822                 nchans = atoi (prop->value().c_str());
1823         }
1824         
1825         // create necessary extra channels
1826         // we are always constructed with one and we always need one
1827
1828         if (nchans > _n_channels) {
1829
1830                 // we need to add new channel infos
1831                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1832
1833                 int diff = nchans - channels.size();
1834
1835                 for (int i=0; i < diff; ++i) {
1836                         add_channel ();
1837                 }
1838
1839         } else if (nchans < _n_channels) {
1840
1841                 // we need to get rid of channels
1842                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1843
1844                 int diff = channels.size() - nchans;
1845                 
1846                 for (int i = 0; i < diff; ++i) {
1847                         remove_channel ();
1848                 }
1849         }
1850
1851         if ((prop = node.property ("playlist")) == 0) {
1852                 return -1;
1853         }
1854
1855         {
1856                 bool had_playlist = (_playlist != 0);
1857         
1858                 if (find_and_use_playlist (prop->value())) {
1859                         return -1;
1860                 }
1861
1862                 if (!had_playlist) {
1863                         _playlist->set_orig_diskstream_id (_id);
1864                 }
1865                 
1866                 if (!destructive() && capture_pending_node) {
1867                         /* destructive streams have one and only one source per channel,
1868                            and so they never end up in pending capture in any useful
1869                            sense.
1870                         */
1871                         use_pending_capture_data (*capture_pending_node);
1872                 }
1873
1874         }
1875
1876         if ((prop = node.property ("speed")) != 0) {
1877                 double sp = atof (prop->value().c_str());
1878
1879                 if (realtime_set_speed (sp, false)) {
1880                         non_realtime_set_speed ();
1881                 }
1882         }
1883
1884         _n_channels = channels.size();
1885
1886         in_set_state = false;
1887
1888         /* make sure this is clear before we do anything else */
1889
1890         capturing_sources.clear ();
1891
1892         /* write sources are handled when we handle the input set 
1893            up of the IO that owns this DS (::non_realtime_input_change())
1894         */
1895                 
1896         in_set_state = false;
1897
1898         return 0;
1899 }
1900
1901 int
1902 AudioDiskstream::use_new_write_source (uint32_t n)
1903 {
1904         if (!recordable()) {
1905                 return 1;
1906         }
1907
1908         if (n >= channels.size()) {
1909                 error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1910                 return -1;
1911         }
1912
1913         ChannelInfo &chan = channels[n];
1914         
1915         if (chan.write_source) {
1916                 chan.write_source->set_allow_remove_if_empty (true);
1917                 chan.write_source.reset ();
1918         }
1919
1920         try {
1921                 if ((chan.write_source = _session.create_audio_source_for_session (*this, n, destructive())) == 0) {
1922                         throw failed_constructor();
1923                 }
1924         } 
1925
1926         catch (failed_constructor &err) {
1927                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1928                 chan.write_source.reset ();
1929                 return -1;
1930         }
1931
1932         /* do not remove destructive files even if they are empty */
1933
1934         chan.write_source->set_allow_remove_if_empty (!destructive());
1935
1936         return 0;
1937 }
1938
1939 void
1940 AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force)
1941 {
1942         ChannelList::iterator chan;
1943         uint32_t n;
1944
1945         if (!recordable()) {
1946                 return;
1947         }
1948         
1949         capturing_sources.clear ();
1950
1951         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
1952                 if (!destructive()) {
1953
1954                         if ((*chan).write_source && mark_write_complete) {
1955                                 (*chan).write_source->mark_streaming_write_completed ();
1956                         }
1957                         use_new_write_source (n);
1958
1959                         if (record_enabled()) {
1960                                 capturing_sources.push_back ((*chan).write_source);
1961                         }
1962
1963                 } else {
1964                         if ((*chan).write_source == 0) {
1965                                 use_new_write_source (n);
1966                         }
1967                 }
1968         }
1969
1970         if (destructive()) {
1971
1972                 /* we now have all our write sources set up, so create the
1973                    playlist's single region.
1974                 */
1975
1976                 if (_playlist->empty()) {
1977                         setup_destructive_playlist ();
1978                 }
1979         }
1980 }
1981
1982 int
1983 AudioDiskstream::rename_write_sources ()
1984 {
1985         ChannelList::iterator chan;
1986         uint32_t n;
1987
1988         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
1989                 if ((*chan).write_source != 0) {
1990                         (*chan).write_source->set_name (_name, destructive());
1991                         /* XXX what to do if one of them fails ? */
1992                 }
1993         }
1994
1995         return 0;
1996 }
1997
1998 void
1999 AudioDiskstream::set_block_size (nframes_t nframes)
2000 {
2001         if (_session.get_block_size() > speed_buffer_size) {
2002                 speed_buffer_size = _session.get_block_size();
2003
2004                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2005                         if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2006                         (*chan).speed_buffer = new Sample[speed_buffer_size];
2007                 }
2008         }
2009         allocate_temporary_buffers ();
2010 }
2011
2012 void
2013 AudioDiskstream::allocate_temporary_buffers ()
2014 {
2015         /* make sure the wrap buffer is at least large enough to deal
2016            with the speeds up to 1.2, to allow for micro-variation
2017            when slaving to MTC, SMPTE etc.
2018         */
2019
2020         double sp = max (fabsf (_actual_speed), 1.2f);
2021         nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * sp) + 1;
2022
2023         if (required_wrap_size > wrap_buffer_size) {
2024
2025                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2026                         if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2027                         (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
2028                         if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2029                         (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
2030                 }
2031
2032                 wrap_buffer_size = required_wrap_size;
2033         }
2034 }
2035
2036 void
2037 AudioDiskstream::monitor_input (bool yn)
2038 {
2039         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2040                 
2041                 if ((*chan).source) {
2042                         (*chan).source->ensure_monitor_input (yn);
2043                 }
2044         }
2045 }
2046
2047 void
2048 AudioDiskstream::set_align_style_from_io ()
2049 {
2050         bool have_physical = false;
2051
2052         if (_io == 0) {
2053                 return;
2054         }
2055
2056         get_input_sources ();
2057         
2058         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2059                 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2060                         have_physical = true;
2061                         break;
2062                 }
2063         }
2064
2065         if (have_physical) {
2066                 set_align_style (ExistingMaterial);
2067         } else {
2068                 set_align_style (CaptureTime);
2069         }
2070 }
2071
2072 int
2073 AudioDiskstream::add_channel ()
2074 {
2075         /* XXX need to take lock??? */
2076
2077         /* this copies the ChannelInfo, which currently has no buffers. kind
2078            of pointless really, but we want the channels list to contain
2079            actual objects, not pointers to objects. mostly for convenience,
2080            which isn't much in evidence.
2081         */
2082
2083         channels.push_back (ChannelInfo());
2084
2085         /* now allocate the buffers */
2086
2087         channels.back().init (_session.diskstream_buffer_size(), 
2088                               speed_buffer_size,
2089                               wrap_buffer_size);
2090
2091         _n_channels = channels.size();
2092
2093         return 0;
2094 }
2095
2096 int
2097 AudioDiskstream::remove_channel ()
2098 {
2099         if (channels.size() > 1) {
2100                 /* XXX need to take lock??? */
2101                 channels.back().release ();
2102                 channels.pop_back();
2103                 _n_channels = channels.size();
2104                 return 0;
2105         }
2106
2107         return -1;
2108 }
2109
2110 float
2111 AudioDiskstream::playback_buffer_load () const
2112 {
2113         return (float) ((double) channels.front().playback_buf->read_space()/
2114                         (double) channels.front().playback_buf->bufsize());
2115 }
2116
2117 float
2118 AudioDiskstream::capture_buffer_load () const
2119 {
2120         return (float) ((double) channels.front().capture_buf->write_space()/
2121                         (double) channels.front().capture_buf->bufsize());
2122 }
2123
2124 int
2125 AudioDiskstream::use_pending_capture_data (XMLNode& node)
2126 {
2127         const XMLProperty* prop;
2128         XMLNodeList nlist = node.children();
2129         XMLNodeIterator niter;
2130         boost::shared_ptr<AudioFileSource> fs;
2131         boost::shared_ptr<AudioFileSource> first_fs;
2132         SourceList pending_sources;
2133         nframes_t position;
2134
2135         if ((prop = node.property (X_("at"))) == 0) {
2136                 return -1;
2137         }
2138
2139         if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2140                 return -1;
2141         }
2142
2143         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2144                 if ((*niter)->name() == X_("file")) {
2145
2146                         if ((prop = (*niter)->property (X_("path"))) == 0) {
2147                                 continue;
2148                         }
2149
2150                         try {
2151                                 fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (_session, prop->value(), false, _session.frame_rate()));
2152                         }
2153
2154                         catch (failed_constructor& err) {
2155                                 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2156                                                   _name, prop->value())
2157                                       << endmsg;
2158                                 return -1;
2159                         }
2160
2161                         pending_sources.push_back (fs);
2162                         
2163                         if (first_fs == 0) {
2164                                 first_fs = fs;
2165                         }
2166
2167                         fs->set_captured_for (_name);
2168                 }
2169         }
2170
2171         if (pending_sources.size() == 0) {
2172                 /* nothing can be done */
2173                 return 1;
2174         }
2175
2176         if (pending_sources.size() != _n_channels) {
2177                 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2178                       << endmsg;
2179                 return -1;
2180         }
2181
2182         boost::shared_ptr<AudioRegion> region;
2183         
2184         try {
2185                 region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(),
2186                                                                                           region_name_from_path (first_fs->name(), true), 
2187                                                                                           0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
2188                 region->special_set_position (0);
2189         }
2190
2191         catch (failed_constructor& err) {
2192                 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2193                                   _name)
2194                       << endmsg;
2195                 
2196                 return -1;
2197         }
2198
2199         try {
2200                 region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name(), true)));
2201         }
2202
2203         catch (failed_constructor& err) {
2204                 error << string_compose (_("%1: cannot create region from pending capture sources"),
2205                                   _name)
2206                       << endmsg;
2207                 
2208                 return -1;
2209         }
2210
2211         _playlist->add_region (region, position);
2212
2213         return 0;
2214 }
2215
2216 int
2217 AudioDiskstream::set_destructive (bool yn)
2218 {
2219         bool bounce_ignored;
2220
2221         if (yn != destructive()) {
2222                 
2223                 if (yn) {
2224                         /* requestor should already have checked this and
2225                            bounced if necessary and desired 
2226                         */
2227                         if (!can_become_destructive (bounce_ignored)) {
2228                                 return -1;
2229                         }
2230                         _flags = Flag (_flags | Destructive);
2231                         use_destructive_playlist ();
2232                 } else {
2233                         _flags = Flag (_flags & ~Destructive);
2234                         reset_write_sources (true, true);
2235                 }
2236         }
2237
2238         return 0;
2239 }
2240
2241 bool
2242 AudioDiskstream::can_become_destructive (bool& requires_bounce) const
2243 {
2244         if (!_playlist) {
2245                 requires_bounce = false;
2246                 return false;
2247         }
2248
2249         /* is there only one region ? */
2250
2251         if (_playlist->n_regions() != 1) {
2252                 requires_bounce = true;
2253                 return false;
2254         }
2255
2256         boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1);
2257         assert (first);
2258
2259         /* do the source(s) for the region cover the session start position ? */
2260         
2261         if (first->position() != _session.current_start_frame()) {
2262                 if (first->start() > _session.current_start_frame()) {
2263                         requires_bounce = true;
2264                         return false;
2265                 }
2266         }
2267
2268         /* is the source used by only 1 playlist ? */
2269
2270         boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first);
2271
2272         assert (afirst);
2273
2274         if (afirst->source()->used() > 1) {
2275                 requires_bounce = true; 
2276                 return false;
2277         }
2278
2279         requires_bounce = false;
2280         return true;
2281 }
2282
2283 AudioDiskstream::ChannelInfo::ChannelInfo ()
2284 {
2285         playback_wrap_buffer = 0;
2286         capture_wrap_buffer = 0;
2287         speed_buffer = 0;
2288         peak_power = 0.0f;
2289         source = 0;
2290         current_capture_buffer = 0;
2291         current_playback_buffer = 0;
2292         curr_capture_cnt = 0;
2293         playback_buf = 0;
2294         capture_buf = 0;
2295         capture_transition_buf = 0;
2296 }
2297
2298 void
2299 AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size)
2300 {
2301         speed_buffer = new Sample[speed_size];
2302         playback_wrap_buffer = new Sample[wrap_size];
2303         capture_wrap_buffer = new Sample[wrap_size];
2304
2305         playback_buf = new RingBufferNPT<Sample> (bufsize);
2306         capture_buf = new RingBufferNPT<Sample> (bufsize);
2307         capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
2308         
2309         /* touch the ringbuffer buffers, which will cause
2310            them to be mapped into locked physical RAM if
2311            we're running with mlockall(). this doesn't do
2312            much if we're not.  
2313         */
2314
2315         memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
2316         memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
2317         memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize());
2318 }
2319
2320 AudioDiskstream::ChannelInfo::~ChannelInfo ()
2321 {
2322 }
2323
2324 void
2325 AudioDiskstream::ChannelInfo::release ()
2326 {
2327         if (write_source) {
2328                 write_source.reset ();
2329         }
2330                 
2331         if (speed_buffer) {
2332                 delete [] speed_buffer;
2333                 speed_buffer = 0;
2334         }
2335
2336         if (playback_wrap_buffer) {
2337                 delete [] playback_wrap_buffer;
2338                 playback_wrap_buffer = 0;
2339         }
2340
2341         if (capture_wrap_buffer) {
2342                 delete [] capture_wrap_buffer;
2343                 capture_wrap_buffer = 0;
2344         }
2345         
2346         if (playback_buf) {
2347                 delete playback_buf;
2348                 playback_buf = 0;
2349         }
2350
2351         if (capture_buf) {
2352                 delete capture_buf;
2353                 capture_buf = 0;
2354         }
2355
2356         if (capture_transition_buf) {
2357                 delete capture_transition_buf;
2358                 capture_transition_buf = 0;
2359         }
2360 }