obey monitor=disk when recording also; remove debug output
[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 <boost/scoped_array.hpp>
21
22 #include "pbd/error.h"
23 #include "pbd/enumwriter.h"
24 #include "pbd/boost_debug.h"
25
26 #include "evoral/Curve.hpp"
27
28 #include "ardour/amp.h"
29 #include "ardour/audio_buffer.h"
30 #include "ardour/audio_diskstream.h"
31 #include "ardour/audio_track.h"
32 #include "ardour/audioplaylist.h"
33 #include "ardour/audioregion.h"
34 #include "ardour/audiosource.h"
35 #include "ardour/buffer_set.h"
36 #include "ardour/io_processor.h"
37 #include "ardour/panner.h"
38 #include "ardour/meter.h"
39 #include "ardour/playlist_factory.h"
40 #include "ardour/plugin_insert.h"
41 #include "ardour/processor.h"
42 #include "ardour/region_factory.h"
43 #include "ardour/route_group_specialized.h"
44 #include "ardour/session.h"
45 #include "ardour/utils.h"
46 #include "ardour/session_playlists.h"
47 #include "ardour/delivery.h"
48 #include "ardour/meter.h"
49 #include "i18n.h"
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54
55 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
56         : Track (sess, name, flag, mode)
57 {
58 }
59
60 AudioTrack::~AudioTrack ()
61 {
62 }
63
64 void
65 AudioTrack::use_new_diskstream ()
66 {
67         AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
68
69         if (_flags & Hidden) {
70                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
71         } else {
72                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
73         }
74
75         if (_mode == Destructive) {
76                 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
77         } else if (_mode == NonLayered){
78                 dflags = AudioDiskstream::Flag(dflags | AudioDiskstream::NonLayered);
79         }
80
81         AudioDiskstream* dsp (new AudioDiskstream (_session, name(), dflags));
82         boost::shared_ptr<AudioDiskstream> ds (dsp);
83
84         ds->do_refill_with_alloc ();
85         ds->set_block_size (_session.get_block_size ());
86
87         set_diskstream (ds);
88 }
89
90 void
91 AudioTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
92 {
93         Track::set_diskstream (ds);
94
95         _diskstream->set_track (this);
96         _diskstream->set_destructive (_mode == Destructive);
97         _diskstream->set_non_layered (_mode == NonLayered);
98
99         if (audio_diskstream()->deprecated_io_node) {
100
101                 if (!IO::connecting_legal) {
102                         IO::ConnectingLegal.connect_same_thread (*this, boost::bind (&AudioTrack::deprecated_use_diskstream_connections, this));
103                 } else {
104                         deprecated_use_diskstream_connections ();
105                 }
106         }
107
108         _diskstream->set_record_enabled (false);
109         _diskstream->monitor_input (false);
110
111         DiskstreamChanged (); /* EMIT SIGNAL */
112 }
113
114 boost::shared_ptr<AudioDiskstream>
115 AudioTrack::audio_diskstream() const
116 {
117         return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
118 }
119
120 int
121 AudioTrack::set_mode (TrackMode m)
122 {
123         if (m != _mode) {
124
125                 if (_diskstream->set_destructive (m == Destructive)) {
126                         return -1;
127                 }
128
129                 _diskstream->set_non_layered (m == NonLayered);
130                 _mode = m;
131
132                 TrackModeChanged (); /* EMIT SIGNAL */
133         }
134
135         return 0;
136 }
137
138 bool
139 AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
140 {
141         switch (m) {
142         case NonLayered:
143         case Normal:
144                 bounce_required = false;
145                 return true;
146
147         case Destructive:
148         default:
149                 return _diskstream->can_become_destructive (bounce_required);
150         }
151 }
152
153 int
154 AudioTrack::deprecated_use_diskstream_connections ()
155 {
156         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
157
158         if (diskstream->deprecated_io_node == 0) {
159                 return 0;
160         }
161
162         const XMLProperty* prop;
163         XMLNode& node (*diskstream->deprecated_io_node);
164
165         /* don't do this more than once. */
166
167         diskstream->deprecated_io_node = 0;
168
169         if ((prop = node.property ("gain")) != 0) {
170                 _amp->set_gain (atof (prop->value().c_str()), this);
171         }
172
173         if ((prop = node.property ("input-connection")) != 0) {
174                 boost::shared_ptr<Bundle> c = _session.bundle_by_name (prop->value());
175
176                 if (c == 0) {
177                         error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
178
179                         if ((c = _session.bundle_by_name (_("in 1"))) == 0) {
180                                 error << _("No input bundles available as a replacement")
181                                 << endmsg;
182                                 return -1;
183                         } else {
184                                 info << string_compose (_("Bundle %1 was not available - \"in 1\" used instead"), prop->value())
185                                << endmsg;
186                         }
187                 }
188
189                 _input->connect_ports_to_bundle (c, this);
190
191         } else if ((prop = node.property ("inputs")) != 0) {
192                 if (_input->set_ports (prop->value())) {
193                         error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg;
194                         return -1;
195                 }
196         }
197
198         return 0;
199 }
200
201 int
202 AudioTrack::set_state (const XMLNode& node, int version)
203 {
204         return _set_state (node, version, true);
205 }
206
207 int
208 AudioTrack::_set_state (const XMLNode& node, int version, bool call_base)
209 {
210         const XMLProperty *prop;
211         XMLNodeConstIterator iter;
212         XMLNode *child;
213
214         if (call_base) {
215                 if (Route::_set_state (node, version, call_base)) {
216                         return -1;
217                 }
218         }
219
220         if ((prop = node.property (X_("mode"))) != 0) {
221                 _mode = TrackMode (string_2_enum (prop->value(), _mode));
222         } else {
223                 _mode = Normal;
224         }
225
226         if (version >= 3000) {
227                 if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
228                         boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, *child));
229                         ds->do_refill_with_alloc ();
230                         set_diskstream (ds);
231                 }
232         }
233
234         /* set rec-enable control *AFTER* setting up diskstream, because it may want to operate
235            on the diskstream as it sets its own state
236         */
237
238         XMLNodeList nlist;
239         XMLNodeConstIterator niter;
240
241         nlist = node.children();
242         for (niter = nlist.begin(); niter != nlist.end(); ++niter){
243                 child = *niter;
244
245                 if (child->name() == Controllable::xml_node_name && (prop = child->property ("name")) != 0) {
246                         if (prop->value() == X_("recenable")) {
247                                 _rec_enable_control->set_state (*child, version);
248                         }
249                 }
250         }
251
252         pending_state = const_cast<XMLNode*> (&node);
253
254         if (_session.state_of_the_state() & Session::Loading) {
255                 _session.StateReady.connect_same_thread (*this, boost::bind (&AudioTrack::set_state_part_two, this));
256         } else {
257                 set_state_part_two ();
258         }
259
260         return 0;
261 }
262
263 XMLNode&
264 AudioTrack::state (bool full_state)
265 {
266         XMLNode& root (Route::state(full_state));
267         XMLNode* freeze_node;
268         char buf[64];
269
270         if (_freeze_record.playlist) {
271                 XMLNode* inode;
272
273                 freeze_node = new XMLNode (X_("freeze-info"));
274                 freeze_node->add_property ("playlist", _freeze_record.playlist->name());
275                 freeze_node->add_property ("state", enum_2_string (_freeze_record.state));
276
277                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
278                         inode = new XMLNode (X_("processor"));
279                         (*i)->id.print (buf, sizeof (buf));
280                         inode->add_property (X_("id"), buf);
281                         inode->add_child_copy ((*i)->state);
282
283                         freeze_node->add_child_nocopy (*inode);
284                 }
285
286                 root.add_child_nocopy (*freeze_node);
287         }
288
289         root.add_property (X_("mode"), enum_2_string (_mode));
290         root.add_child_nocopy (_rec_enable_control->get_state());
291         root.add_child_nocopy (_diskstream->get_state ());
292
293         return root;
294 }
295
296 void
297 AudioTrack::set_state_part_two ()
298 {
299         XMLNode* fnode;
300         XMLProperty* prop;
301         LocaleGuard lg (X_("POSIX"));
302
303         /* This is called after all session state has been restored but before
304            have been made ports and connections are established.
305         */
306
307         if (pending_state == 0) {
308                 return;
309         }
310
311         if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
312
313                 _freeze_record.state = Frozen;
314
315                 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
316                         delete *i;
317                 }
318                 _freeze_record.processor_info.clear ();
319
320                 if ((prop = fnode->property (X_("playlist"))) != 0) {
321                         boost::shared_ptr<Playlist> pl = _session.playlists->by_name (prop->value());
322                         if (pl) {
323                                 _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
324                         } else {
325                                 _freeze_record.playlist.reset ();
326                                 _freeze_record.state = NoFreeze;
327                         return;
328                         }
329                 }
330
331                 if ((prop = fnode->property (X_("state"))) != 0) {
332                         _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
333                 }
334
335                 XMLNodeConstIterator citer;
336                 XMLNodeList clist = fnode->children();
337
338                 for (citer = clist.begin(); citer != clist.end(); ++citer) {
339                         if ((*citer)->name() != X_("processor")) {
340                                 continue;
341                         }
342
343                         if ((prop = (*citer)->property (X_("id"))) == 0) {
344                                 continue;
345                         }
346
347                         FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()),
348                                                                                    boost::shared_ptr<Processor>());
349                         frii->id = prop->value ();
350                         _freeze_record.processor_info.push_back (frii);
351                 }
352         }
353 }
354
355 int
356 AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
357                   bool can_record, bool& need_butler)
358 {
359         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
360         if (!lm.locked()) {
361                 return 0;
362         }
363
364         int dret;
365         Sample* b;
366         Sample* tmpb;
367         framepos_t transport_frame;
368         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
369
370         automation_snapshot (start_frame, false);
371
372         if (n_outputs().n_total() == 0 && _processors.empty()) {
373                 return 0;
374         }
375
376         if (!_active) {
377                 silence (nframes);
378                 return 0;
379         }
380
381         transport_frame = _session.transport_frame();
382
383         if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
384
385                 /* need to do this so that the diskstream sets its
386                    playback distance to zero, thus causing diskstream::commit
387                    to do nothing.
388                 */
389                 return diskstream->process (transport_frame, 0, can_record, need_butler);
390         }
391
392         _silent = false;
393         _amp->apply_gain_automation(false);
394
395         if ((dret = diskstream->process (transport_frame, nframes, can_record, need_butler)) != 0) {
396                 silence (nframes);
397                 return dret;
398         }
399
400         /* special condition applies */
401
402         if (_meter_point == MeterInput) {
403                 _input->process_input (_meter, start_frame, end_frame, nframes);
404         }
405
406         if ((_monitoring & MonitorInput) || (!(_monitoring & MonitorDisk) && 
407                                              (diskstream->record_enabled() && 
408                                               !can_record && 
409                                               !_session.config.get_auto_input()))) {
410                 
411                 /* not actually recording, but we want to hear the input material anyway,
412                    at least potentially (depending on monitoring options)
413                  */
414
415                 passthru (start_frame, end_frame, nframes, false);
416
417         } else if ((b = diskstream->playback_buffer(0)) != 0) {
418
419                 /*
420                   XXX is it true that the earlier test on n_outputs()
421                   means that we can avoid checking it again here? i think
422                   so, because changing the i/o configuration of an IO
423                   requires holding the AudioEngine lock, which we hold
424                   while in the process() tree.
425                 */
426
427
428                 /* copy the diskstream data to all output buffers */
429
430                 size_t limit = input_streams ().n_audio();
431                 BufferSet& bufs = _session.get_scratch_buffers ();
432                 const size_t blimit = bufs.count().n_audio();
433
434                 uint32_t n;
435                 uint32_t i;
436
437                 if (limit > blimit) {
438
439                         /* example case: auditioner configured for stereo output,
440                            but loaded with an 8 channel file. there are only
441                            2 passthrough buffers, but n_process_buffers() will
442                            return 8.
443
444                            arbitrary decision: map all channels in the diskstream
445                            to the outputs available.
446                         */
447
448                         float scaling = limit/blimit;
449
450                         for (i = 0, n = 1; i < blimit; ++i, ++n) {
451
452                                 /* first time through just copy a channel into
453                                    the output buffer.
454                                 */
455
456                                 Sample* bb = bufs.get_audio (i).data();
457
458                                 for (pframes_t xx = 0; xx < nframes; ++xx) {
459                                         bb[xx] = b[xx] * scaling;
460                                 }
461
462                                 if (n < diskstream->n_channels().n_audio()) {
463                                         tmpb = diskstream->playback_buffer(n);
464                                         if (tmpb!=0) {
465                                                 b = tmpb;
466                                         }
467                                 }
468                         }
469
470                         for (;i < limit; ++i, ++n) {
471
472                                 /* for all remaining channels, sum with existing
473                                    data in the output buffers
474                                 */
475
476                                 bufs.get_audio (i%blimit).accumulate_with_gain_from (b, nframes, 0, scaling);
477
478                                 if (n < diskstream->n_channels().n_audio()) {
479                                         tmpb = diskstream->playback_buffer(n);
480                                         if (tmpb!=0) {
481                                                 b = tmpb;
482                                         }
483                                 }
484
485                         }
486
487                         limit = blimit;
488
489                 } else {
490                         for (i = 0, n = 1; i < limit; ++i, ++n) {
491                                 memcpy (bufs.get_audio (i).data(), b, sizeof (Sample) * nframes);
492                                 if (n < diskstream->n_channels().n_audio()) {
493                                         tmpb = diskstream->playback_buffer(n);
494                                         if (tmpb!=0) {
495                                                 b = tmpb;
496                                         }
497                                 }
498                         }
499
500                         /* try to leave any MIDI buffers alone */
501
502                         ChanCount chn;
503                         chn.set_audio (limit);
504                         chn.set_midi (_input->n_ports().n_midi());
505                         bufs.set_count (chn);
506                 }
507
508                 /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
509
510                 process_output_buffers (
511                         bufs, start_frame, end_frame, nframes,
512                         (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()),
513                         declick,
514                         (!diskstream->record_enabled() && _session.transport_rolling()));
515
516         } else {
517                 /* problem with the diskstream; just be quiet for a bit */
518                 silence (nframes);
519         }
520
521         return 0;
522 }
523
524 int
525 AudioTrack::export_stuff (BufferSet& buffers, framepos_t start, framecnt_t nframes, bool enable_processing)
526 {
527         boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]);
528         boost::scoped_array<Sample> mix_buffer (new Sample[nframes]);
529         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
530
531         Glib::RWLock::ReaderLock rlock (_processor_lock);
532
533         boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
534
535         assert(apl);
536         assert(buffers.count().n_audio() >= 1);
537         assert ((framecnt_t) buffers.get_audio(0).capacity() >= nframes);
538
539         if (apl->read (buffers.get_audio(0).data(), mix_buffer.get(), gain_buffer.get(), start, nframes) != nframes) {
540                 return -1;
541         }
542
543         uint32_t n=1;
544         Sample* b = buffers.get_audio(0).data();
545         BufferSet::audio_iterator bi = buffers.audio_begin();
546         ++bi;
547         for ( ; bi != buffers.audio_end(); ++bi, ++n) {
548                 if (n < diskstream->n_channels().n_audio()) {
549                         if (apl->read (bi->data(), mix_buffer.get(), gain_buffer.get(), start, nframes, n) != nframes) {
550                                 return -1;
551                         }
552                         b = bi->data();
553                 } else {
554                         /* duplicate last across remaining buffers */
555                         memcpy (bi->data(), b, sizeof (Sample) * nframes);
556                 }
557         }
558
559         // If no processing is required, there's no need to go any further.
560         if (!enable_processing) {
561                 return 0;
562         }
563
564         /* note: only run processors during export. other layers in the machinery
565            will already have checked that there are no external port processors.
566            Also, don't run deliveries that write to real output ports, and don't
567            run meters.
568         */
569
570         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
571                 boost::shared_ptr<Processor> processor = boost::dynamic_pointer_cast<Processor> (*i);
572                 boost::shared_ptr<Delivery> delivery = boost::dynamic_pointer_cast<Delivery> (*i);
573                 boost::shared_ptr<PeakMeter> meter = boost::dynamic_pointer_cast<PeakMeter> (*i);
574
575                 if (processor && (!delivery || !Delivery::role_requires_output_ports (delivery->role())) && !meter) {
576                         processor->run (buffers, start, start+nframes, nframes, true);
577                 }
578         }
579
580         return 0;
581 }
582
583 boost::shared_ptr<Region>
584 AudioTrack::bounce (InterThreadInfo& itt)
585 {
586         vector<boost::shared_ptr<Source> > srcs;
587         return _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), false, srcs, itt);
588 }
589
590 boost::shared_ptr<Region>
591 AudioTrack::bounce_range (framepos_t start, framepos_t end, InterThreadInfo& itt, bool enable_processing)
592 {
593         vector<boost::shared_ptr<Source> > srcs;
594         return _session.write_one_track (*this, start, end, false, srcs, itt, enable_processing);
595 }
596
597 void
598 AudioTrack::freeze_me (InterThreadInfo& itt)
599 {
600         vector<boost::shared_ptr<Source> > srcs;
601         string new_playlist_name;
602         boost::shared_ptr<Playlist> new_playlist;
603         string dir;
604         string region_name;
605         boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
606
607         if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
608                 return;
609         }
610
611         uint32_t n = 1;
612
613         while (n < (UINT_MAX-1)) {
614
615                 string candidate;
616
617                 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
618
619                 if (_session.playlists->by_name (candidate) == 0) {
620                         new_playlist_name = candidate;
621                         break;
622                 }
623
624                 ++n;
625
626         }
627
628         if (n == (UINT_MAX-1)) {
629           error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
630                             " to create another one"), _freeze_record.playlist->name())
631                << endmsg;
632                 return;
633         }
634
635         boost::shared_ptr<Region> res;
636
637         if ((res = _session.write_one_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
638                 return;
639         }
640
641         _freeze_record.processor_info.clear ();
642
643         {
644                 Glib::RWLock::ReaderLock lm (_processor_lock);
645
646                 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
647
648                         boost::shared_ptr<Processor> processor;
649
650                         if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
651
652                                 FreezeRecordProcessorInfo* frii  = new FreezeRecordProcessorInfo ((*r)->get_state(), processor);
653
654                                 frii->id = processor->id();
655
656                                 _freeze_record.processor_info.push_back (frii);
657
658                                 /* now deactivate the processor */
659
660                                 processor->deactivate ();
661                                 _session.set_dirty ();
662                         }
663                 }
664         }
665
666         new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false);
667
668         /* XXX need main outs automation state _freeze_record.pan_automation_state = _mainpanner->automation_state(); */
669
670         region_name = new_playlist_name;
671
672         /* create a new region from all filesources, keep it private */
673
674         PropertyList plist;
675
676         plist.add (Properties::start, 0);
677         plist.add (Properties::length, srcs[0]->length(srcs[0]->timeline_position()));
678         plist.add (Properties::name, region_name);
679         plist.add (Properties::whole_file, true);
680
681         boost::shared_ptr<Region> region (RegionFactory::create (srcs, plist, false));
682
683         new_playlist->set_orig_diskstream_id (_diskstream->id());
684         new_playlist->add_region (region, _session.current_start_frame());
685         new_playlist->set_frozen (true);
686         region->set_locked (true);
687
688         diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
689         diskstream->set_record_enabled (false);
690
691         /* reset stuff that has already been accounted for in the freeze process */
692
693         set_gain (1.0, this);
694         _amp->gain_control()->set_automation_state (Off);
695         /* XXX need to use _main_outs _panner->set_automation_state (Off); */
696
697         _freeze_record.state = Frozen;
698         FreezeChange(); /* EMIT SIGNAL */
699 }
700
701 void
702 AudioTrack::unfreeze ()
703 {
704         if (_freeze_record.playlist) {
705                 audio_diskstream()->use_playlist (_freeze_record.playlist);
706
707                 {
708                         Glib::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc
709                         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
710                                 for (vector<FreezeRecordProcessorInfo*>::iterator ii = _freeze_record.processor_info.begin(); ii != _freeze_record.processor_info.end(); ++ii) {
711                                         if ((*ii)->id == (*i)->id()) {
712                                                 (*i)->set_state (((*ii)->state), Stateful::current_state_version);
713                                                 break;
714                                         }
715                                 }
716                         }
717                 }
718
719                 _freeze_record.playlist.reset ();
720                 /* XXX need to use _main_outs _panner->set_automation_state (_freeze_record.pan_automation_state); */
721         }
722
723         _freeze_record.state = UnFrozen;
724         FreezeChange (); /* EMIT SIGNAL */
725 }
726
727 boost::shared_ptr<AudioFileSource>
728 AudioTrack::write_source (uint32_t n)
729 {
730         boost::shared_ptr<AudioDiskstream> ds = boost::dynamic_pointer_cast<AudioDiskstream> (_diskstream);
731         assert (ds);
732         return ds->write_source (n);
733 }
734
735 bool
736 AudioTrack::bounceable () const
737 {
738         return n_inputs().n_audio() >= n_outputs().n_audio();
739 }
740
741