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