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