patch from hsyl20 for punch in wierdness (mantis #1937). Thanks!
[ardour.git] / libs / ardour / audio_track.cc
1 /*
2     Copyright (C) 2002 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
20 #include <sigc++/retype.h>
21 #include <sigc++/retype_return.h>
22 #include <sigc++/bind.h>
23
24 #include <pbd/error.h>
25 #include <pbd/enumwriter.h>
26
27 #include <ardour/audio_track.h>
28 #include <ardour/audio_diskstream.h>
29 #include <ardour/session.h>
30 #include <ardour/redirect.h>
31 #include <ardour/audioregion.h>
32 #include <ardour/audiosource.h>
33 #include <ardour/region_factory.h>
34 #include <ardour/route_group_specialized.h>
35 #include <ardour/insert.h>
36 #include <ardour/audioplaylist.h>
37 #include <ardour/playlist_factory.h>
38 #include <ardour/panner.h>
39 #include <ardour/utils.h>
40 #include <ardour/mix.h>
41
42 #include "i18n.h"
43
44 using namespace std;
45 using namespace ARDOUR;
46 using namespace PBD;
47
48 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
49         : Track (sess, name, flag, mode)
50 {
51         use_new_diskstream ();
52 }
53
54 AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
55         : Track (sess, node)
56 {
57         _set_state (node, false);
58 }
59
60 AudioTrack::~AudioTrack ()
61 {
62 }
63
64 void
65 AudioTrack::use_new_diskstream ()
66 {
67         AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
68
69         if (_flags & Hidden) {
70                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
71         } else {
72                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
73         }
74
75         if (_mode == Destructive) {
76                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
77         }
78
79         boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name(), dflags));
80         
81         _session.add_diskstream (ds);
82
83         set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
84 }
85
86 int
87 AudioTrack::set_mode (TrackMode m)
88 {
89         if (m != _mode) {
90
91                 if (_diskstream->set_destructive (m == Destructive)) {
92                         return -1;
93                 }
94
95                 _mode = m;
96                 
97                 TrackModeChanged (); /* EMIT SIGNAL */
98         }
99
100         return 0;
101 }
102
103 bool
104 AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
105 {
106         switch (m) {
107         case Normal:
108                 bounce_required = false;
109                 return true;
110                 
111         case Destructive:
112         default:
113                 return _diskstream->can_become_destructive (bounce_required);
114         }
115 }
116
117 int
118 AudioTrack::deprecated_use_diskstream_connections ()
119 {
120         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
121
122         if (diskstream->deprecated_io_node == 0) {
123                 return 0;
124         }
125
126         const XMLProperty* prop;
127         XMLNode& node (*diskstream->deprecated_io_node);
128
129         /* don't do this more than once. */
130
131         diskstream->deprecated_io_node = 0;
132
133         set_input_minimum (-1);
134         set_input_maximum (-1);
135         set_output_minimum (-1);
136         set_output_maximum (-1);
137         
138         if ((prop = node.property ("gain")) != 0) {
139                 set_gain (atof (prop->value().c_str()), this);
140                 _gain = _desired_gain;
141         }
142
143         if ((prop = node.property ("input-connection")) != 0) {
144                 Connection* c = _session.connection_by_name (prop->value());
145                 
146                 if (c == 0) {
147                         error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
148
149                         string replacement_connection;
150
151                         if (prop->value().find ('+') != string::npos) {
152                                 replacement_connection = _("in 1+2");
153                         } else {
154                                 replacement_connection = _("in 1");
155                         }
156                         
157                         if ((c = _session.connection_by_name (replacement_connection)) == 0) {
158                                 error << _("No input connections available as a replacement")
159                                 << endmsg;
160                                 return -1;
161                         } else {
162                                 info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), prop->value(), replacement_connection)
163                                      << endmsg;
164                         }
165                 }
166
167                 use_input_connection (*c, this);
168
169         } else if ((prop = node.property ("inputs")) != 0) {
170                 if (set_inputs (prop->value())) {
171                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
172                         return -1;
173                 }
174         }
175         
176         return 0;
177 }
178
179 int
180 AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void *src)
181 {
182         _diskstream = ds;
183         _diskstream->set_io (*this);
184         _diskstream->set_destructive (_mode == Destructive);
185
186         if (audio_diskstream()->deprecated_io_node) {
187
188                 if (!connecting_legal) {
189                         ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
190                 } else {
191                         deprecated_use_diskstream_connections ();
192                 }
193         }
194
195         _diskstream->set_record_enabled (false);
196         _diskstream->monitor_input (false);
197
198         ic_connection.disconnect();
199         ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
200
201         DiskstreamChanged (); /* EMIT SIGNAL */
202
203         return 0;
204 }       
205
206 int 
207 AudioTrack::use_diskstream (string name)
208 {
209         boost::shared_ptr<AudioDiskstream> dstream;
210
211         if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream>(_session.diskstream_by_name (name))) == 0) {
212                 error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
213                 return -1;
214         }
215         
216         return set_diskstream (dstream, this);
217 }
218
219 int 
220 AudioTrack::use_diskstream (const PBD::ID& id)
221 {
222         boost::shared_ptr<AudioDiskstream> dstream;
223
224         if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream> (_session.diskstream_by_id (id))) == 0) {
225                 error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
226                 return -1;
227         }
228         
229         return set_diskstream (dstream, this);
230 }
231
232 boost::shared_ptr<AudioDiskstream>
233 AudioTrack::audio_diskstream() const
234 {
235         return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
236 }
237
238 int
239 AudioTrack::set_state (const XMLNode& node)
240 {
241         return _set_state (node, true);
242 }
243
244 int
245 AudioTrack::_set_state (const XMLNode& node, bool call_base)
246 {
247         const XMLProperty *prop;
248         XMLNodeConstIterator iter;
249
250         if (call_base) {
251                 if (Route::_set_state (node, call_base)) {
252                         return -1;
253                 }
254         }
255
256         if ((prop = node.property (X_("mode"))) != 0) {
257                 _mode = TrackMode (string_2_enum (prop->value(), _mode));
258         } else {
259                 _mode = Normal;
260         }
261
262         if ((prop = node.property ("diskstream-id")) == 0) {
263                 
264                 /* some old sessions use the diskstream name rather than the ID */
265
266                 if ((prop = node.property ("diskstream")) == 0) {
267                         fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg;
268                         /*NOTREACHED*/
269                         return -1;
270                 }
271
272                 if (use_diskstream (prop->value())) {
273                         return -1;
274                 }
275
276         } else {
277                 
278                 PBD::ID id (prop->value());
279                 PBD::ID zero ("0");
280
281                 /* this wierd hack is used when creating tracks from a template. there isn't
282                    a particularly good time to interpose between setting the first part of
283                    the track state (notably Route::set_state() and the track mode), and the
284                    second part (diskstream stuff). So, we have a special ID for the diskstream
285                    that means "you should create a new diskstream here, not look for
286                    an old one.
287                 */
288
289                 if (id == zero) {
290                         use_new_diskstream ();
291                 } else if (use_diskstream (id)) {
292                         return -1;
293                 }
294         }
295
296
297         XMLNodeList nlist;
298         XMLNodeConstIterator niter;
299         XMLNode *child;
300
301         nlist = node.children();
302         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
303                 child = *niter;
304
305                 if (child->name() == X_("recenable")) {
306                         _rec_enable_control.set_state (*child);
307                         _session.add_controllable (&_rec_enable_control);
308                 }
309         }
310
311         pending_state = const_cast<XMLNode*> (&node);
312
313         if (_session.state_of_the_state() & Session::Loading) {
314                 _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
315         } else {
316                 set_state_part_two ();
317         }
318
319         return 0;
320 }
321
322 XMLNode& 
323 AudioTrack::state(bool full_state)
324 {
325         XMLNode& root (Route::state(full_state));
326         XMLNode* freeze_node;
327         char buf[64];
328
329         if (_freeze_record.playlist) {
330                 XMLNode* inode;
331
332                 freeze_node = new XMLNode (X_("freeze-info"));
333                 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
334                 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
335
336                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
337                         inode = new XMLNode (X_("insert"));
338                         (*i)->id.print (buf, sizeof (buf));
339                         inode->add_property (X_("id"), buf);
340                         inode->add_child_copy ((*i)->state);
341                 
342                         freeze_node->add_child_nocopy (*inode);
343                 }
344
345                 root.add_child_nocopy (*freeze_node);
346         }
347
348         /* Alignment: act as a proxy for the diskstream */
349         
350         XMLNode* align_node = new XMLNode (X_("alignment"));
351         AlignStyle as = _diskstream->alignment_style ();
352         align_node->add_property (X_("style"), enum_2_string (as));
353         root.add_child_nocopy (*align_node);
354
355         root.add_property (X_("mode"), enum_2_string (_mode));
356
357         /* we don't return diskstream state because we don't
358            own the diskstream exclusively. control of the diskstream
359            state is ceded to the Session, even if we create the
360            diskstream.
361         */
362
363         _diskstream->id().print (buf, sizeof (buf));
364         root.add_property ("diskstream-id", buf);
365
366         root.add_child_nocopy (_rec_enable_control.get_state());
367
368         return root;
369 }
370
371 void
372 AudioTrack::set_state_part_two ()
373 {
374         XMLNode* fnode;
375         XMLProperty* prop;
376         LocaleGuard lg (X_("POSIX"));
377
378         /* During session loading: this is called after all session state has been restored but before
379            ports have been created and connections are established.
380
381            During creation from templates: this is called after ports have been created, and connections
382            are established.
383         */
384
385         if (pending_state == 0) {
386                 return;
387         }
388
389         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
390
391                 
392                 _freeze_record.have_mementos = false;
393                 _freeze_record.state = Frozen;
394                 
395                 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
396                         delete *i;
397                 }
398                 _freeze_record.insert_info.clear ();
399                 
400                 if ((prop = fnode->property (X_("playlist"))) != 0) {
401                         boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
402                         if (pl) {
403                                 _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
404                         } else {
405                                 _freeze_record.playlist.reset ();
406                                 _freeze_record.state = NoFreeze;
407                         return;
408                         }
409                 }
410                 
411                 if ((prop = fnode->property (X_("state"))) != 0) {
412                         _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
413                 }
414                 
415                 XMLNodeConstIterator citer;
416                 XMLNodeList clist = fnode->children();
417                 
418                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
419                         if ((*citer)->name() != X_("insert")) {
420                                 continue;
421                         }
422                         
423                         if ((prop = (*citer)->property (X_("id"))) == 0) {
424                                 continue;
425                         }
426                         
427                         FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()),
428                                                                                    boost::shared_ptr<Insert>());
429                         frii->id = prop->value ();
430                         _freeze_record.insert_info.push_back (frii);
431                 }
432         }
433
434         /* Alignment: act as a proxy for the diskstream */
435
436         if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
437
438                 if ((prop = fnode->property (X_("style"))) != 0) {
439
440                         /* fix for older sessions from before EnumWriter */
441
442                         string pstr;
443
444                         if (prop->value() == "capture") {
445                                 pstr = "CaptureTime";
446                         } else if (prop->value() == "existing") {
447                                 pstr = "ExistingMaterial";
448                         } else {
449                                 pstr = prop->value();
450                         }
451
452                         AlignStyle as = AlignStyle (string_2_enum (pstr, as));
453                         _diskstream->set_persistent_align_style (as);
454                 }
455         }
456         return;
457 }       
458
459 uint32_t
460 AudioTrack::n_process_buffers ()
461 {
462         return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
463 }
464
465 void
466 AudioTrack::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, int declick, bool meter)
467 {
468         uint32_t nbufs = n_process_buffers ();
469
470         process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, true, declick, meter);
471 }
472
473 int 
474 AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, 
475                      bool session_state_changing, bool can_record, bool rec_monitors_input)
476 {
477         if (n_outputs() == 0) {
478                 return 0;
479         }
480
481         if (!_active) {
482                 silence (nframes);
483                 return 0;
484         }
485
486         if (session_state_changing) {
487
488                 /* XXX is this safe to do against transport state changes? */
489
490                 passthru_silence (start_frame, end_frame, nframes, 0, false);
491                 return 0;
492         }
493
494         audio_diskstream()->check_record_status (start_frame, nframes, can_record);
495
496         bool send_silence;
497         
498         if (_have_internal_generator) {
499                 /* since the instrument has no input streams,
500                    there is no reason to send any signal
501                    into the route.
502                 */
503                 send_silence = true;
504         } else {
505
506                 if (!Config->get_tape_machine_mode()) {
507                         /* 
508                            ADATs work in a strange way.. 
509                            they monitor input always when stopped.and auto-input is engaged. 
510                         */
511                         if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) {
512                                 send_silence = false;
513                         } else {
514                                 send_silence = true;
515                         }
516                 } else {
517                         /* 
518                            Other machines switch to input on stop if the track is record enabled,
519                            regardless of the auto input setting (auto input only changes the 
520                            monitoring state when the transport is rolling) 
521                         */
522                         if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) {
523                                 send_silence = false;
524                         } else {
525                                 send_silence = true;
526                         }
527                 }
528         }
529
530         apply_gain_automation = false;
531
532         if (send_silence) {
533                 
534                 /* if we're sending silence, but we want the meters to show levels for the signal,
535                    meter right here.
536                 */
537                 
538                 if (_have_internal_generator) {
539                         passthru_silence (start_frame, end_frame, nframes, 0, true);
540                 } else {
541                         if (_meter_point == MeterInput) {
542                                 just_meter_input (start_frame, end_frame, nframes);
543                         }
544                         passthru_silence (start_frame, end_frame, nframes, 0, false);
545                 }
546
547         } else {
548         
549                 /* we're sending signal, but we may still want to meter the input. 
550                  */
551
552                 passthru (start_frame, end_frame, nframes, 0, (_meter_point == MeterInput));
553         }
554
555         return 0;
556 }
557
558 int
559 AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
560                   bool can_record, bool rec_monitors_input)
561 {
562         int dret;
563         Sample* b;
564         Sample* tmpb;
565         nframes_t transport_frame;
566         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
567
568         {
569                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
570                 if (lm.locked()) {
571                         // automation snapshot can also be called from the non-rt context
572                         // and it uses the redirect list, so we take the lock out here
573                         automation_snapshot (start_frame, false);
574                 }
575         }
576
577         
578         if (n_outputs() == 0 && _redirects.empty()) {
579                 return 0;
580         }
581
582         if (!_active) {
583                 silence (nframes);
584                 return 0;
585         }
586
587         transport_frame = _session.transport_frame();
588
589         if (!can_record || !diskstream->record_enabled()) {
590                 if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
591                         /* need to do this so that the diskstream sets its
592                            playback distance to zero, thus causing diskstream::commit
593                            to do nothing.
594                         */
595                         return diskstream->process (transport_frame, 0, can_record, rec_monitors_input);
596                 } 
597         }
598
599         _silent = false;
600         apply_gain_automation = false;
601
602         if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input)) != 0) {
603                 
604                 silence (nframes);
605
606                 return dret;
607         }
608
609         /* special condition applies */
610         
611         if (_meter_point == MeterInput) {
612                 just_meter_input (start_frame, end_frame, nframes);
613         }
614
615         if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
616
617                 /* not actually recording, but we want to hear the input material anyway,
618                    at least potentially (depending on monitoring options)
619                  */
620
621                 passthru (start_frame, end_frame, nframes, 0, true);
622
623         } else if ((b = diskstream->playback_buffer(0)) != 0) {
624
625                 /*
626                   XXX is it true that the earlier test on n_outputs()
627                   means that we can avoid checking it again here? i think
628                   so, because changing the i/o configuration of an IO
629                   requires holding the AudioEngine lock, which we hold
630                   while in the process() tree.
631                 */
632
633                 
634                 /* copy the diskstream data to all output buffers */
635                 
636                 vector<Sample*>& bufs = _session.get_passthru_buffers ();
637                 vector<Sample*>::size_type blimit = bufs.size();
638                 uint32_t limit = n_process_buffers ();
639                 
640                 uint32_t n;
641                 uint32_t i;
642
643                 if (limit > blimit) {
644
645                         /* example case: auditioner configured for stereo output,
646                            but loaded with an 8 channel file. there are only
647                            2 passthrough buffers, but n_process_buffers() will
648                            return 8.
649                            
650                            arbitrary decision: map all channels in the diskstream
651                            to the outputs available.
652                         */
653
654                         float scaling = limit/blimit;
655                         
656                         for (i = 0, n = 1; i < blimit; ++i, ++n) {
657
658                                 /* first time through just copy a channel into 
659                                    the output buffer.
660                                 */
661                                 
662                                 for (nframes_t xx = 0; xx < nframes; ++xx) {
663                                         bufs[i][xx] = b[xx] * scaling;
664                                 }
665
666                                 if (n < diskstream->n_channels()) {
667                                         tmpb = diskstream->playback_buffer(n);
668                                         if (tmpb!=0) {
669                                                 b = tmpb;
670                                         }
671                                 }
672                         }
673
674                         for (;i < limit; ++i, ++n) {
675                                 
676                                 /* for all remaining channels, sum with existing
677                                    data in the output buffers 
678                                 */
679                                 
680                                 Session::mix_buffers_with_gain (bufs[i%blimit], b, nframes, scaling);
681
682                                 if (n < diskstream->n_channels()) {
683                                         tmpb = diskstream->playback_buffer(n);
684                                         if (tmpb!=0) {
685                                                 b = tmpb;
686                                         }
687                                 }
688                                 
689                         }
690
691                         limit = blimit;
692
693                 } else {
694                         for (i = 0, n = 1; i < limit; ++i, ++n) {
695                                 memcpy (bufs[i], b, sizeof (Sample) * nframes); 
696                                 if (n < diskstream->n_channels()) {
697                                         tmpb = diskstream->playback_buffer(n);
698                                         if (tmpb!=0) {
699                                                 b = tmpb;
700                                         }
701                                 }
702                         }
703                 }
704
705                 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
706
707                 if (!diskstream->record_enabled() && _session.transport_rolling()) {
708                         Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
709                         
710                         if (am.locked() && gain_automation_playback()) {
711                                 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
712                         }
713                 }
714
715                 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
716                 
717         } else {
718                 /* problem with the diskstream; just be quiet for a bit */
719                 silence (nframes);
720         }
721
722         return 0;
723 }
724
725 int
726 AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, 
727                          bool can_record, bool rec_monitors_input)
728 {
729         if (n_outputs() == 0 && _redirects.empty()) {
730                 return 0;
731         }
732
733         if (!_active) {
734                 silence (nframes);
735                 return 0;
736         }
737
738         _silent = true;
739         apply_gain_automation = false;
740
741         silence (nframes);
742
743         return audio_diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
744 }
745
746 int
747 AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t start, nframes_t nframes, bool enable_processing)
748 {
749         gain_t  gain_automation[nframes];
750         gain_t  gain_buffer[nframes];
751         float   mix_buffer[nframes];
752         RedirectList::iterator i;
753         bool post_fader_work = false;
754         gain_t this_gain = _gain;
755         vector<Sample*>::iterator bi;
756         Sample * b;
757         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
758         
759         Glib::RWLock::ReaderLock rlock (redirect_lock);
760
761         boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
762         assert(apl);
763
764         if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
765                 return -1;
766         }
767
768         uint32_t n=1;
769         bi = buffers.begin();
770         b = buffers[0];
771         ++bi;
772         for (; bi != buffers.end(); ++bi, ++n) {
773                 if (n < diskstream->n_channels()) {
774                         if (apl->read ((*bi), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
775                                 return -1;
776                         }
777                         b = (*bi);
778                 }
779                 else {
780                         /* duplicate last across remaining buffers */
781                         memcpy ((*bi), b, sizeof (Sample) * nframes); 
782                 }
783         }
784
785         // If no processing is required, there's no need to go any further.
786         if (!enable_processing)
787                 return 0;
788
789         /* note: only run inserts during export. other layers in the machinery
790            will already have checked that there are no external port inserts.
791         */
792         
793         for (i = _redirects.begin(); i != _redirects.end(); ++i) {
794                 boost::shared_ptr<Insert> insert;
795                 
796                 if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
797                         switch (insert->placement()) {
798                         case PreFader:
799                                 insert->run (buffers, nbufs, nframes);
800                                 break;
801                         case PostFader:
802                                 post_fader_work = true;
803                                 break;
804                         }
805                 }
806         }
807         
808         if (_gain_automation_curve.automation_state() == Play) {
809                 
810                 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
811
812                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
813                         Sample *b = *bi;
814                         for (nframes_t n = 0; n < nframes; ++n) {
815                                 b[n] *= gain_automation[n];
816                         }
817                 }
818
819         } else {
820
821                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
822                         apply_gain_to_buffer(*bi, nframes, this_gain);
823                 }
824         }
825
826         if (post_fader_work) {
827
828                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
829                         boost::shared_ptr<PluginInsert> insert;
830                         
831                         if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
832                                 switch ((*i)->placement()) {
833                                 case PreFader:
834                                         break;
835                                 case PostFader:
836                                         insert->run (buffers, nbufs, nframes);
837                                         break;
838                                 }
839                         }
840                 }
841         } 
842
843         return 0;
844 }
845
846 boost::shared_ptr<Region>
847 AudioTrack::bounce (InterThreadInfo& itt)
848 {
849         vector<boost::shared_ptr<AudioSource> > srcs;
850         return _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), 
851                                                false, srcs, itt);
852 }
853
854
855 boost::shared_ptr<Region>
856 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt, bool enable_processing)
857 {
858         vector<boost::shared_ptr<AudioSource> > srcs;
859         return _session.write_one_audio_track (*this, start, end, false, srcs, itt, enable_processing);
860 }
861
862 void
863 AudioTrack::freeze (InterThreadInfo& itt)
864 {
865         vector<boost::shared_ptr<AudioSource> > srcs;
866         string new_playlist_name;
867         boost::shared_ptr<Playlist> new_playlist;
868         string dir;
869         string region_name;
870         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
871         
872         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
873                 return;
874         }
875
876         uint32_t n = 1;
877
878         while (n < (UINT_MAX-1)) {
879          
880                 string candidate;
881                 
882                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
883
884                 if (_session.playlist_by_name (candidate) == 0) {
885                         new_playlist_name = candidate;
886                         break;
887                 }
888
889                 ++n;
890
891         } 
892
893         if (n == (UINT_MAX-1)) {
894           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
895                             " to create another one"), _freeze_record.playlist->name())
896                << endmsg;
897                 return;
898         }
899
900         boost::shared_ptr<Region> res;
901
902         if ((res = _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
903                 return;
904         }
905
906         _freeze_record.insert_info.clear ();
907         _freeze_record.have_mementos = true;
908
909         {
910                 Glib::RWLock::ReaderLock lm (redirect_lock);
911                 
912                 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
913                         
914                         boost::shared_ptr<Insert> insert;
915
916                         if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
917                                 
918                                 FreezeRecordInsertInfo* frii  = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
919                                 
920                                 frii->id = insert->id();
921
922                                 _freeze_record.insert_info.push_back (frii);
923                                 
924                                 /* now deactivate the insert */
925                                 
926                                 insert->set_active (false, this);
927                         }
928                 }
929         }
930
931         _freeze_record.gain = _gain;
932         _freeze_record.gain_automation_state = _gain_automation_curve.automation_state();
933         _freeze_record.pan_automation_state = _panner->automation_state();
934
935         new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
936         region_name = new_playlist_name;
937
938         /* create a new region from all filesources, keep it private */
939
940         boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), 
941                                                                  region_name, 0, 
942                                                                  (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
943                                                                  false));
944
945         new_playlist->set_orig_diskstream_id (diskstream->id());
946         new_playlist->add_region (region, _session.current_start_frame());
947         new_playlist->set_frozen (true);
948         region->set_locked (true);
949
950         diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
951         diskstream->set_record_enabled (false);
952
953         /* reset stuff that has already been accounted for in the freeze process */
954         
955         set_gain (1.0, this);
956         _gain_automation_curve.set_automation_state (Off);
957         _panner->set_automation_state (Off);
958
959         _freeze_record.state = Frozen;
960         FreezeChange(); /* EMIT SIGNAL */
961 }
962
963 void
964 AudioTrack::unfreeze ()
965 {
966         if (_freeze_record.playlist) {
967                 audio_diskstream()->use_playlist (_freeze_record.playlist);
968
969                 if (_freeze_record.have_mementos) {
970
971                         for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
972                                 (*i)->memento ();
973                         }
974
975                 } else {
976
977                         Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
978                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
979                                 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
980                                         if ((*ii)->id == (*i)->id()) {
981                                                 (*i)->set_state (((*ii)->state));
982                                                 break;
983                                         }
984                                 }
985                         }
986                 }
987                 
988                 _freeze_record.playlist.reset ();
989                 set_gain (_freeze_record.gain, this);
990                 _gain_automation_curve.set_automation_state (_freeze_record.gain_automation_state);
991                 _panner->set_automation_state (_freeze_record.pan_automation_state);
992         }
993
994         _freeze_record.state = UnFrozen;
995         FreezeChange (); /* EMIT SIGNAL */
996 }
997