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