Fix split buffer audio glitches with lv2 plugins.
[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_tape_machine_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 () || _diskstream->record_enabled())) {
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 boost::shared_ptr<Region>
767 AudioTrack::bounce (InterThreadInfo& itt)
768 {
769         vector<boost::shared_ptr<AudioSource> > srcs;
770         return _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), 
771                                                false, srcs, itt);
772 }
773
774
775 boost::shared_ptr<Region>
776 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
777 {
778         vector<boost::shared_ptr<AudioSource> > srcs;
779         return _session.write_one_audio_track (*this, start, end, false, srcs, itt);
780 }
781
782 void
783 AudioTrack::freeze (InterThreadInfo& itt)
784 {
785         vector<boost::shared_ptr<AudioSource> > srcs;
786         string new_playlist_name;
787         boost::shared_ptr<Playlist> new_playlist;
788         string dir;
789         string region_name;
790         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
791         
792         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
793                 return;
794         }
795
796         uint32_t n = 1;
797
798         while (n < (UINT_MAX-1)) {
799          
800                 string candidate;
801                 
802                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
803
804                 if (_session.playlist_by_name (candidate) == 0) {
805                         new_playlist_name = candidate;
806                         break;
807                 }
808
809                 ++n;
810
811         } 
812
813         if (n == (UINT_MAX-1)) {
814           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
815                             " to create another one"), _freeze_record.playlist->name())
816                << endmsg;
817                 return;
818         }
819
820         boost::shared_ptr<Region> res;
821
822         if ((res = _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
823                 return;
824         }
825
826         _freeze_record.insert_info.clear ();
827         _freeze_record.have_mementos = true;
828
829         {
830                 Glib::RWLock::ReaderLock lm (redirect_lock);
831                 
832                 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
833                         
834                         boost::shared_ptr<Insert> insert;
835
836                         if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
837                                 
838                                 FreezeRecordInsertInfo* frii  = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
839                                 
840                                 frii->id = insert->id();
841
842                                 _freeze_record.insert_info.push_back (frii);
843                                 
844                                 /* now deactivate the insert */
845                                 
846                                 insert->set_active (false, this);
847                         }
848                 }
849         }
850
851         new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
852         region_name = new_playlist_name;
853
854         /* create a new region from all filesources, keep it private */
855
856         boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), 
857                                                                  region_name, 0, 
858                                                                  (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
859                                                                  false));
860
861         new_playlist->set_orig_diskstream_id (diskstream->id());
862         new_playlist->add_region (region, _session.current_start_frame());
863         new_playlist->set_frozen (true);
864         region->set_locked (true);
865
866         diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
867         diskstream->set_record_enabled (false);
868
869         _freeze_record.state = Frozen;
870         FreezeChange(); /* EMIT SIGNAL */
871 }
872
873 void
874 AudioTrack::unfreeze ()
875 {
876         if (_freeze_record.playlist) {
877                 audio_diskstream()->use_playlist (_freeze_record.playlist);
878
879                 if (_freeze_record.have_mementos) {
880
881                         for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
882                                 (*i)->memento ();
883                         }
884
885                 } else {
886
887                         Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
888                         for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
889                                 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
890                                         if ((*ii)->id == (*i)->id()) {
891                                                 (*i)->set_state (((*ii)->state));
892                                                 break;
893                                         }
894                                 }
895                         }
896                 }
897                 
898                 _freeze_record.playlist.reset ();
899         }
900
901         _freeze_record.state = UnFrozen;
902         FreezeChange (); /* EMIT SIGNAL */
903 }
904