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 vector<Sample*>::size_type blimit = bufs.size();
610 uint32_t limit = n_process_buffers ();
615 if (limit > blimit) {
617 /* example case: auditioner configured for stereo output,
618 but loaded with an 8 channel file. there are only
619 2 passthrough buffers, but n_process_buffers() will
622 arbitrary decision: map all channels in the diskstream
623 to the outputs available.
626 float scaling = limit/blimit;
628 for (i = 0, n = 1; i < blimit; ++i, ++n) {
630 /* first time through just copy a channel into
634 for (nframes_t xx = 0; xx < nframes; ++xx) {
635 bufs[i][xx] = b[xx] * scaling;
638 if (n < diskstream->n_channels()) {
639 tmpb = diskstream->playback_buffer(n);
646 for (;i < limit; ++i, ++n) {
648 /* for all remaining channels, sum with existing
649 data in the output buffers
652 _session.mix_buffers_with_gain (bufs[i%blimit], b, nframes, scaling);
654 if (n < diskstream->n_channels()) {
655 tmpb = diskstream->playback_buffer(n);
665 for (i = 0, n = 1; i < limit; ++i, ++n) {
666 memcpy (bufs[i], b, sizeof (Sample) * nframes);
667 if (n < diskstream->n_channels()) {
668 tmpb = diskstream->playback_buffer(n);
676 /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
678 if (!diskstream->record_enabled() && _session.transport_rolling()) {
679 Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
681 if (am.locked() && gain_automation_playback()) {
682 apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
686 process_output_buffers (bufs, blimit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
689 /* problem with the diskstream; just be quiet for a bit */
690 silence (nframes, offset);
697 AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
698 bool can_record, bool rec_monitors_input)
700 if (n_outputs() == 0 && _redirects.empty()) {
705 silence (nframes, offset);
710 apply_gain_automation = false;
712 silence (nframes, offset);
714 return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
718 AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t start, nframes_t nframes)
720 gain_t gain_automation[nframes];
721 gain_t gain_buffer[nframes];
722 float mix_buffer[nframes];
723 RedirectList::iterator i;
724 bool post_fader_work = false;
725 gain_t this_gain = _gain;
726 vector<Sample*>::iterator bi;
728 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
730 Glib::RWLock::ReaderLock rlock (redirect_lock);
732 boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
735 if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
740 bi = buffers.begin();
743 for (; bi != buffers.end(); ++bi, ++n) {
744 if (n < diskstream->n_channels()) {
745 if (apl->read ((*bi), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
751 /* duplicate last across remaining buffers */
752 memcpy ((*bi), b, sizeof (Sample) * nframes);
757 /* note: only run inserts during export. other layers in the machinery
758 will already have checked that there are no external port inserts.
761 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
762 boost::shared_ptr<Insert> insert;
764 if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
765 switch (insert->placement()) {
767 insert->run (buffers, nbufs, nframes, 0);
770 post_fader_work = true;
776 if (_gain_automation_curve.automation_state() == Play) {
778 _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes);
780 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
782 for (nframes_t n = 0; n < nframes; ++n) {
783 b[n] *= gain_automation[n];
789 for (bi = buffers.begin(); bi != buffers.end(); ++bi) {
791 for (nframes_t n = 0; n < nframes; ++n) {
797 if (post_fader_work) {
799 for (i = _redirects.begin(); i != _redirects.end(); ++i) {
800 boost::shared_ptr<PluginInsert> insert;
802 if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
803 switch ((*i)->placement()) {
807 insert->run (buffers, nbufs, nframes, 0);
817 boost::shared_ptr<Region>
818 AudioTrack::bounce (InterThreadInfo& itt)
820 vector<boost::shared_ptr<AudioSource> > srcs;
821 return _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(),
826 boost::shared_ptr<Region>
827 AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt)
829 vector<boost::shared_ptr<AudioSource> > srcs;
830 return _session.write_one_audio_track (*this, start, end, false, srcs, itt);
834 AudioTrack::freeze (InterThreadInfo& itt)
836 vector<boost::shared_ptr<AudioSource> > srcs;
837 string new_playlist_name;
838 boost::shared_ptr<Playlist> new_playlist;
841 boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
843 if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
849 while (n < (UINT_MAX-1)) {
853 candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n);
855 if (_session.playlist_by_name (candidate) == 0) {
856 new_playlist_name = candidate;
864 if (n == (UINT_MAX-1)) {
865 error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
866 " to create another one"), _freeze_record.playlist->name())
871 boost::shared_ptr<Region> res;
873 if ((res = _session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) == 0) {
877 _freeze_record.insert_info.clear ();
878 _freeze_record.have_mementos = true;
881 Glib::RWLock::ReaderLock lm (redirect_lock);
883 for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
885 boost::shared_ptr<Insert> insert;
887 if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
889 FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
891 frii->id = insert->id();
893 _freeze_record.insert_info.push_back (frii);
895 /* now deactivate the insert */
897 insert->set_active (false, this);
902 _freeze_record.gain = _gain;
903 _freeze_record.gain_automation_state = _gain_automation_curve.automation_state();
904 _freeze_record.pan_automation_state = _panner->automation_state();
906 new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
907 region_name = new_playlist_name;
909 /* create a new region from all filesources, keep it private */
911 boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
913 (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
916 new_playlist->set_orig_diskstream_id (diskstream->id());
917 new_playlist->add_region (region, _session.current_start_frame());
918 new_playlist->set_frozen (true);
919 region->set_locked (true);
921 diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
922 diskstream->set_record_enabled (false);
924 /* reset stuff that has already been accounted for in the freeze process */
926 set_gain (1.0, this);
927 _gain_automation_curve.set_automation_state (Off);
928 _panner->set_automation_state (Off);
930 _freeze_record.state = Frozen;
931 FreezeChange(); /* EMIT SIGNAL */
935 AudioTrack::unfreeze ()
937 if (_freeze_record.playlist) {
938 audio_diskstream()->use_playlist (_freeze_record.playlist);
940 if (_freeze_record.have_mementos) {
942 for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
948 Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
949 for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
950 for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
951 if ((*ii)->id == (*i)->id()) {
952 (*i)->set_state (((*ii)->state));
959 _freeze_record.playlist.reset ();
960 set_gain (_freeze_record.gain, this);
961 _gain_automation_curve.set_automation_state (_freeze_record.gain_automation_state);
962 _panner->set_automation_state (_freeze_record.pan_automation_state);
965 _freeze_record.state = UnFrozen;
966 FreezeChange (); /* EMIT SIGNAL */