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/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>
44 using namespace ARDOUR;
47 AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
48 : Track (sess, name, flag, mode)
50 AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
52 if (_flags & Hidden) {
53 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
55 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
58 if (mode == Destructive) {
59 dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
62 boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags));
64 _session.add_diskstream (ds);
66 set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
69 AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
72 _set_state (node, false);
75 AudioTrack::~AudioTrack ()
80 AudioTrack::set_mode (TrackMode m)
84 if (_diskstream->set_destructive (m == Destructive)) {
90 TrackModeChanged (); /* EMIT SIGNAL */
97 AudioTrack::can_use_mode (TrackMode m, bool& bounce_required)
101 bounce_required = false;
106 return _diskstream->can_become_destructive (bounce_required);
111 AudioTrack::deprecated_use_diskstream_connections ()
113 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
115 if (diskstream->deprecated_io_node == 0) {
119 const XMLProperty* prop;
120 XMLNode& node (*diskstream->deprecated_io_node);
122 /* don't do this more than once. */
124 diskstream->deprecated_io_node = 0;
126 set_input_minimum (-1);
127 set_input_maximum (-1);
128 set_output_minimum (-1);
129 set_output_maximum (-1);
131 if ((prop = node.property ("gain")) != 0) {
132 set_gain (atof (prop->value().c_str()), this);
133 _gain = _desired_gain;
136 if ((prop = node.property ("input-connection")) != 0) {
137 Connection* c = _session.connection_by_name (prop->value());
140 error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg;
142 string replacement_connection;
144 if (prop->value().find ('+') != string::npos) {
145 replacement_connection = _("in 1+2");
147 replacement_connection = _("in 1");
150 if ((c = _session.connection_by_name (replacement_connection)) == 0) {
151 error << _("No input connections available as a replacement")
155 info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), prop->value(), replacement_connection)
160 use_input_connection (*c, this);
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;
173 AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void *src)
176 _diskstream->set_io (*this);
177 _diskstream->set_destructive (_mode == Destructive);
179 if (audio_diskstream()->deprecated_io_node) {
181 if (!connecting_legal) {
182 ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
184 deprecated_use_diskstream_connections ();
188 _diskstream->set_record_enabled (false);
189 _diskstream->monitor_input (false);
191 ic_connection.disconnect();
192 ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
194 DiskstreamChanged (); /* EMIT SIGNAL */
200 AudioTrack::use_diskstream (string name)
202 boost::shared_ptr<AudioDiskstream> dstream;
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;
209 return set_diskstream (dstream, this);
213 AudioTrack::use_diskstream (const PBD::ID& id)
215 boost::shared_ptr<AudioDiskstream> dstream;
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;
222 return set_diskstream (dstream, this);
225 boost::shared_ptr<AudioDiskstream>
226 AudioTrack::audio_diskstream() const
228 return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream);
232 AudioTrack::set_state (const XMLNode& node)
234 return _set_state (node, true);
238 AudioTrack::_set_state (const XMLNode& node, bool call_base)
240 const XMLProperty *prop;
241 XMLNodeConstIterator iter;
244 if (Route::_set_state (node, call_base)) {
249 if ((prop = node.property (X_("mode"))) != 0) {
250 _mode = TrackMode (string_2_enum (prop->value(), _mode));
255 if ((prop = node.property ("diskstream-id")) == 0) {
257 /* some old sessions use the diskstream name rather than the ID */
259 if ((prop = node.property ("diskstream")) == 0) {
260 fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg;
265 if (use_diskstream (prop->value())) {
271 PBD::ID id (prop->value());
273 if (use_diskstream (id)) {
280 XMLNodeConstIterator niter;
283 nlist = node.children();
284 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
287 if (child->name() == X_("recenable")) {
288 _rec_enable_control.set_state (*child);
289 _session.add_controllable (&_rec_enable_control);
293 pending_state = const_cast<XMLNode*> (&node);
295 _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two));
301 AudioTrack::state(bool full_state)
303 XMLNode& root (Route::state(full_state));
304 XMLNode* freeze_node;
307 if (_freeze_record.playlist) {
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));
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);
320 freeze_node->add_child_nocopy (*inode);
323 root.add_child_nocopy (*freeze_node);
326 /* Alignment: act as a proxy for the diskstream */
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);
333 root.add_property (X_("mode"), enum_2_string (_mode));
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
341 _diskstream->id().print (buf, sizeof (buf));
342 root.add_property ("diskstream-id", buf);
344 root.add_child_nocopy (_rec_enable_control.get_state());
350 AudioTrack::set_state_part_two ()
354 LocaleGuard lg (X_("POSIX"));
356 /* This is called after all session state has been restored but before
357 have been made ports and connections are established.
360 if (pending_state == 0) {
364 if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) {
367 _freeze_record.have_mementos = false;
368 _freeze_record.state = Frozen;
370 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
373 _freeze_record.insert_info.clear ();
375 if ((prop = fnode->property (X_("playlist"))) != 0) {
376 boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
378 _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
380 _freeze_record.playlist.reset ();
381 _freeze_record.state = NoFreeze;
386 if ((prop = fnode->property (X_("state"))) != 0) {
387 _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state));
390 XMLNodeConstIterator citer;
391 XMLNodeList clist = fnode->children();
393 for (citer = clist.begin(); citer != clist.end(); ++citer) {
394 if ((*citer)->name() != X_("insert")) {
398 if ((prop = (*citer)->property (X_("id"))) == 0) {
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);
409 /* Alignment: act as a proxy for the diskstream */
411 if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) {
413 if ((prop = fnode->property (X_("style"))) != 0) {
415 /* fix for older sessions from before EnumWriter */
419 if (prop->value() == "capture") {
420 pstr = "CaptureTime";
421 } else if (prop->value() == "existing") {
422 pstr = "ExistingMaterial";
424 pstr = prop->value();
427 AlignStyle as = AlignStyle (string_2_enum (pstr, as));
428 _diskstream->set_persistent_align_style (as);
435 AudioTrack::n_process_buffers ()
437 return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
441 AudioTrack::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter)
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);
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)
451 if (n_outputs() == 0) {
456 silence (nframes, offset);
460 if (session_state_changing) {
462 /* XXX is this safe to do against transport state changes? */
464 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
468 audio_diskstream()->check_record_status (start_frame, nframes, can_record);
472 if (_have_internal_generator) {
473 /* since the instrument has no input streams,
474 there is no reason to send any signal
480 if (!Config->get_tape_machine_mode()) {
482 ADATs work in a strange way..
483 they monitor input always when stopped.and auto-input is engaged.
485 if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) {
486 send_silence = false;
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)
496 if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) {
497 send_silence = false;
504 apply_gain_automation = false;
508 /* if we're sending silence, but we want the meters to show levels for the signal,
512 if (_have_internal_generator) {
513 passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
515 if (_meter_point == MeterInput) {
516 just_meter_input (start_frame, end_frame, nframes, offset);
518 passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
523 /* we're sending signal, but we may still want to meter the input.
526 passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
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)
539 nframes_t transport_frame;
540 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
543 Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
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);
552 if (n_outputs() == 0 && _redirects.empty()) {
557 silence (nframes, offset);
561 transport_frame = _session.transport_frame();
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
568 return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
572 apply_gain_automation = false;
574 if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
576 silence (nframes, offset);
581 /* special condition applies */
583 if (_meter_point == MeterInput) {
584 just_meter_input (start_frame, end_frame, nframes, offset);
587 if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
589 /* not actually recording, but we want to hear the input material anyway,
590 at least potentially (depending on monitoring options)
593 passthru (start_frame, end_frame, nframes, offset, 0, true);
595 } else if ((b = diskstream->playback_buffer(0)) != 0) {
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.
606 /* copy the diskstream data to all output buffers */
608 vector<Sample*>& bufs = _session.get_passthru_buffers ();
609 uint32_t limit = n_process_buffers ();
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);
625 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
627 if (!diskstream->record_enabled() && _session.transport_rolling()) {
628 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
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);
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));
638 /* problem with the diskstream; just be quiet for a bit */
639 silence (nframes, offset);
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)
649 if (n_outputs() == 0 && _redirects.empty()) {
654 silence (nframes, offset);
659 apply_gain_automation = false;
661 silence (nframes, offset);
663 return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
667 AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t start, nframes_t nframes)
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;
677 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
679 Glib::RWLock::ReaderLock rlock (redirect_lock);
681 boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
684 if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
689 bi = buffers.begin();
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) {
700 /* duplicate last across remaining buffers */
701 memcpy ((*bi), b, sizeof (Sample) * nframes);
706 /* note: only run inserts during export. other layers in the machinery
707 will already have checked that there are no external port inserts.
710 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
711 boost::shared_ptr<Insert> insert;
713 if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
714 switch (insert->placement()) {
716 insert->run (buffers, nbufs, nframes, 0);
719 post_fader_work = true;
725 if (_gain_automation_curve.automation_state() == Play) {
727 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
729 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
731 for (nframes_t n = 0; n < nframes; ++n) {
732 b[n] *= gain_automation[n];
738 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
740 for (nframes_t n = 0; n < nframes; ++n) {
746 if (post_fader_work) {
748 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
749 boost::shared_ptr<PluginInsert> insert;
751 if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
752 switch ((*i)->placement()) {
756 insert->run (buffers, nbufs, nframes, 0);
767 AudioTrack::bounce (InterThreadInfo& itt)
769 vector<boost::shared_ptr<AudioSource> > srcs;
770 _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
775 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
777 vector<boost::shared_ptr<AudioSource> > srcs;
778 _session.write_one_audio_track (*this, start, end, false, srcs, itt);
782 AudioTrack::freeze (InterThreadInfo& itt)
784 vector<boost::shared_ptr<AudioSource> > srcs;
785 string new_playlist_name;
786 boost::shared_ptr<Playlist> new_playlist;
789 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
791 if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
797 while (n < (UINT_MAX-1)) {
801 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
803 if (_session.playlist_by_name (candidate) == 0) {
804 new_playlist_name = candidate;
812 if (n == (UINT_MAX-1)) {
813 error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
814 " to create another one"), _freeze_record.playlist->name())
819 if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) {
823 _freeze_record.insert_info.clear ();
824 _freeze_record.have_mementos = true;
827 Glib::RWLock::ReaderLock lm (redirect_lock);
829 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
831 boost::shared_ptr<Insert> insert;
833 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
835 FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
837 frii->id = insert->id();
839 _freeze_record.insert_info.push_back (frii);
841 /* now deactivate the insert */
843 insert->set_active (false, this);
848 new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
849 region_name = new_playlist_name;
851 /* create a new region from all filesources, keep it private */
853 boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
855 (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
858 new_playlist->set_orig_diskstream_id (diskstream->id());
859 new_playlist->add_region (region, _session.current_start_frame());
860 new_playlist->set_frozen (true);
861 region->set_locked (true);
863 diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
864 diskstream->set_record_enabled (false);
866 _freeze_record.state = Frozen;
867 FreezeChange(); /* EMIT SIGNAL */
871 AudioTrack::unfreeze ()
873 if (_freeze_record.playlist) {
874 audio_diskstream()->use_playlist (_freeze_record.playlist);
876 if (_freeze_record.have_mementos) {
878 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
884 Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
885 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
886 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
887 if ((*ii)->id == (*i)->id()) {
888 (*i)->set_state (((*ii)->state));
895 _freeze_record.playlist.reset ();
898 _freeze_record.state = UnFrozen;
899 FreezeChange (); /* EMIT SIGNAL */