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