padding patch for mutex problem; better x86_64 alignment patch from mike taht; fixes...
[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         _processed = false;
829
830         return need_butler;
831 }
832
833 void
834 AudioDiskstream::set_pending_overwrite (bool yn)
835 {
836         /* called from audio thread, so we can use the read ptr and playback sample as we wish */
837         
838         pending_overwrite = yn;
839
840         overwrite_frame = playback_sample;
841         overwrite_offset = channels.front().playback_buf->get_read_ptr();
842 }
843
844 int
845 AudioDiskstream::overwrite_existing_buffers ()
846 {
847         Sample* mixdown_buffer;
848         float* gain_buffer;
849         int ret = -1;
850         bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
851
852         overwrite_queued = false;
853
854         /* assume all are the same size */
855         nframes_t size = channels[0].playback_buf->bufsize();
856         
857         mixdown_buffer = new Sample[size];
858         gain_buffer = new float[size];
859         
860         /* reduce size so that we can fill the buffer correctly. */
861         size--;
862         
863         uint32_t n=0;
864         nframes_t start;
865
866         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
867
868                 start = overwrite_frame;
869                 nframes_t cnt = size;
870                 
871                 /* to fill the buffer without resetting the playback sample, we need to
872                    do it one or two chunks (normally two).
873
874                    |----------------------------------------------------------------------|
875
876                                        ^
877                                        overwrite_offset
878                     |<- second chunk->||<----------------- first chunk ------------------>|
879                    
880                 */
881                 
882                 nframes_t to_read = size - overwrite_offset;
883
884                 if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, *chan, n, reversed)) {
885                         error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
886                                          _id, size, playback_sample) << endmsg;
887                         goto out;
888                 }
889                         
890                 if (cnt > to_read) {
891
892                         cnt -= to_read;
893                 
894                         if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer,
895                                   start, cnt, *chan, n, reversed)) {
896                                 error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
897                                                  _id, size, playback_sample) << endmsg;
898                                 goto out;
899                         }
900                 }
901         }
902
903         ret = 0;
904  
905   out:
906         pending_overwrite = false;
907         delete [] gain_buffer;
908         delete [] mixdown_buffer;
909         return ret;
910 }
911
912 int
913 AudioDiskstream::seek (nframes_t frame, bool complete_refill)
914 {
915         Glib::Mutex::Lock lm (state_lock);
916         uint32_t n;
917         int ret;
918         ChannelList::iterator chan;
919
920         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
921                 (*chan).playback_buf->reset ();
922                 (*chan).capture_buf->reset ();
923         }
924         
925         /* can't rec-enable in destructive mode if transport is before start */
926
927         if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
928                 disengage_record_enable ();
929         }
930
931         playback_sample = frame;
932         file_frame = frame;
933
934         if (complete_refill) {
935                 while ((ret = do_refill_with_alloc ()) > 0) ;
936         } else {
937                 ret = do_refill_with_alloc ();
938         }
939
940         return ret;
941 }
942
943 int
944 AudioDiskstream::can_internal_playback_seek (nframes_t distance)
945 {
946         ChannelList::iterator chan;
947
948         for (chan = channels.begin(); chan != channels.end(); ++chan) {
949                 if ((*chan).playback_buf->read_space() < distance) {
950                         return false;
951                 } 
952         }
953         return true;
954 }
955
956 int
957 AudioDiskstream::internal_playback_seek (nframes_t distance)
958 {
959         ChannelList::iterator chan;
960
961         for (chan = channels.begin(); chan != channels.end(); ++chan) {
962                 (*chan).playback_buf->increment_read_ptr (distance);
963         }
964
965         first_recordable_frame += distance;
966         playback_sample += distance;
967         
968         return 0;
969 }
970
971 int
972 AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, nframes_t& start, nframes_t cnt, 
973                   ChannelInfo& channel_info, int channel, bool reversed)
974 {
975         nframes_t this_read = 0;
976         bool reloop = false;
977         nframes_t loop_end = 0;
978         nframes_t loop_start = 0;
979         nframes_t loop_length = 0;
980         nframes_t offset = 0;
981         Location *loc = 0;
982
983         /* XXX we don't currently play loops in reverse. not sure why */
984
985         if (!reversed) {
986
987                 /* Make the use of a Location atomic for this read operation.
988                    
989                    Note: Locations don't get deleted, so all we care about
990                    when I say "atomic" is that we are always pointing to
991                    the same one and using a start/length values obtained
992                    just once.
993                 */
994                 
995                 if ((loc = loop_location) != 0) {
996                         loop_start = loc->start();
997                         loop_end = loc->end();
998                         loop_length = loop_end - loop_start;
999                 }
1000                 
1001                 /* if we are looping, ensure that the first frame we read is at the correct
1002                    position within the loop.
1003                 */
1004                 
1005                 if (loc && start >= loop_end) {
1006                         //cerr << "start adjusted from " << start;
1007                         start = loop_start + ((start - loop_start) % loop_length);
1008                         //cerr << "to " << start << endl;
1009                 }
1010
1011                 //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
1012         }
1013
1014         while (cnt) {
1015
1016                 if (reversed) {
1017                         start -= cnt;
1018                 }
1019                         
1020                 /* take any loop into account. we can't read past the end of the loop. */
1021
1022                 if (loc && (loop_end - start < cnt)) {
1023                         this_read = loop_end - start;
1024                         //cerr << "reloop true: thisread: " << this_read << "  cnt: " << cnt << endl;
1025                         reloop = true;
1026                 } else {
1027                         reloop = false;
1028                         this_read = cnt;
1029                 }
1030
1031                 if (this_read == 0) {
1032                         break;
1033                 }
1034
1035                 this_read = min(cnt,this_read);
1036
1037                 if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
1038                         error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read, 
1039                                          start) << endmsg;
1040                         return -1;
1041                 }
1042
1043                 _read_data_count = _playlist->read_data_count();
1044                 
1045                 if (reversed) {
1046
1047                         swap_by_ptr (buf, buf + this_read - 1);
1048                         
1049                 } else {
1050                         
1051                         /* if we read to the end of the loop, go back to the beginning */
1052                         
1053                         if (reloop) {
1054                                 start = loop_start;
1055                         } else {
1056                                 start += this_read;
1057                         }
1058                 } 
1059
1060                 cnt -= this_read;
1061                 offset += this_read;
1062         }
1063
1064         return 0;
1065 }
1066
1067 int
1068 AudioDiskstream::do_refill_with_alloc()
1069 {
1070         Sample* mix_buf  = new Sample[disk_io_chunk_frames];
1071         float*  gain_buf = new float[disk_io_chunk_frames];
1072
1073         int ret = _do_refill(mix_buf, gain_buf);
1074         
1075         delete [] mix_buf;
1076         delete [] gain_buf;
1077
1078         return ret;
1079 }
1080
1081 int
1082 AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer)
1083 {
1084         int32_t ret = 0;
1085         nframes_t to_read;
1086         RingBufferNPT<Sample>::rw_vector vector;
1087         bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
1088         nframes_t total_space;
1089         nframes_t zero_fill;
1090         uint32_t chan_n;
1091         ChannelList::iterator i;
1092         nframes_t ts;
1093
1094         assert(mixdown_buffer);
1095         assert(gain_buffer);
1096
1097         vector.buf[0] = 0;
1098         vector.len[0] = 0;
1099         vector.buf[1] = 0;
1100         vector.len[1] = 0;
1101
1102         channels.front().playback_buf->get_write_vector (&vector);
1103
1104         
1105         if ((total_space = vector.len[0] + vector.len[1]) == 0) {
1106                 return 0;
1107         }
1108
1109         /* if there are 2+ chunks of disk i/o possible for
1110            this track, let the caller know so that it can arrange
1111            for us to be called again, ASAP.
1112         */
1113         
1114         if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
1115                 ret = 1;
1116         }
1117         
1118         /* if we're running close to normal speed and there isn't enough 
1119            space to do disk_io_chunk_frames of I/O, then don't bother.  
1120            
1121            at higher speeds, just do it because the sync between butler
1122            and audio thread may not be good enough.
1123         */
1124         
1125         if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
1126                 return 0;
1127         }
1128         
1129         /* when slaved, don't try to get too close to the read pointer. this
1130            leaves space for the buffer reversal to have something useful to
1131            work with.
1132         */
1133         
1134         if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
1135                 return 0;
1136         }
1137
1138         /* never do more than disk_io_chunk_frames worth of disk input per call (limit doesn't apply for memset) */
1139
1140         total_space = min (disk_io_chunk_frames, total_space);
1141
1142         if (reversed) {
1143
1144                 if (file_frame == 0) {
1145
1146                         /* at start: nothing to do but fill with silence */
1147
1148                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1149                                         
1150                                 ChannelInfo& chan (*i);
1151                                 chan.playback_buf->get_write_vector (&vector);
1152                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1153                                 if (vector.len[1]) {
1154                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1155                                 }
1156                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1157                         }
1158                         return 0;
1159                 }
1160
1161                 if (file_frame < total_space) {
1162
1163                         /* too close to the start: read what we can, 
1164                            and then zero fill the rest 
1165                         */
1166
1167                         zero_fill = total_space - file_frame;
1168                         total_space = file_frame;
1169                         file_frame = 0;
1170
1171                 } else {
1172                         
1173                         zero_fill = 0;
1174                 }
1175
1176         } else {
1177
1178                 if (file_frame == max_frames) {
1179
1180                         /* at end: nothing to do but fill with silence */
1181                         
1182                         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1183                                         
1184                                 ChannelInfo& chan (*i);
1185                                 chan.playback_buf->get_write_vector (&vector);
1186                                 memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
1187                                 if (vector.len[1]) {
1188                                         memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
1189                                 }
1190                                 chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
1191                         }
1192                         return 0;
1193                 }
1194                 
1195                 if (file_frame > max_frames - total_space) {
1196
1197                         /* to close to the end: read what we can, and zero fill the rest */
1198
1199                         zero_fill = total_space - (max_frames - file_frame);
1200                         total_space = max_frames - file_frame;
1201
1202                 } else {
1203                         zero_fill = 0;
1204                 }
1205         }
1206         
1207         nframes_t file_frame_tmp = 0;
1208
1209         for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
1210
1211                 ChannelInfo& chan (*i);
1212                 Sample* buf1;
1213                 Sample* buf2;
1214                 nframes_t len1, len2;
1215
1216                 chan.playback_buf->get_write_vector (&vector);
1217
1218                 if (vector.len[0] > disk_io_chunk_frames) {
1219                         
1220                         /* we're not going to fill the first chunk, so certainly do not bother with the
1221                            other part. it won't be connected with the part we do fill, as in:
1222                            
1223                            .... => writable space
1224                            ++++ => readable space
1225                            ^^^^ => 1 x disk_io_chunk_frames that would be filled
1226                            
1227                            |......|+++++++++++++|...............................|
1228                            buf1                buf0
1229                                                 ^^^^^^^^^^^^^^^
1230                            
1231                            
1232                            So, just pretend that the buf1 part isn't there.                                     
1233                            
1234                         */
1235                 
1236                         vector.buf[1] = 0;
1237                         vector.len[1] = 0;
1238                 
1239                 } 
1240
1241                 ts = total_space;
1242                 file_frame_tmp = file_frame;
1243
1244                 buf1 = vector.buf[0];
1245                 len1 = vector.len[0];
1246                 buf2 = vector.buf[1];
1247                 len2 = vector.len[1];
1248
1249                 to_read = min (ts, len1);
1250                 to_read = min (to_read, disk_io_chunk_frames);
1251
1252                 if (to_read) {
1253
1254                         if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1255                                 ret = -1;
1256                                 goto out;
1257                         }
1258
1259                         chan.playback_buf->increment_write_ptr (to_read);
1260                         ts -= to_read;
1261                 }
1262
1263                 to_read = min (ts, len2);
1264
1265                 if (to_read) {
1266
1267                         /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
1268                            so read some or all of vector.len[1] as well.
1269                         */
1270
1271                         if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
1272                                 ret = -1;
1273                                 goto out;
1274                         }
1275                 
1276                         chan.playback_buf->increment_write_ptr (to_read);
1277                 }
1278
1279                 if (zero_fill) {
1280                         /* do something */
1281                 }
1282
1283         }
1284         
1285         file_frame = file_frame_tmp;
1286
1287   out:
1288
1289         return ret;
1290 }       
1291
1292 /** Flush pending data to disk.
1293  *
1294  * Important note: this function will write *AT MOST* disk_io_chunk_frames
1295  * of data to disk. it will never write more than that.  If it writes that
1296  * much and there is more than that waiting to be written, it will return 1,
1297  * otherwise 0 on success or -1 on failure.
1298  * 
1299  * If there is less than disk_io_chunk_frames to be written, no data will be
1300  * written at all unless @a force_flush is true.
1301  */
1302 int
1303 AudioDiskstream::do_flush (Session::RunContext context, bool force_flush)
1304 {
1305         uint32_t to_write;
1306         int32_t ret = 0;
1307         RingBufferNPT<Sample>::rw_vector vector;
1308         RingBufferNPT<CaptureTransition>::rw_vector transvec;
1309         nframes_t total;
1310
1311         _write_data_count = 0;
1312
1313         transvec.buf[0] = 0;
1314         transvec.buf[1] = 0;
1315         vector.buf[0] = 0;
1316         vector.buf[1] = 0;
1317
1318         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1319         
1320                 (*chan).capture_buf->get_read_vector (&vector);
1321
1322                 total = vector.len[0] + vector.len[1];
1323
1324                 if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
1325                         goto out;
1326                 }
1327
1328                 /* if there are 2+ chunks of disk i/o possible for
1329                    this track, let the caller know so that it can arrange
1330                    for us to be called again, ASAP.
1331                    
1332                    if we are forcing a flush, then if there is* any* extra
1333                    work, let the caller know.
1334
1335                    if we are no longer recording and there is any extra work,
1336                    let the caller know too.
1337                 */
1338
1339                 if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
1340                         ret = 1;
1341                 } 
1342
1343                 to_write = min (disk_io_chunk_frames, (nframes_t) vector.len[0]);
1344                 
1345                 // check the transition buffer when recording destructive
1346                 // important that we get this after the capture buf
1347
1348                 if (destructive()) {
1349                         (*chan).capture_transition_buf->get_read_vector(&transvec);
1350                         size_t transcount = transvec.len[0] + transvec.len[1];
1351                         bool have_start = false;
1352                         size_t ti;
1353
1354                         for (ti=0; ti < transcount; ++ti) {
1355                                 CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
1356                                 
1357                                 if (captrans.type == CaptureStart) {
1358                                         // by definition, the first data we got above represents the given capture pos
1359
1360                                         (*chan).write_source->mark_capture_start (captrans.capture_val);
1361                                         (*chan).curr_capture_cnt = 0;
1362
1363                                         have_start = true;
1364                                 }
1365                                 else if (captrans.type == CaptureEnd) {
1366
1367                                         // capture end, the capture_val represents total frames in capture
1368
1369                                         if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
1370
1371                                                 // shorten to make the write a perfect fit
1372                                                 uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt); 
1373
1374                                                 if (nto_write < to_write) {
1375                                                         ret = 1; // should we?
1376                                                 }
1377                                                 to_write = nto_write;
1378
1379                                                 (*chan).write_source->mark_capture_end ();
1380                                                 
1381                                                 // increment past this transition, but go no further
1382                                                 ++ti;
1383                                                 break;
1384                                         }
1385                                         else {
1386                                                 // actually ends just beyond this chunk, so force more work
1387                                                 ret = 1;
1388                                                 break;
1389                                         }
1390                                 }
1391                         }
1392
1393                         if (ti > 0) {
1394                                 (*chan).capture_transition_buf->increment_read_ptr(ti);
1395                         }
1396                 }
1397
1398                 if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
1399                         error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
1400                         return -1;
1401                 }
1402
1403                 (*chan).capture_buf->increment_read_ptr (to_write);
1404                 (*chan).curr_capture_cnt += to_write;
1405                 
1406                 if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
1407                 
1408                         /* we wrote all of vector.len[0] but it wasn't an entire
1409                            disk_io_chunk_frames of data, so arrange for some part 
1410                            of vector.len[1] to be flushed to disk as well.
1411                         */
1412                         
1413                         to_write = min ((nframes_t)(disk_io_chunk_frames - to_write), (nframes_t) vector.len[1]);
1414
1415                         if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
1416                                 error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
1417                                 return -1;
1418                         }
1419
1420                         _write_data_count += (*chan).write_source->write_data_count();
1421         
1422                         (*chan).capture_buf->increment_read_ptr (to_write);
1423                         (*chan).curr_capture_cnt += to_write;
1424                 }
1425         }
1426
1427   out:
1428         return ret;
1429 }
1430
1431 void
1432 AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
1433 {
1434         uint32_t buffer_position;
1435         bool more_work = true;
1436         int err = 0;
1437         boost::shared_ptr<AudioRegion> region;
1438         nframes_t total_capture;
1439         SourceList srcs;
1440         SourceList::iterator src;
1441         ChannelList::iterator chan;
1442         vector<CaptureInfo*>::iterator ci;
1443         uint32_t n = 0; 
1444         bool mark_write_completed = false;
1445
1446         finish_capture (true);
1447
1448         /* butler is already stopped, but there may be work to do 
1449            to flush remaining data to disk.
1450         */
1451
1452         while (more_work && !err) {
1453                 switch (do_flush (Session::TransportContext, true)) {
1454                 case 0:
1455                         more_work = false;
1456                         break;
1457                 case 1:
1458                         break;
1459                 case -1:
1460                         error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
1461                         err++;
1462                 }
1463         }
1464
1465         /* XXX is there anything we can do if err != 0 ? */
1466         Glib::Mutex::Lock lm (capture_info_lock);
1467         
1468         if (capture_info.empty()) {
1469                 return;
1470         }
1471
1472         if (abort_capture) {
1473                 
1474                 if (destructive()) {
1475                         goto outout;
1476                 }
1477
1478                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1479
1480                         if ((*chan).write_source) {
1481                                 
1482                                 (*chan).write_source->mark_for_remove ();
1483                                 (*chan).write_source->drop_references ();
1484                                 (*chan).write_source.reset ();
1485                         }
1486                         
1487                         /* new source set up in "out" below */
1488                 }
1489
1490                 goto out;
1491         } 
1492
1493         for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1494                 total_capture += (*ci)->frames;
1495         }
1496
1497         /* figure out the name for this take */
1498
1499         for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
1500
1501                 boost::shared_ptr<AudioFileSource> s = (*chan).write_source;
1502                 
1503                 if (s) {
1504                         srcs.push_back (s);
1505                         s->update_header (capture_info.front()->start, when, twhen);
1506                         s->set_captured_for (_name);
1507                         s->mark_immutable ();
1508                 }
1509         }
1510
1511         /* destructive tracks have a single, never changing region */
1512
1513         if (destructive()) {
1514
1515                 /* send a signal that any UI can pick up to do the right thing. there is 
1516                    a small problem here in that a UI may need the peak data to be ready
1517                    for the data that was recorded and this isn't interlocked with that
1518                    process. this problem is deferred to the UI.
1519                  */
1520                 
1521                 _playlist->Modified();
1522
1523         } else {
1524
1525                 string whole_file_region_name;
1526                 whole_file_region_name = region_name_from_path (channels[0].write_source->name(), true);
1527
1528                 /* Register a new region with the Session that
1529                    describes the entire source. Do this first
1530                    so that any sub-regions will obviously be
1531                    children of this one (later!)
1532                 */
1533                 
1534                 try {
1535                         boost::shared_ptr<Region> rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, 
1536                                                                              whole_file_region_name,
1537                                                                              0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
1538
1539                         region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1540                         region->special_set_position (capture_info.front()->start);
1541                 }
1542                 
1543                 
1544                 catch (failed_constructor& err) {
1545                         error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1546                         /* XXX what now? */
1547                 }
1548                 
1549                 _last_capture_regions.push_back (region);
1550
1551                 // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
1552                 
1553                 XMLNode &before = _playlist->get_state();
1554                 _playlist->freeze ();
1555                 
1556                 for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1557                         
1558                         string region_name;
1559
1560                         _session.region_name (region_name, whole_file_region_name, false);
1561                         
1562                         // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
1563                         
1564                         try {
1565                                 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
1566                                 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1567                         }
1568                         
1569                         catch (failed_constructor& err) {
1570                                 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1571                                 continue; /* XXX is this OK? */
1572                         }
1573                         
1574                         region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region)));
1575                         
1576                         _last_capture_regions.push_back (region);
1577                         
1578                         i_am_the_modifier++;
1579                         _playlist->add_region (region, (*ci)->start);
1580                         i_am_the_modifier--;
1581                         
1582                         buffer_position += (*ci)->frames;
1583                 }
1584
1585                 _playlist->thaw ();
1586                 XMLNode &after = _playlist->get_state();
1587                 _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
1588         }
1589
1590         mark_write_completed = true;
1591
1592   out:
1593         reset_write_sources (mark_write_completed);
1594
1595   outout:
1596
1597         for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1598                 delete *ci;
1599         }
1600
1601         capture_info.clear ();
1602         capture_start_frame = 0;
1603 }
1604
1605 void
1606 AudioDiskstream::finish_capture (bool rec_monitors_input)
1607 {
1608         was_recording = false;
1609         
1610         if (capture_captured == 0) {
1611                 return;
1612         }
1613
1614         if (recordable() && destructive()) {
1615                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1616                         
1617                         RingBufferNPT<CaptureTransition>::rw_vector transvec;
1618                         (*chan).capture_transition_buf->get_write_vector(&transvec);
1619                         
1620                         
1621                         if (transvec.len[0] > 0) {
1622                                 transvec.buf[0]->type = CaptureEnd;
1623                                 transvec.buf[0]->capture_val = capture_captured;
1624                                 (*chan).capture_transition_buf->increment_write_ptr(1);
1625                         }
1626                         else {
1627                                 // bad!
1628                                 fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
1629                         }
1630                 }
1631         }
1632         
1633         
1634         CaptureInfo* ci = new CaptureInfo;
1635         
1636         ci->start =  capture_start_frame;
1637         ci->frames = capture_captured;
1638         
1639         /* XXX theoretical race condition here. Need atomic exchange ? 
1640            However, the circumstances when this is called right 
1641            now (either on record-disable or transport_stopped)
1642            mean that no actual race exists. I think ...
1643            We now have a capture_info_lock, but it is only to be used
1644            to synchronize in the transport_stop and the capture info
1645            accessors, so that invalidation will not occur (both non-realtime).
1646         */
1647
1648         // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
1649
1650         capture_info.push_back (ci);
1651         capture_captured = 0;
1652 }
1653
1654 void
1655 AudioDiskstream::set_record_enabled (bool yn)
1656 {
1657         if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs() == 0) {
1658                 return;
1659         }
1660
1661         /* can't rec-enable in destructive mode if transport is before start */
1662
1663         if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
1664                 return;
1665         }
1666
1667         if (yn && channels[0].source == 0) {
1668
1669                 /* pick up connections not initiated *from* the IO object
1670                    we're associated with.
1671                 */
1672
1673                 get_input_sources ();
1674         }
1675
1676         /* yes, i know that this not proof against race conditions, but its
1677            good enough. i think.
1678         */
1679
1680         if (record_enabled() != yn) {
1681                 if (yn) {
1682                         engage_record_enable ();
1683                 } else {
1684                         disengage_record_enable ();
1685                 }
1686         }
1687 }
1688
1689 void
1690 AudioDiskstream::engage_record_enable ()
1691 {
1692     bool rolling = _session.transport_speed() != 0.0f;
1693
1694         g_atomic_int_set (&_record_enabled, 1);
1695         capturing_sources.clear ();
1696
1697         if (Config->get_monitoring_model() == HardwareMonitoring) {
1698
1699                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1700                         if ((*chan).source) {
1701                                 (*chan).source->ensure_monitor_input (!(Config->get_auto_input() && rolling));
1702                         }
1703                         capturing_sources.push_back ((*chan).write_source);
1704                 }
1705                 
1706         } else {
1707                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1708                         capturing_sources.push_back ((*chan).write_source);
1709                 }
1710         }
1711
1712         RecordEnableChanged (); /* EMIT SIGNAL */
1713 }
1714
1715 void
1716 AudioDiskstream::disengage_record_enable ()
1717 {
1718         g_atomic_int_set (&_record_enabled, 0);
1719         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
1720                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1721                         if ((*chan).source) {
1722                                 (*chan).source->ensure_monitor_input (false);
1723                         }
1724                 }
1725         }
1726         capturing_sources.clear ();
1727         RecordEnableChanged (); /* EMIT SIGNAL */
1728 }
1729
1730 XMLNode&
1731 AudioDiskstream::get_state ()
1732 {
1733         XMLNode* node = new XMLNode ("AudioDiskstream");
1734         char buf[64] = "";
1735         LocaleGuard lg (X_("POSIX"));
1736
1737         node->add_property ("flags", enum_2_string (_flags));
1738
1739         snprintf (buf, sizeof(buf), "%zd", channels.size());
1740         node->add_property ("channels", buf);
1741
1742         node->add_property ("playlist", _playlist->name());
1743         
1744         snprintf (buf, sizeof(buf), "%.12g", _visible_speed);
1745         node->add_property ("speed", buf);
1746
1747         node->add_property("name", _name);
1748         id().print (buf, sizeof (buf));
1749         node->add_property("id", buf);
1750
1751         if (!capturing_sources.empty() && _session.get_record_enabled()) {
1752
1753                 XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
1754                 XMLNode* cs_grandchild;
1755
1756                 for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
1757                         cs_grandchild = new XMLNode (X_("file"));
1758                         cs_grandchild->add_property (X_("path"), (*i)->path());
1759                         cs_child->add_child_nocopy (*cs_grandchild);
1760                 }
1761
1762                 /* store the location where capture will start */
1763
1764                 Location* pi;
1765
1766                 if (Config->get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
1767                         snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
1768                 } else {
1769                         snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
1770                 }
1771
1772                 cs_child->add_property (X_("at"), buf);
1773                 node->add_child_nocopy (*cs_child);
1774         }
1775
1776         if (_extra_xml) {
1777                 node->add_child_copy (*_extra_xml);
1778         }
1779
1780         return* node;
1781 }
1782
1783 int
1784 AudioDiskstream::set_state (const XMLNode& node)
1785 {
1786         const XMLProperty* prop;
1787         XMLNodeList nlist = node.children();
1788         XMLNodeIterator niter;
1789         uint32_t nchans = 1;
1790         XMLNode* capture_pending_node = 0;
1791         LocaleGuard lg (X_("POSIX"));
1792
1793         in_set_state = true;
1794
1795         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1796                 if ((*niter)->name() == IO::state_node_name) {
1797                         deprecated_io_node = new XMLNode (**niter);
1798                 }
1799
1800                 if ((*niter)->name() == X_("CapturingSources")) {
1801                         capture_pending_node = *niter;
1802                 }
1803         }
1804
1805         /* prevent write sources from being created */
1806         
1807         in_set_state = true;
1808         
1809         if ((prop = node.property ("name")) != 0) {
1810                 _name = prop->value();
1811         } 
1812
1813         if (deprecated_io_node) {
1814                 if ((prop = deprecated_io_node->property ("id")) != 0) {
1815                         _id = prop->value ();
1816                 }
1817         } else {
1818                 if ((prop = node.property ("id")) != 0) {
1819                         _id = prop->value ();
1820                 }
1821         }
1822
1823         if ((prop = node.property ("flags")) != 0) {
1824                 _flags = Flag (string_2_enum (prop->value(), _flags));
1825         }
1826
1827         if ((prop = node.property ("channels")) != 0) {
1828                 nchans = atoi (prop->value().c_str());
1829         }
1830         
1831         // create necessary extra channels
1832         // we are always constructed with one and we always need one
1833
1834         if (nchans > _n_channels) {
1835
1836                 // we need to add new channel infos
1837                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1838
1839                 int diff = nchans - channels.size();
1840
1841                 for (int i=0; i < diff; ++i) {
1842                         add_channel ();
1843                 }
1844
1845         } else if (nchans < _n_channels) {
1846
1847                 // we need to get rid of channels
1848                 //LockMonitor lm (state_lock, __LINE__, __FILE__);
1849
1850                 int diff = channels.size() - nchans;
1851                 
1852                 for (int i = 0; i < diff; ++i) {
1853                         remove_channel ();
1854                 }
1855         }
1856
1857         if ((prop = node.property ("playlist")) == 0) {
1858                 return -1;
1859         }
1860
1861         {
1862                 bool had_playlist = (_playlist != 0);
1863         
1864                 if (find_and_use_playlist (prop->value())) {
1865                         return -1;
1866                 }
1867
1868                 if (!had_playlist) {
1869                         _playlist->set_orig_diskstream_id (_id);
1870                 }
1871                 
1872                 if (!destructive() && capture_pending_node) {
1873                         /* destructive streams have one and only one source per channel,
1874                            and so they never end up in pending capture in any useful
1875                            sense.
1876                         */
1877                         use_pending_capture_data (*capture_pending_node);
1878                 }
1879
1880         }
1881
1882         if ((prop = node.property ("speed")) != 0) {
1883                 double sp = atof (prop->value().c_str());
1884
1885                 if (realtime_set_speed (sp, false)) {
1886                         non_realtime_set_speed ();
1887                 }
1888         }
1889
1890         _n_channels = channels.size();
1891
1892         in_set_state = false;
1893
1894         /* make sure this is clear before we do anything else */
1895
1896         capturing_sources.clear ();
1897
1898         /* write sources are handled when we handle the input set 
1899            up of the IO that owns this DS (::non_realtime_input_change())
1900         */
1901                 
1902         in_set_state = false;
1903
1904         return 0;
1905 }
1906
1907 int
1908 AudioDiskstream::use_new_write_source (uint32_t n)
1909 {
1910         if (!recordable()) {
1911                 return 1;
1912         }
1913
1914         if (n >= channels.size()) {
1915                 error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
1916                 return -1;
1917         }
1918
1919         ChannelInfo &chan = channels[n];
1920         
1921         if (chan.write_source) {
1922                 chan.write_source->done_with_peakfile_writes ();
1923                 chan.write_source->set_allow_remove_if_empty (true);
1924                 chan.write_source.reset ();
1925         }
1926
1927         try {
1928                 if ((chan.write_source = _session.create_audio_source_for_session (*this, n, destructive())) == 0) {
1929                         throw failed_constructor();
1930                 }
1931         } 
1932
1933         catch (failed_constructor &err) {
1934                 error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
1935                 chan.write_source.reset ();
1936                 return -1;
1937         }
1938
1939         /* do not remove destructive files even if they are empty */
1940
1941         chan.write_source->set_allow_remove_if_empty (!destructive());
1942
1943         return 0;
1944 }
1945
1946 void
1947 AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force)
1948 {
1949         ChannelList::iterator chan;
1950         uint32_t n;
1951
1952         if (!recordable()) {
1953                 return;
1954         }
1955         
1956         capturing_sources.clear ();
1957
1958         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
1959                 if (!destructive()) {
1960
1961                         if ((*chan).write_source && mark_write_complete) {
1962                                 (*chan).write_source->mark_streaming_write_completed ();
1963                         }
1964                         use_new_write_source (n);
1965
1966                         if (record_enabled()) {
1967                                 capturing_sources.push_back ((*chan).write_source);
1968                         }
1969
1970                 } else {
1971                         if ((*chan).write_source == 0) {
1972                                 use_new_write_source (n);
1973                         }
1974                 }
1975         }
1976
1977         if (destructive()) {
1978
1979                 /* we now have all our write sources set up, so create the
1980                    playlist's single region.
1981                 */
1982
1983                 if (_playlist->empty()) {
1984                         setup_destructive_playlist ();
1985                 }
1986         }
1987 }
1988
1989 int
1990 AudioDiskstream::rename_write_sources ()
1991 {
1992         ChannelList::iterator chan;
1993         uint32_t n;
1994
1995         for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
1996                 if ((*chan).write_source != 0) {
1997                         (*chan).write_source->set_name (_name, destructive());
1998                         /* XXX what to do if one of them fails ? */
1999                 }
2000         }
2001
2002         return 0;
2003 }
2004
2005 void
2006 AudioDiskstream::set_block_size (nframes_t nframes)
2007 {
2008         if (_session.get_block_size() > speed_buffer_size) {
2009                 speed_buffer_size = _session.get_block_size();
2010
2011                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2012                         if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
2013                         (*chan).speed_buffer = new Sample[speed_buffer_size];
2014                 }
2015         }
2016         allocate_temporary_buffers ();
2017 }
2018
2019 void
2020 AudioDiskstream::allocate_temporary_buffers ()
2021 {
2022         /* make sure the wrap buffer is at least large enough to deal
2023            with the speeds up to 1.2, to allow for micro-variation
2024            when slaving to MTC, SMPTE etc.
2025         */
2026
2027         double sp = max (fabsf (_actual_speed), 1.2f);
2028         nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * sp) + 1;
2029
2030         if (required_wrap_size > wrap_buffer_size) {
2031
2032                 for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2033                         if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
2034                         (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
2035                         if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
2036                         (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
2037                 }
2038
2039                 wrap_buffer_size = required_wrap_size;
2040         }
2041 }
2042
2043 void
2044 AudioDiskstream::monitor_input (bool yn)
2045 {
2046         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2047                 
2048                 if ((*chan).source) {
2049                         (*chan).source->ensure_monitor_input (yn);
2050                 }
2051         }
2052 }
2053
2054 void
2055 AudioDiskstream::set_align_style_from_io ()
2056 {
2057         bool have_physical = false;
2058
2059         if (_io == 0) {
2060                 return;
2061         }
2062
2063         get_input_sources ();
2064         
2065         for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
2066                 if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
2067                         have_physical = true;
2068                         break;
2069                 }
2070         }
2071
2072         if (have_physical) {
2073                 set_align_style (ExistingMaterial);
2074         } else {
2075                 set_align_style (CaptureTime);
2076         }
2077 }
2078
2079 int
2080 AudioDiskstream::add_channel ()
2081 {
2082         /* XXX need to take lock??? */
2083
2084         /* this copies the ChannelInfo, which currently has no buffers. kind
2085            of pointless really, but we want the channels list to contain
2086            actual objects, not pointers to objects. mostly for convenience,
2087            which isn't much in evidence.
2088         */
2089
2090         channels.push_back (ChannelInfo());
2091
2092         /* now allocate the buffers */
2093
2094         channels.back().init (_session.diskstream_buffer_size(), 
2095                               speed_buffer_size,
2096                               wrap_buffer_size);
2097
2098         _n_channels = channels.size();
2099
2100         return 0;
2101 }
2102
2103 int
2104 AudioDiskstream::remove_channel ()
2105 {
2106         if (channels.size() > 1) {
2107                 /* XXX need to take lock??? */
2108                 channels.back().release ();
2109                 channels.pop_back();
2110                 _n_channels = channels.size();
2111                 return 0;
2112         }
2113
2114         return -1;
2115 }
2116
2117 float
2118 AudioDiskstream::playback_buffer_load () const
2119 {
2120         return (float) ((double) channels.front().playback_buf->read_space()/
2121                         (double) channels.front().playback_buf->bufsize());
2122 }
2123
2124 float
2125 AudioDiskstream::capture_buffer_load () const
2126 {
2127         return (float) ((double) channels.front().capture_buf->write_space()/
2128                         (double) channels.front().capture_buf->bufsize());
2129 }
2130
2131 int
2132 AudioDiskstream::use_pending_capture_data (XMLNode& node)
2133 {
2134         const XMLProperty* prop;
2135         XMLNodeList nlist = node.children();
2136         XMLNodeIterator niter;
2137         boost::shared_ptr<AudioFileSource> fs;
2138         boost::shared_ptr<AudioFileSource> first_fs;
2139         SourceList pending_sources;
2140         nframes_t position;
2141
2142         if ((prop = node.property (X_("at"))) == 0) {
2143                 return -1;
2144         }
2145
2146         if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
2147                 return -1;
2148         }
2149
2150         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2151                 if ((*niter)->name() == X_("file")) {
2152
2153                         if ((prop = (*niter)->property (X_("path"))) == 0) {
2154                                 continue;
2155                         }
2156
2157                         try {
2158                                 fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (_session, prop->value(), false, _session.frame_rate()));
2159                         }
2160
2161                         catch (failed_constructor& err) {
2162                                 error << string_compose (_("%1: cannot restore pending capture source file %2"),
2163                                                   _name, prop->value())
2164                                       << endmsg;
2165                                 return -1;
2166                         }
2167
2168                         pending_sources.push_back (fs);
2169                         
2170                         if (first_fs == 0) {
2171                                 first_fs = fs;
2172                         }
2173
2174                         fs->set_captured_for (_name);
2175                 }
2176         }
2177
2178         if (pending_sources.size() == 0) {
2179                 /* nothing can be done */
2180                 return 1;
2181         }
2182
2183         if (pending_sources.size() != _n_channels) {
2184                 error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
2185                       << endmsg;
2186                 return -1;
2187         }
2188
2189         boost::shared_ptr<AudioRegion> region;
2190         
2191         try {
2192                 region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(),
2193                                                                                           region_name_from_path (first_fs->name(), true), 
2194                                                                                           0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
2195                 region->special_set_position (0);
2196         }
2197
2198         catch (failed_constructor& err) {
2199                 error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
2200                                   _name)
2201                       << endmsg;
2202                 
2203                 return -1;
2204         }
2205
2206         try {
2207                 region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name(), true)));
2208         }
2209
2210         catch (failed_constructor& err) {
2211                 error << string_compose (_("%1: cannot create region from pending capture sources"),
2212                                   _name)
2213                       << endmsg;
2214                 
2215                 return -1;
2216         }
2217
2218         _playlist->add_region (region, position);
2219
2220         return 0;
2221 }
2222
2223 int
2224 AudioDiskstream::set_destructive (bool yn)
2225 {
2226         bool bounce_ignored;
2227
2228         if (yn != destructive()) {
2229                 
2230                 if (yn) {
2231                         /* requestor should already have checked this and
2232                            bounced if necessary and desired 
2233                         */
2234                         if (!can_become_destructive (bounce_ignored)) {
2235                                 return -1;
2236                         }
2237                         _flags = Flag (_flags | Destructive);
2238                         use_destructive_playlist ();
2239                 } else {
2240                         _flags = Flag (_flags & ~Destructive);
2241                         reset_write_sources (true, true);
2242                 }
2243         }
2244
2245         return 0;
2246 }
2247
2248 bool
2249 AudioDiskstream::can_become_destructive (bool& requires_bounce) const
2250 {
2251         if (!_playlist) {
2252                 requires_bounce = false;
2253                 return false;
2254         }
2255
2256         /* is there only one region ? */
2257
2258         if (_playlist->n_regions() != 1) {
2259                 requires_bounce = true;
2260                 return false;
2261         }
2262
2263         boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1);
2264         assert (first);
2265
2266         /* do the source(s) for the region cover the session start position ? */
2267         
2268         if (first->position() != _session.current_start_frame()) {
2269                 if (first->start() > _session.current_start_frame()) {
2270                         requires_bounce = true;
2271                         return false;
2272                 }
2273         }
2274
2275         /* is the source used by only 1 playlist ? */
2276
2277         boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first);
2278
2279         assert (afirst);
2280
2281         if (afirst->source()->used() > 1) {
2282                 requires_bounce = true; 
2283                 return false;
2284         }
2285
2286         requires_bounce = false;
2287         return true;
2288 }
2289
2290 AudioDiskstream::ChannelInfo::ChannelInfo ()
2291 {
2292         playback_wrap_buffer = 0;
2293         capture_wrap_buffer = 0;
2294         speed_buffer = 0;
2295         peak_power = 0.0f;
2296         source = 0;
2297         current_capture_buffer = 0;
2298         current_playback_buffer = 0;
2299         curr_capture_cnt = 0;
2300         playback_buf = 0;
2301         capture_buf = 0;
2302         capture_transition_buf = 0;
2303 }
2304
2305 void
2306 AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size)
2307 {
2308         speed_buffer = new Sample[speed_size];
2309         playback_wrap_buffer = new Sample[wrap_size];
2310         capture_wrap_buffer = new Sample[wrap_size];
2311
2312         playback_buf = new RingBufferNPT<Sample> (bufsize);
2313         capture_buf = new RingBufferNPT<Sample> (bufsize);
2314         capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
2315         
2316         /* touch the ringbuffer buffers, which will cause
2317            them to be mapped into locked physical RAM if
2318            we're running with mlockall(). this doesn't do
2319            much if we're not.  
2320         */
2321
2322         memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize());
2323         memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize());
2324         memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize());
2325 }
2326
2327 AudioDiskstream::ChannelInfo::~ChannelInfo ()
2328 {
2329 }
2330
2331 void
2332 AudioDiskstream::ChannelInfo::release ()
2333 {
2334         if (write_source) {
2335                 write_source.reset ();
2336         }
2337                 
2338         if (speed_buffer) {
2339                 delete [] speed_buffer;
2340                 speed_buffer = 0;
2341         }
2342
2343         if (playback_wrap_buffer) {
2344                 delete [] playback_wrap_buffer;
2345                 playback_wrap_buffer = 0;
2346         }
2347
2348         if (capture_wrap_buffer) {
2349                 delete [] capture_wrap_buffer;
2350                 capture_wrap_buffer = 0;
2351         }
2352         
2353         if (playback_buf) {
2354                 delete playback_buf;
2355                 playback_buf = 0;
2356         }
2357
2358         if (capture_buf) {
2359                 delete capture_buf;
2360                 capture_buf = 0;
2361         }
2362
2363         if (capture_transition_buf) {
2364                 delete capture_transition_buf;
2365                 capture_transition_buf = 0;
2366         }
2367 }