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