clean up VST debugging output
[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, nframes_t offset, int declick, bool meter)
467 {
468         uint32_t nbufs = n_process_buffers ();
469         process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, offset, true, declick, meter);
470 }
471
472 int 
473 AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
474                      bool session_state_changing, bool can_record, bool rec_monitors_input)
475 {
476         if (n_outputs() == 0) {
477                 return 0;
478         }
479
480         if (!_active) {
481                 silence (nframes, offset);
482                 return 0;
483         }
484
485         if (session_state_changing) {
486
487                 /* XXX is this safe to do against transport state changes? */
488
489                 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
490                 return 0;
491         }
492
493         audio_diskstream()->check_record_status (start_frame, nframes, can_record);
494
495         bool send_silence;
496         
497         if (_have_internal_generator) {
498                 /* since the instrument has no input streams,
499                    there is no reason to send any signal
500                    into the route.
501                 */
502                 send_silence = true;
503         } else {
504
505                 if (!Config->get_tape_machine_mode()) {
506                         /* 
507                            ADATs work in a strange way.. 
508                            they monitor input always when stopped.and auto-input is engaged. 
509                         */
510                         if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) {
511                                 send_silence = false;
512                         } else {
513                                 send_silence = true;
514                         }
515                 } else {
516                         /* 
517                            Other machines switch to input on stop if the track is record enabled,
518                            regardless of the auto input setting (auto input only changes the 
519                            monitoring state when the transport is rolling) 
520                         */
521                         if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) {
522                                 send_silence = false;
523                         } else {
524                                 send_silence = true;
525                         }
526                 }
527         }
528
529         apply_gain_automation = false;
530
531         if (send_silence) {
532                 
533                 /* if we're sending silence, but we want the meters to show levels for the signal,
534                    meter right here.
535                 */
536                 
537                 if (_have_internal_generator) {
538                         passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
539                 } else {
540                         if (_meter_point == MeterInput) {
541                                 just_meter_input (start_frame, end_frame, nframes, offset);
542                         }
543                         passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
544                 }
545
546         } else {
547         
548                 /* we're sending signal, but we may still want to meter the input. 
549                  */
550
551                 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
552         }
553
554         return 0;
555 }
556
557 int
558 AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
559                   bool can_record, bool rec_monitors_input)
560 {
561         int dret;
562         Sample* b;
563         Sample* tmpb;
564         nframes_t transport_frame;
565         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
566
567         {
568                 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
569                 if (lm.locked()) {
570                         // automation snapshot can also be called from the non-rt context
571                         // and it uses the redirect list, so we take the lock out here
572                         automation_snapshot (start_frame, false);
573                 }
574         }
575
576         
577         if (n_outputs() == 0 && _redirects.empty()) {
578                 return 0;
579         }
580
581         if (!_active) {
582                 silence (nframes, offset);
583                 return 0;
584         }
585
586         transport_frame = _session.transport_frame();
587
588         if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
589                 /* need to do this so that the diskstream sets its
590                    playback distance to zero, thus causing diskstream::commit
591                    to do nothing.
592                 */
593                 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
594         } 
595
596         _silent = false;
597         apply_gain_automation = false;
598
599         if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
600                 
601                 silence (nframes, offset);
602
603                 return dret;
604         }
605
606         /* special condition applies */
607         
608         if (_meter_point == MeterInput) {
609                 just_meter_input (start_frame, end_frame, nframes, offset);
610         }
611
612         if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
613
614                 /* not actually recording, but we want to hear the input material anyway,
615                    at least potentially (depending on monitoring options)
616                  */
617
618                 passthru (start_frame, end_frame, nframes, offset, 0, true);
619
620         } else if ((b = diskstream->playback_buffer(0)) != 0) {
621
622                 /*
623                   XXX is it true that the earlier test on n_outputs()
624                   means that we can avoid checking it again here? i think
625                   so, because changing the i/o configuration of an IO
626                   requires holding the AudioEngine lock, which we hold
627                   while in the process() tree.
628                 */
629
630                 
631                 /* copy the diskstream data to all output buffers */
632                 
633                 vector<Sample*>& bufs = _session.get_passthru_buffers ();
634                 vector<Sample*>::size_type blimit = bufs.size();
635                 uint32_t limit = n_process_buffers ();
636                 
637                 uint32_t n;
638                 uint32_t i;
639
640                 if (limit > blimit) {
641
642                         /* example case: auditioner configured for stereo output,
643                            but loaded with an 8 channel file. there are only
644                            2 passthrough buffers, but n_process_buffers() will
645                            return 8.
646                            
647                            arbitrary decision: map all channels in the diskstream
648                            to the outputs available.
649                         */
650
651                         float scaling = limit/blimit;
652                         
653                         for (i = 0, n = 1; i < blimit; ++i, ++n) {
654
655                                 /* first time through just copy a channel into 
656                                    the output buffer.
657                                 */
658                                 
659                                 for (nframes_t xx = 0; xx < nframes; ++xx) {
660                                         bufs[i][xx] = b[xx] * scaling;
661                                 }
662
663                                 if (n < diskstream->n_channels()) {
664                                         tmpb = diskstream->playback_buffer(n);
665                                         if (tmpb!=0) {
666                                                 b = tmpb;
667                                         }
668                                 }
669                         }
670
671                         for (;i < limit; ++i, ++n) {
672                                 
673                                 /* for all remaining channels, sum with existing
674                                    data in the output buffers 
675                                 */
676                                 
677                                 Session::mix_buffers_with_gain (bufs[i%blimit], b, nframes, scaling);
678
679                                 if (n < diskstream->n_channels()) {
680                                         tmpb = diskstream->playback_buffer(n);
681                                         if (tmpb!=0) {
682                                                 b = tmpb;
683                                         }
684                                 }
685                                 
686                         }
687
688                         limit = blimit;
689
690                 } else {
691                         for (i = 0, n = 1; i < limit; ++i, ++n) {
692                                 memcpy (bufs[i], b, sizeof (Sample) * nframes); 
693                                 if (n < diskstream->n_channels()) {
694                                         tmpb = diskstream->playback_buffer(n);
695                                         if (tmpb!=0) {
696                                                 b = tmpb;
697                                         }
698                                 }
699                         }
700                 }
701
702                 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
703
704                 if (!diskstream->record_enabled() && _session.transport_rolling()) {
705                         Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
706                         
707                         if (am.locked() && gain_automation_playback()) {
708                                 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
709                         }
710                 }
711
712                 process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
713                 
714         } else {
715                 /* problem with the diskstream; just be quiet for a bit */
716                 silence (nframes, offset);
717         }
718
719         return 0;
720 }
721
722 int
723 AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
724                          bool can_record, bool rec_monitors_input)
725 {
726         if (n_outputs() == 0 && _redirects.empty()) {
727                 return 0;
728         }
729
730         if (!_active) {
731                 silence (nframes, offset);
732                 return 0;
733         }
734
735         _silent = true;
736         apply_gain_automation = false;
737
738         silence (nframes, offset);
739
740         return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
741 }
742
743 int
744 AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t start, nframes_t nframes, bool enable_processing)
745 {
746         gain_t  gain_automation[nframes];
747         gain_t  gain_buffer[nframes];
748         float   mix_buffer[nframes];
749         RedirectList::iterator i;
750         bool post_fader_work = false;
751         gain_t this_gain = _gain;
752         vector<Sample*>::iterator bi;
753         Sample * b;
754         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
755         
756         Glib::RWLock::ReaderLock rlock (redirect_lock);
757
758         boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
759         assert(apl);
760
761         if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
762                 return -1;
763         }
764
765         uint32_t n=1;
766         bi = buffers.begin();
767         b = buffers[0];
768         ++bi;
769         for (; bi != buffers.end(); ++bi, ++n) {
770                 if (n < diskstream->n_channels()) {
771                         if (apl->read ((*bi), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
772                                 return -1;
773                         }
774                         b = (*bi);
775                 }
776                 else {
777                         /* duplicate last across remaining buffers */
778                         memcpy ((*bi), b, sizeof (Sample) * nframes); 
779                 }
780         }
781
782         // If no processing is required, there's no need to go any further.
783         if (!enable_processing)
784                 return 0;
785
786         /* note: only run inserts during export. other layers in the machinery
787            will already have checked that there are no external port inserts.
788         */
789         
790         for (i = _redirects.begin(); i != _redirects.end(); ++i) {
791                 boost::shared_ptr<Insert> insert;
792                 
793                 if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
794                         switch (insert->placement()) {
795                         case PreFader:
796                                 insert->run (buffers, nbufs, nframes, 0);
797                                 break;
798                         case PostFader:
799                                 post_fader_work = true;
800                                 break;
801                         }
802                 }
803         }
804         
805         if (_gain_automation_curve.automation_state() == Play) {
806                 
807                 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
808
809                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
810                         Sample *b = *bi;
811                         for (nframes_t n = 0; n < nframes; ++n) {
812                                 b[n] *= gain_automation[n];
813                         }
814                 }
815
816         } else {
817
818                 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
819                         apply_gain_to_buffer(*bi, nframes, this_gain);
820                 }
821         }
822
823         if (post_fader_work) {
824
825                 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
826                         boost::shared_ptr<PluginInsert> insert;
827                         
828                         if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
829                                 switch ((*i)->placement()) {
830                                 case PreFader:
831                                         break;
832                                 case PostFader:
833                                         insert->run (buffers, nbufs, nframes, 0);
834                                         break;
835                                 }
836                         }
837                 }
838         } 
839
840         return 0;
841 }
842
843 boost::shared_ptr<Region>
844 AudioTrack::bounce (InterThreadInfo& itt)
845 {
846         vector<boost::shared_ptr<AudioSource> > srcs;
847         return _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), 
848                                                false, srcs, itt);
849 }
850
851
852 boost::shared_ptr<Region>
853 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt, bool enable_processing)
854 {
855         vector<boost::shared_ptr<AudioSource> > srcs;
856         return _session.write_one_audio_track (*this, start, end, false, srcs, itt, enable_processing);
857 }
858
859 void
860 AudioTrack::freeze (InterThreadInfo& itt)
861 {
862         vector<boost::shared_ptr<AudioSource> > srcs;
863         string new_playlist_name;
864         boost::shared_ptr<Playlist> new_playlist;
865         string dir;
866         string region_name;
867         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
868         
869         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
870                 return;
871         }
872
873         uint32_t n = 1;
874
875         while (n < (UINT_MAX-1)) {
876          
877                 string candidate;
878                 
879                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
880
881                 if (_session.playlist_by_name (candidate) == 0) {
882                         new_playlist_name = candidate;
883                         break;
884                 }
885
886                 ++n;
887
888         } 
889
890         if (n == (UINT_MAX-1)) {
891           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
892                             " to create another one"), _freeze_record.playlist->name())
893                << endmsg;
894                 return;
895         }
896
897         boost::shared_ptr<Region> res;
898
899         if ((res = _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
900                 return;
901         }
902
903         _freeze_record.insert_info.clear ();
904         _freeze_record.have_mementos = true;
905
906         {
907                 Glib::RWLock::ReaderLock lm (redirect_lock);
908                 
909                 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
910                         
911                         boost::shared_ptr<Insert> insert;
912
913                         if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
914                                 
915                                 FreezeRecordInsertInfo* frii  = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
916                                 
917                                 frii->id = insert->id();
918
919                                 _freeze_record.insert_info.push_back (frii);
920                                 
921                                 /* now deactivate the insert */
922                                 
923                                 insert->set_active (false, this);
924                         }
925                 }
926         }
927
928         _freeze_record.gain = _gain;
929         _freeze_record.gain_automation_state = _gain_automation_curve.automation_state();
930         _freeze_record.pan_automation_state = _panner->automation_state();
931
932         new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
933         region_name = new_playlist_name;
934
935         /* create a new region from all filesources, keep it private */
936
937         boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), 
938                                                                  region_name, 0, 
939                                                                  (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
940                                                                  false));
941
942         new_playlist->set_orig_diskstream_id (diskstream->id());
943         new_playlist->add_region (region, _session.current_start_frame());
944         new_playlist->set_frozen (true);
945         region->set_locked (true);
946
947         diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
948         diskstream->set_record_enabled (false);
949
950         /* reset stuff that has already been accounted for in the freeze process */
951         
952         set_gain (1.0, this);
953         _gain_automation_curve.set_automation_state (Off);
954         _panner->set_automation_state (Off);
955
956         _freeze_record.state = Frozen;
957         FreezeChange(); /* EMIT SIGNAL */
958 }
959
960 void
961 AudioTrack::unfreeze ()
962 {
963         if (_freeze_record.playlist) {
964                 audio_diskstream()->use_playlist (_freeze_record.playlist);
965
966                 if (_freeze_record.have_mementos) {
967
968                         for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
969                                 (*i)->memento ();
970                         }
971
972                 } else {
973
974                         Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
975                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
976                                 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
977                                         if ((*ii)->id == (*i)->id()) {
978                                                 (*i)->set_state (((*ii)->state));
979                                                 break;
980                                         }
981                                 }
982                         }
983                 }
984                 
985                 _freeze_record.playlist.reset ();
986                 set_gain (_freeze_record.gain, this);
987                 _gain_automation_curve.set_automation_state (_freeze_record.gain_automation_state);
988                 _panner->set_automation_state (_freeze_record.pan_automation_state);
989         }
990
991         _freeze_record.state = UnFrozen;
992         FreezeChange (); /* EMIT SIGNAL */
993 }
994