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