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