Apply MIDI looping patch from torbenh, with minor changes.
[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         prepare_inputs( nframes, offset );
544
545         if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
546                 /* need to do this so that the diskstream sets its
547                    playback distance to zero, thus causing diskstream::commit
548                    to do nothing.
549                 */
550                 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
551         } 
552
553         _silent = false;
554         apply_gain_automation = false;
555
556         if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
557                 
558                 silence (nframes, offset);
559
560                 return dret;
561         }
562
563         /* special condition applies */
564         
565         if (_meter_point == MeterInput) {
566                 just_meter_input (start_frame, end_frame, nframes, offset);
567         }
568
569         if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
570
571                 /* not actually recording, but we want to hear the input material anyway,
572                    at least potentially (depending on monitoring options)
573                  */
574
575                 passthru (start_frame, end_frame, nframes, offset, 0, true);
576
577         } else if ((b = diskstream->playback_buffer(0)) != 0) {
578
579                 /*
580                   XXX is it true that the earlier test on n_outputs()
581                   means that we can avoid checking it again here? i think
582                   so, because changing the i/o configuration of an IO
583                   requires holding the AudioEngine lock, which we hold
584                   while in the process() tree.
585                 */
586
587                 
588                 /* copy the diskstream data to all output buffers */
589                 
590                 const size_t limit = n_process_buffers().n_audio();
591                 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
592                 
593                 uint32_t n;
594                 uint32_t i;
595
596                 for (i = 0, n = 1; i < limit; ++i, ++n) {
597                         memcpy (bufs.get_audio(i).data(), b, sizeof (Sample) * nframes); 
598                         if (n < diskstream->n_channels().n_audio()) {
599                                 tmpb = diskstream->playback_buffer(n);
600                                 if (tmpb!=0) {
601                                         b = tmpb;
602                                 }
603                         }
604                 }
605
606                 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
607
608                 if (!diskstream->record_enabled() && _session.transport_rolling()) {
609                         Glib::Mutex::Lock am (data().control_lock(), Glib::TRY_LOCK);
610                         
611                         if (am.locked() && gain_control()->automation_playback()) {
612                                 apply_gain_automation = gain_control()->list()->curve().rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
613                         }
614                 }
615
616                 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
617                 
618         } else {
619                 /* problem with the diskstream; just be quiet for a bit */
620                 silence (nframes, offset);
621         }
622
623         return 0;
624 }
625
626 int
627 AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, 
628                          bool can_record, bool rec_monitors_input)
629 {
630         if (n_outputs().n_total() == 0 && _processors.empty()) {
631                 return 0;
632         }
633
634         if (!_active) {
635                 silence (nframes, offset);
636                 return 0;
637         }
638
639         _silent = true;
640         apply_gain_automation = false;
641
642         silence (nframes, offset);
643
644         return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
645 }
646
647 int
648 AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes)
649 {
650         gain_t  gain_automation[nframes];
651         gain_t  gain_buffer[nframes];
652         float   mix_buffer[nframes];
653         ProcessorList::iterator i;
654         bool post_fader_work = false;
655         gain_t this_gain = _gain;
656         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
657         
658         Glib::RWLock::ReaderLock rlock (_processor_lock);
659
660         boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
661         assert(apl);
662
663         assert(buffers.get_audio(0).capacity() >= nframes);
664
665         if (apl->read (buffers.get_audio(0).data(), mix_buffer, gain_buffer, start, nframes) != nframes) {
666                 return -1;
667         }
668
669         assert(buffers.count().n_audio() >= 1);
670         uint32_t n=1;
671         Sample* b = buffers.get_audio(0).data();
672         BufferSet::audio_iterator bi = buffers.audio_begin();
673         ++bi;
674         for ( ; bi != buffers.audio_end(); ++bi, ++n) {
675                 if (n < diskstream->n_channels().n_audio()) {
676                         if (apl->read (bi->data(), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
677                                 return -1;
678                         }
679                         b = bi->data();
680                 }
681                 else {
682                         /* duplicate last across remaining buffers */
683                         memcpy (bi->data(), b, sizeof (Sample) * nframes); 
684                 }
685         }
686
687
688         /* note: only run processors during export. other layers in the machinery
689            will already have checked that there are no external port processors.
690         */
691         
692         for (i = _processors.begin(); i != _processors.end(); ++i) {
693                 boost::shared_ptr<Processor> processor;
694                 
695                 if ((processor = boost::dynamic_pointer_cast<Processor>(*i)) != 0) {
696                         switch (processor->placement()) {
697                         case PreFader:
698                                 processor->run_in_place (buffers, start, start+nframes, nframes, 0);
699                                 break;
700                         case PostFader:
701                                 post_fader_work = true;
702                                 break;
703                         }
704                 }
705         }
706         
707         if (gain_control()->automation_state() == Play) {
708                 
709                 gain_control()->list()->curve().get_vector (start, start + nframes, gain_automation, nframes);
710
711                 for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
712                         Sample *b = bi->data();
713                         for (nframes_t n = 0; n < nframes; ++n) {
714                                 b[n] *= gain_automation[n];
715                         }
716                 }
717
718         } else {
719
720                 for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
721                         Sample *b = bi->data();
722                         for (nframes_t n = 0; n < nframes; ++n) {
723                                 b[n] *= this_gain;
724                         }
725                 }
726         }
727
728         if (post_fader_work) {
729
730                 for (i = _processors.begin(); i != _processors.end(); ++i) {
731                         boost::shared_ptr<PluginInsert> processor;
732                         
733                         if ((processor = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
734                                 switch ((*i)->placement()) {
735                                 case PreFader:
736                                         break;
737                                 case PostFader:
738                                         processor->run_in_place (buffers, start, start+nframes, nframes, 0);
739                                         break;
740                                 }
741                         }
742                 }
743         } 
744
745         return 0;
746 }
747
748 boost::shared_ptr<Region>
749 AudioTrack::bounce (InterThreadInfo& itt)
750 {
751         vector<boost::shared_ptr<Source> > srcs;
752         return _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), false, srcs, itt);
753 }
754
755 boost::shared_ptr<Region>
756 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
757 {
758         vector<boost::shared_ptr<Source> > srcs;
759         return _session.write_one_track (*this, start, end, false, srcs, itt);
760 }
761
762 void
763 AudioTrack::freeze (InterThreadInfo& itt)
764 {
765         vector<boost::shared_ptr<Source> > srcs;
766         string new_playlist_name;
767         boost::shared_ptr<Playlist> new_playlist;
768         string dir;
769         string region_name;
770         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
771         
772         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
773                 return;
774         }
775
776         uint32_t n = 1;
777
778         while (n < (UINT_MAX-1)) {
779          
780                 string candidate;
781                 
782                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
783
784                 if (_session.playlist_by_name (candidate) == 0) {
785                         new_playlist_name = candidate;
786                         break;
787                 }
788
789                 ++n;
790
791         } 
792
793         if (n == (UINT_MAX-1)) {
794           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
795                             " to create another one"), _freeze_record.playlist->name())
796                << endmsg;
797                 return;
798         }
799
800         boost::shared_ptr<Region> res;
801
802         if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
803                 return;
804         }
805
806         _freeze_record.processor_info.clear ();
807         _freeze_record.have_mementos = true;
808
809         {
810                 Glib::RWLock::ReaderLock lm (_processor_lock);
811                 
812                 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
813                         
814                         boost::shared_ptr<Processor> processor;
815
816                         if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
817                                 
818                                 FreezeRecordProcessorInfo* frii  = new FreezeRecordProcessorInfo ((*r)->get_state(), processor);
819                                 
820                                 frii->id = processor->id();
821
822                                 _freeze_record.processor_info.push_back (frii);
823                                 
824                                 /* now deactivate the processor */
825                                 
826                                 processor->set_active (false);
827                                 _session.set_dirty ();
828                         }
829                 }
830         }
831
832         new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false);
833         region_name = new_playlist_name;
834
835         /* create a new region from all filesources, keep it private */
836
837         boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), 
838                                                                  region_name, 0, 
839                                                                  (Region::Flag) (Region::WholeFile|Region::DefaultFlags),
840                                                                  false));
841
842         new_playlist->set_orig_diskstream_id (diskstream->id());
843         new_playlist->add_region (region, _session.current_start_frame());
844         new_playlist->set_frozen (true);
845         region->set_locked (true);
846
847         diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
848         diskstream->set_record_enabled (false);
849
850         _freeze_record.state = Frozen;
851         FreezeChange(); /* EMIT SIGNAL */
852 }
853
854 void
855 AudioTrack::unfreeze ()
856 {
857         if (_freeze_record.playlist) {
858                 audio_diskstream()->use_playlist (_freeze_record.playlist);
859
860                 if (_freeze_record.have_mementos) {
861
862                         for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
863                                 (*i)->memento ();
864                         }
865
866                 } else {
867
868                         Glib::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc
869                         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
870                                 for (vector<FreezeRecordProcessorInfo*>::iterator ii = _freeze_record.processor_info.begin(); ii != _freeze_record.processor_info.end(); ++ii) {
871                                         if ((*ii)->id == (*i)->id()) {
872                                                 (*i)->set_state (((*ii)->state));
873                                                 break;
874                                         }
875                                 }
876                         }
877                 }
878                 
879                 _freeze_record.playlist.reset ();
880         }
881
882         _freeze_record.state = UnFrozen;
883         FreezeChange (); /* EMIT SIGNAL */
884 }
885