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