2 Copyright (C) 2002 Paul Davis
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.
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.
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.
20 #include <sigc++/retype.h>
21 #include <sigc++/retype_return.h>
22 #include <sigc++/bind.h>
24 #include <pbd/error.h>
25 #include <pbd/enumwriter.h>
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>
45 using namespace ARDOUR;
48 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
49 : Track (sess, name, flag, mode)
51 AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
53 if (_flags & Hidden) {
54 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
56 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
59 if (mode == Destructive) {
60 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
63 boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
65 _session.add_diskstream (ds);
67 set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
70 AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
73 _set_state (node, false);
76 AudioTrack::~AudioTrack ()
81 AudioTrack::set_mode (TrackMode m)
85 if (_diskstream->set_destructive (m == Destructive)) {
91 TrackModeChanged (); /* EMIT SIGNAL */
98 AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
102 bounce_required = false;
107 return _diskstream->can_become_destructive (bounce_required);
112 AudioTrack::deprecated_use_diskstream_connections ()
114 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
116 if (diskstream->deprecated_io_node == 0) {
120 const XMLProperty* prop;
121 XMLNode& node (*diskstream->deprecated_io_node);
123 /* don't do this more than once. */
125 diskstream->deprecated_io_node = 0;
127 set_input_minimum (ChanCount::ZERO);
128 set_input_maximum (ChanCount::INFINITE);
129 set_output_minimum (ChanCount::ZERO);
130 set_output_maximum (ChanCount::INFINITE);
132 if ((prop = node.property ("gain")) != 0) {
133 set_gain (atof (prop->value().c_str()), this);
134 _gain = _desired_gain;
137 if ((prop = node.property ("input-connection")) != 0) {
138 Bundle* c = _session.bundle_by_name (prop->value());
141 error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
143 if ((c = _session.bundle_by_name (_("in 1"))) == 0) {
144 error << _("No input bundles available as a replacement")
148 info << string_compose (_("Bundle %1 was not available - \"in 1\" used instead"), prop->value())
153 use_input_bundle(*c, this);
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;
166 AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void *src)
169 _diskstream->set_io (*this);
170 _diskstream->set_destructive (_mode == Destructive);
172 if (audio_diskstream()->deprecated_io_node) {
174 if (!connecting_legal) {
175 ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
177 deprecated_use_diskstream_connections ();
181 _diskstream->set_record_enabled (false);
182 _diskstream->monitor_input (false);
184 ic_connection.disconnect();
185 ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
187 DiskstreamChanged (); /* EMIT SIGNAL */
193 AudioTrack::use_diskstream (string name)
195 boost::shared_ptr<AudioDiskstream> dstream;
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;
202 return set_diskstream (dstream, this);
206 AudioTrack::use_diskstream (const PBD::ID& id)
208 boost::shared_ptr<AudioDiskstream> dstream;
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;
215 return set_diskstream (dstream, this);
218 boost::shared_ptr<AudioDiskstream>
219 AudioTrack::audio_diskstream() const
221 return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
225 AudioTrack::set_state (const XMLNode& node)
227 return _set_state (node, true);
231 AudioTrack::_set_state (const XMLNode& node, bool call_base)
233 const XMLProperty *prop;
234 XMLNodeConstIterator iter;
237 if (Route::_set_state (node, call_base)) {
242 if ((prop = node.property (X_("mode"))) != 0) {
243 _mode = TrackMode (string_2_enum (prop->value(), _mode));
248 if ((prop = node.property ("diskstream-id")) == 0) {
250 /* some old sessions use the diskstream name rather than the ID */
252 if ((prop = node.property ("diskstream")) == 0) {
253 fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg;
258 if (use_diskstream (prop->value())) {
264 PBD::ID id (prop->value());
266 if (use_diskstream (id)) {
273 XMLNodeConstIterator niter;
276 nlist = node.children();
277 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
280 if (child->name() == X_("recenable")) {
281 _rec_enable_control->set_state (*child);
282 _session.add_controllable (_rec_enable_control);
286 pending_state = const_cast<XMLNode*> (&node);
288 _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
294 AudioTrack::state(bool full_state)
296 XMLNode& root (Route::state(full_state));
297 XMLNode* freeze_node;
300 if (_freeze_record.playlist) {
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));
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);
313 freeze_node->add_child_nocopy (*inode);
316 root.add_child_nocopy (*freeze_node);
319 /* Alignment: act as a proxy for the diskstream */
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);
326 root.add_property (X_("mode"), enum_2_string (_mode));
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
334 _diskstream->id().print (buf, sizeof (buf));
335 root.add_property ("diskstream-id", buf);
337 root.add_child_nocopy (_rec_enable_control->get_state());
343 AudioTrack::set_state_part_two ()
347 LocaleGuard lg (X_("POSIX"));
349 /* This is called after all session state has been restored but before
350 have been made ports and connections are established.
353 if (pending_state == 0) {
357 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
360 _freeze_record.have_mementos = false;
361 _freeze_record.state = Frozen;
363 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
366 _freeze_record.processor_info.clear ();
368 if ((prop = fnode->property (X_("playlist"))) != 0) {
369 boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
371 _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
373 _freeze_record.playlist.reset ();
374 _freeze_record.state = NoFreeze;
379 if ((prop = fnode->property (X_("state"))) != 0) {
380 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
383 XMLNodeConstIterator citer;
384 XMLNodeList clist = fnode->children();
386 for (citer = clist.begin(); citer != clist.end(); ++citer) {
387 if ((*citer)->name() != X_("processor")) {
391 if ((prop = (*citer)->property (X_("id"))) == 0) {
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);
402 /* Alignment: act as a proxy for the diskstream */
404 if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
406 if ((prop = fnode->property (X_("style"))) != 0) {
408 /* fix for older sessions from before EnumWriter */
412 if (prop->value() == "capture") {
413 pstr = "CaptureTime";
414 } else if (prop->value() == "existing") {
415 pstr = "ExistingMaterial";
417 pstr = prop->value();
420 AlignStyle as = AlignStyle (string_2_enum (pstr, as));
421 _diskstream->set_persistent_align_style (as);
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)
431 if (n_outputs().n_total() == 0) {
436 silence (nframes, offset);
440 if (session_state_changing) {
442 /* XXX is this safe to do against transport state changes? */
444 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
448 audio_diskstream()->check_record_status (start_frame, nframes, can_record);
452 if (_have_internal_generator) {
453 /* since the instrument has no input streams,
454 there is no reason to send any signal
460 if (Config->get_auto_input()) {
461 if (Config->get_monitoring_model() == SoftwareMonitoring) {
462 send_silence = false;
467 if (_diskstream->record_enabled()) {
468 if (Config->get_monitoring_model() == SoftwareMonitoring) {
469 send_silence = false;
479 apply_gain_automation = false;
483 /* if we're sending silence, but we want the meters to show levels for the signal,
487 if (_have_internal_generator) {
488 passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
490 if (_meter_point == MeterInput) {
491 just_meter_input (start_frame, end_frame, nframes, offset);
493 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
498 /* we're sending signal, but we may still want to meter the input.
501 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
508 AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
509 bool can_record, bool rec_monitors_input)
514 nframes_t transport_frame;
515 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
518 Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
520 // automation snapshot can also be called from the non-rt context
521 // and it uses the redirect list, so we take the lock out here
522 automation_snapshot (start_frame);
527 if (n_outputs().n_total() == 0 && _processors.empty()) {
532 silence (nframes, offset);
536 transport_frame = _session.transport_frame();
538 if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
539 /* need to do this so that the diskstream sets its
540 playback distance to zero, thus causing diskstream::commit
543 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
547 apply_gain_automation = false;
549 if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
551 silence (nframes, offset);
556 /* special condition applies */
558 if (_meter_point == MeterInput) {
559 just_meter_input (start_frame, end_frame, nframes, offset);
562 if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
564 /* not actually recording, but we want to hear the input material anyway,
565 at least potentially (depending on monitoring options)
568 passthru (start_frame, end_frame, nframes, offset, 0, true);
570 } else if ((b = diskstream->playback_buffer(0)) != 0) {
573 XXX is it true that the earlier test on n_outputs()
574 means that we can avoid checking it again here? i think
575 so, because changing the i/o configuration of an IO
576 requires holding the AudioEngine lock, which we hold
577 while in the process() tree.
581 /* copy the diskstream data to all output buffers */
583 const size_t limit = n_process_buffers().n_audio();
584 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
589 for (i = 0, n = 1; i < limit; ++i, ++n) {
590 memcpy (bufs.get_audio(i).data(), b, sizeof (Sample) * nframes);
591 if (n < diskstream->n_channels().n_audio()) {
592 tmpb = diskstream->playback_buffer(n);
599 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
601 if (!diskstream->record_enabled() && _session.transport_rolling()) {
602 Glib::Mutex::Lock am (_automation_lock, Glib::TRY_LOCK);
604 if (am.locked() && gain_control()->list()->automation_playback()) {
605 apply_gain_automation = gain_control()->list()->curve().rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
609 process_output_buffers (bufs, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
612 /* problem with the diskstream; just be quiet for a bit */
613 silence (nframes, offset);
620 AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
621 bool can_record, bool rec_monitors_input)
623 if (n_outputs().n_total() == 0 && _processors.empty()) {
628 silence (nframes, offset);
633 apply_gain_automation = false;
635 silence (nframes, offset);
637 return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
641 AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes)
643 gain_t gain_automation[nframes];
644 gain_t gain_buffer[nframes];
645 float mix_buffer[nframes];
646 ProcessorList::iterator i;
647 bool post_fader_work = false;
648 gain_t this_gain = _gain;
649 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
651 Glib::RWLock::ReaderLock rlock (_processor_lock);
653 boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
656 if (apl->read (buffers.get_audio(nframes).data(),
657 mix_buffer, gain_buffer, start, nframes) != nframes) {
661 assert(buffers.count().n_audio() >= 1);
663 Sample* b = buffers.get_audio(0).data();
664 BufferSet::audio_iterator bi = buffers.audio_begin();
666 for ( ; bi != buffers.audio_end(); ++bi, ++n) {
667 if (n < diskstream->n_channels().n_audio()) {
668 if (apl->read (bi->data(), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
674 /* duplicate last across remaining buffers */
675 memcpy (bi->data(), b, sizeof (Sample) * nframes);
680 /* note: only run processors during export. other layers in the machinery
681 will already have checked that there are no external port processors.
684 for (i = _processors.begin(); i != _processors.end(); ++i) {
685 boost::shared_ptr<Processor> processor;
687 if ((processor = boost::dynamic_pointer_cast<Processor>(*i)) != 0) {
688 switch (processor->placement()) {
690 processor->run_in_place (buffers, start, start+nframes, nframes, 0);
693 post_fader_work = true;
699 if (gain_control()->list()->automation_state() == Play) {
701 gain_control()->list()->curve().get_vector (start, start + nframes, gain_automation, nframes);
703 for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
704 Sample *b = bi->data();
705 for (nframes_t n = 0; n < nframes; ++n) {
706 b[n] *= gain_automation[n];
712 for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) {
713 Sample *b = bi->data();
714 for (nframes_t n = 0; n < nframes; ++n) {
720 if (post_fader_work) {
722 for (i = _processors.begin(); i != _processors.end(); ++i) {
723 boost::shared_ptr<PluginInsert> processor;
725 if ((processor = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
726 switch ((*i)->placement()) {
730 processor->run_in_place (buffers, start, start+nframes, nframes, 0);
741 AudioTrack::bounce (InterThreadInfo& itt)
743 vector<boost::shared_ptr<Source> > srcs;
744 _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
750 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
752 vector<boost::shared_ptr<Source> > srcs;
753 _session.write_one_audio_track (*this, start, end, false, srcs, itt);
758 AudioTrack::freeze (InterThreadInfo& itt)
760 vector<boost::shared_ptr<Source> > srcs;
761 string new_playlist_name;
762 boost::shared_ptr<Playlist> new_playlist;
765 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
767 if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
773 while (n < (UINT_MAX-1)) {
777 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
779 if (_session.playlist_by_name (candidate) == 0) {
780 new_playlist_name = candidate;
788 if (n == (UINT_MAX-1)) {
789 error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
790 " to create another one"), _freeze_record.playlist->name())
795 if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) {
799 _freeze_record.processor_info.clear ();
800 _freeze_record.have_mementos = true;
803 Glib::RWLock::ReaderLock lm (_processor_lock);
805 for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
807 boost::shared_ptr<Processor> processor;
809 if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) {
811 FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo ((*r)->get_state(), processor);
813 frii->id = processor->id();
815 _freeze_record.processor_info.push_back (frii);
817 /* now deactivate the processor */
819 processor->set_active (false);
820 _session.set_dirty ();
825 new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false);
826 region_name = new_playlist_name;
828 /* create a new region from all filesources, keep it private */
830 boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
832 (Region::Flag) (Region::WholeFile|Region::DefaultFlags),
835 new_playlist->set_orig_diskstream_id (diskstream->id());
836 new_playlist->add_region (region, _session.current_start_frame());
837 new_playlist->set_frozen (true);
838 region->set_locked (true);
840 diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
841 diskstream->set_record_enabled (false);
843 _freeze_record.state = Frozen;
844 FreezeChange(); /* EMIT SIGNAL */
848 AudioTrack::unfreeze ()
850 if (_freeze_record.playlist) {
851 audio_diskstream()->use_playlist (_freeze_record.playlist);
853 if (_freeze_record.have_mementos) {
855 for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) {
861 Glib::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc
862 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
863 for (vector<FreezeRecordProcessorInfo*>::iterator ii = _freeze_record.processor_info.begin(); ii != _freeze_record.processor_info.end(); ++ii) {
864 if ((*ii)->id == (*i)->id()) {
865 (*i)->set_state (((*ii)->state));
872 _freeze_record.playlist.reset ();
875 _freeze_record.state = UnFrozen;
876 FreezeChange (); /* EMIT SIGNAL */