2 * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
3 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2007-2019 Paul Davis <paul@linuxaudiosystems.com>
5 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
6 * Copyright (C) 2014-2018 Ben Loftis <ben@harrisonconsoles.com>
7 * Copyright (C) 2016 Julien "_FrnchFrgg_" RIVAUD <frnchfrgg@free.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "pbd/error.h"
25 #include "ardour/amp.h"
26 #include "ardour/audioengine.h"
27 #include "ardour/audiofilesource.h"
28 #include "ardour/audioplaylist.h"
29 #include "ardour/audioregion.h"
30 #include "ardour/debug.h"
31 #include "ardour/delivery.h"
32 #include "ardour/disk_reader.h"
33 #include "ardour/disk_writer.h"
34 #include "ardour/event_type_map.h"
35 #include "ardour/io_processor.h"
36 #include "ardour/meter.h"
37 #include "ardour/midi_playlist.h"
38 #include "ardour/midi_region.h"
39 #include "ardour/monitor_control.h"
40 #include "ardour/playlist.h"
41 #include "ardour/playlist_factory.h"
42 #include "ardour/port.h"
43 #include "ardour/processor.h"
44 #include "ardour/profile.h"
45 #include "ardour/region_factory.h"
46 #include "ardour/record_enable_control.h"
47 #include "ardour/record_safe_control.h"
48 #include "ardour/route_group_specialized.h"
49 #include "ardour/session.h"
50 #include "ardour/session_playlists.h"
51 #include "ardour/smf_source.h"
52 #include "ardour/track.h"
53 #include "ardour/types_convert.h"
54 #include "ardour/utils.h"
59 using namespace ARDOUR;
62 Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
63 : Route (sess, name, flag, default_type)
64 , _saved_meter_point (_meter_point)
66 , _alignment_choice (Automatic)
68 _freeze_record.state = NoFreeze;
73 DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
76 _disk_reader->set_route (boost::shared_ptr<Route>());
77 _disk_reader.reset ();
81 _disk_writer->set_route (boost::shared_ptr<Route>());
82 _disk_writer.reset ();
93 DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
95 if (_mode == Destructive && !Profile->get_trx()) {
96 dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
99 _disk_reader.reset (new DiskReader (_session, name(), dflags));
100 _disk_reader->set_block_size (_session.get_block_size ());
101 _disk_reader->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
102 _disk_reader->set_owner (this);
104 _disk_writer.reset (new DiskWriter (_session, name(), dflags));
105 _disk_writer->set_block_size (_session.get_block_size ());
106 _disk_writer->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
107 _disk_writer->set_owner (this);
109 set_align_choice_from_io ();
111 if (!name().empty()) {
112 /* an empty name means that we are being constructed via
113 serialized state (XML). Don't create a playlist, because one
114 will be created or discovered during ::set_state().
116 use_new_playlist (data_type());
119 boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
120 boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
122 _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
123 add_control (_record_enable_control);
125 _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
126 add_control (_record_safe_control);
128 _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
129 add_control (_monitoring_control);
131 _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
133 _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
134 _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
135 _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
137 _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this));
143 Track::input_changed ()
145 if (_disk_writer && _alignment_choice == Automatic) {
146 set_align_choice_from_io ();
151 Track::state (bool save_template)
153 XMLNode& root (Route::state (save_template));
155 if (_playlists[DataType::AUDIO]) {
156 root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
159 if (_playlists[DataType::MIDI]) {
160 root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
163 root.add_child_nocopy (_monitoring_control->get_state ());
164 root.add_child_nocopy (_record_safe_control->get_state ());
165 root.add_child_nocopy (_record_enable_control->get_state ());
167 root.set_property (X_("saved-meter-point"), _saved_meter_point);
168 root.set_property (X_("alignment-choice"), _alignment_choice);
174 Track::set_state (const XMLNode& node, int version)
176 if (Route::set_state (node, version)) {
180 if (version >= 3000 && version < 6000) {
181 if (XMLNode* ds_node = find_named_node (node, "Diskstream")) {
183 if (ds_node->get_property ("playlist", name)) {
185 ds_node->set_property ("active", true);
187 _disk_writer->set_state (*ds_node, version);
188 _disk_reader->set_state (*ds_node, version);
191 if (ds_node->get_property (X_("capture-alignment"), ac)) {
192 set_align_choice (ac, true);
195 if (boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists()->by_name (name))) {
196 use_playlist (DataType::AUDIO, pl);
199 if (boost::shared_ptr<MidiPlaylist> pl = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists()->by_name (name))) {
200 use_playlist (DataType::MIDI, pl);
207 std::string playlist_id;
209 if (node.get_property (X_("audio-playlist"), playlist_id)) {
210 find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
213 if (node.get_property (X_("midi-playlist"), playlist_id)) {
214 find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
217 XMLNodeList nlist = node.children();
218 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
221 if (child->name() == Controllable::xml_node_name) {
223 if (!child->get_property ("name", name)) {
227 if (name == _record_enable_control->name()) {
228 _record_enable_control->set_state (*child, version);
229 } else if (name == _record_safe_control->name()) {
230 _record_safe_control->set_state (*child, version);
231 } else if (name == _monitoring_control->name()) {
232 _monitoring_control->set_state (*child, version);
237 if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
238 _saved_meter_point = _meter_point;
244 if (node.get_property (X_("alignment-choice"), ac)) {
245 set_align_choice (ac, true);
251 Track::FreezeRecord::~FreezeRecord ()
253 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
259 Track::freeze_state() const
261 return _freeze_record.state;
265 Track::declick_in_progress () const
267 return _disk_reader->declick_in_progress ();
273 bool will_record = true;
274 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
283 Track::prep_record_enabled (bool yn)
285 if (yn && _record_safe_control->get_value()) {
289 if (!can_be_record_enabled()) {
293 /* keep track of the meter point as it was before we rec-enabled */
294 if (!_disk_writer->record_enabled()) {
295 _saved_meter_point = _meter_point;
301 will_follow = _disk_writer->prep_record_enable ();
303 will_follow = _disk_writer->prep_record_disable ();
308 if (_meter_point != MeterCustom) {
309 set_meter_point (MeterInput);
312 set_meter_point (_saved_meter_point);
320 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
322 _disk_writer->set_record_enabled (_record_enable_control->get_value());
326 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
328 _disk_writer->set_record_safe (_record_safe_control->get_value());
332 Track::can_be_record_safe ()
334 return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
338 Track::can_be_record_enabled ()
340 return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
344 Track::parameter_changed (string const & p)
346 if (p == "track-name-number") {
347 resync_track_name ();
349 else if (p == "track-name-take") {
350 resync_track_name ();
352 else if (p == "take-name") {
353 if (_session.config.get_track_name_take()) {
354 resync_track_name ();
360 Track::resync_track_name ()
366 Track::set_name (const string& str)
374 if (_record_enable_control->get_value()) {
375 /* when re-arm'ed the file (named after the track) is already ready to rolll */
379 string diskstream_name = "";
380 if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
381 // Note: any text is fine, legalize_for_path() fixes this later
382 diskstream_name += _session.config.get_take_name ();
383 diskstream_name += "_";
385 const int64_t tracknumber = track_number();
386 if (tracknumber > 0 && _session.config.get_track_name_number()) {
387 char num[64], fmt[10];
388 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
389 snprintf(num, sizeof(num), fmt, tracknumber);
390 diskstream_name += num;
391 diskstream_name += "_";
393 diskstream_name += str;
395 if (diskstream_name == _diskstream_name) {
398 _diskstream_name = diskstream_name;
400 _disk_writer->set_write_source_name (diskstream_name);
402 boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
404 if (_playlists[data_type()]->all_regions_empty () && _session.playlists()->playlists_for_track (me).size() == 1) {
405 /* Only rename the diskstream (and therefore the playlist) if
406 a) the playlist has never had a region added to it and
407 b) there is only one playlist for this track.
409 If (a) is not followed, people can get confused if, say,
410 they have notes about a playlist with a given name and then
411 it changes (see mantis #4759).
413 If (b) is not followed, we rename the current playlist and not
414 the other ones, which is a bit confusing (see mantis #4977).
416 _disk_reader->set_name (str);
417 _disk_writer->set_name (str);
420 for (uint32_t n = 0; n < DataType::num_types; ++n) {
422 _playlists[n]->set_name (str);
426 /* save state so that the statefile fully reflects any filename changes */
428 if ((ret = Route::set_name (str)) == 0) {
429 _session.save_state ("");
435 boost::shared_ptr<Playlist>
438 return _playlists[data_type()];
442 Track::request_input_monitoring (bool m)
444 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
445 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
450 Track::ensure_input_monitoring (bool m)
452 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
453 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
458 Track::destructive () const
460 return _disk_writer->destructive ();
463 list<boost::shared_ptr<Source> > &
464 Track::last_capture_sources ()
466 return _disk_writer->last_capture_sources ();
470 Track::steal_write_source_name()
472 return _disk_writer->steal_write_source_name ();
476 Track::reset_write_sources (bool r, bool force)
478 _disk_writer->reset_write_sources (r, force);
482 Track::playback_buffer_load () const
484 return _disk_reader->buffer_load ();
488 Track::capture_buffer_load () const
490 return _disk_writer->buffer_load ();
496 return _disk_reader->do_refill ();
500 Track::do_flush (RunContext c, bool force)
502 return _disk_writer->do_flush (c, force);
506 Track::set_pending_overwrite ()
508 _disk_reader->set_pending_overwrite ();
512 Track::seek (samplepos_t p, bool complete_refill)
514 if (_disk_reader->seek (p, complete_refill)) {
517 return _disk_writer->seek (p, complete_refill);
521 Track::can_internal_playback_seek (samplecnt_t p)
523 return _disk_reader->can_internal_playback_seek (p);
527 Track::internal_playback_seek (samplecnt_t p)
529 return _disk_reader->internal_playback_seek (p);
533 Track::non_realtime_locate (samplepos_t p)
535 Route::non_realtime_locate (p);
539 Track::overwrite_existing_buffers ()
541 return _disk_reader->overwrite_existing_buffers ();
545 Track::get_captured_samples (uint32_t n) const
547 return _disk_writer->get_captured_samples (n);
551 Track::transport_looped (samplepos_t p)
553 return _disk_writer->transport_looped (p);
557 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
559 _disk_writer->transport_stopped_wallclock (n, t, g);
563 Track::pending_overwrite () const
565 return _disk_reader->pending_overwrite ();
569 Track::set_slaved (bool s)
571 _disk_reader->set_slaved (s);
572 _disk_writer->set_slaved (s);
578 return _disk_reader->output_streams();
582 Track::get_capture_start_sample (uint32_t n) const
584 return _disk_writer->get_capture_start_sample (n);
588 Track::alignment_style () const
590 return _disk_writer->alignment_style ();
594 Track::alignment_choice () const
596 return _alignment_choice;
600 Track::current_capture_start () const
602 return _disk_writer->current_capture_start ();
606 Track::current_capture_end () const
608 return _disk_writer->current_capture_end ();
612 Track::playlist_modified ()
614 _disk_reader->playlist_modified ();
618 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
620 boost::shared_ptr<Playlist> playlist;
622 if ((playlist = _session.playlists()->by_id (id)) == 0) {
627 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
631 return use_playlist (dt, playlist);
635 update_region_visibility(boost::shared_ptr<Region> r)
637 Region::RegionPropertyChanged(r, Properties::hidden);
642 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
646 if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
647 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
648 p->set_orig_track_id (id());
652 boost::shared_ptr<Playlist> old = _playlists[dt];
658 //allow all regions of prior and new playlists to update their visibility?
659 if (old) old->foreach_region(update_region_visibility);
660 if (p) p->foreach_region(update_region_visibility);
662 _session.set_dirty ();
663 PlaylistChanged (); /* EMIT SIGNAL */
669 Track::use_copy_playlist ()
671 assert (_playlists[data_type()]);
673 if (_playlists[data_type()] == 0) {
674 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
679 boost::shared_ptr<Playlist> playlist;
681 newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
683 if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
687 playlist->reset_shares();
689 return use_playlist (data_type(), playlist);
693 Track::use_new_playlist (DataType dt)
696 boost::shared_ptr<Playlist> playlist = _playlists[dt];
699 newname = Playlist::bump_name (playlist->name(), _session);
701 newname = Playlist::bump_name (_name, _session);
704 playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
710 return use_playlist (dt, playlist);
714 Track::set_align_choice (AlignChoice ac, bool force)
716 _alignment_choice = ac;
719 set_align_choice_from_io ();
722 _disk_writer->set_align_style (CaptureTime, force);
724 case UseExistingMaterial:
725 _disk_writer->set_align_style (ExistingMaterial, force);
731 Track::set_align_style (AlignStyle s, bool force)
733 _disk_writer->set_align_style (s, force);
737 Track::set_align_choice_from_io ()
739 bool have_physical = false;
743 vector<string> connections;
744 boost::shared_ptr<Port> p;
748 p = _input->nth (n++);
754 if (p->get_connections (connections) != 0) {
755 if (AudioEngine::instance()->port_is_physical (connections[0])) {
756 have_physical = true;
761 connections.clear ();
764 /* Special case bounding the Metronome.
765 * Click-out is aligned to output and hence
766 * equivalent to a physical round-trip alike
769 if (!have_physical && _session.click_io ()) {
770 if (_session.click_io ()->connected_to (_input)) {
771 have_physical = true;
778 // compensate for latency when bouncing from master or mixbus.
779 // we need to use "ExistingMaterial" to pick up the master bus' latency
780 // see also Route::direct_feeds_according_to_reality
782 ios.push_back (_input);
783 if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
784 have_physical = true;
786 for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
787 if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
788 have_physical = true;
794 _disk_writer->set_align_style (ExistingMaterial);
796 _disk_writer->set_align_style (CaptureTime);
801 Track::set_block_size (pframes_t n)
803 Route::set_block_size (n);
804 _disk_reader->set_block_size (n);
805 _disk_writer->set_block_size (n);
809 Track::adjust_playback_buffering ()
812 _disk_reader->adjust_buffering ();
817 Track::adjust_capture_buffering ()
820 _disk_writer->adjust_buffering ();
825 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
827 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
828 (*i)->monitoring_changed ();
833 Track::metering_state () const
836 if (_session.transport_rolling ()) {
837 // audio_track.cc || midi_track.cc roll() runs meter IFF:
838 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
840 // track no_roll() always metering if
841 rv = _meter_point == MeterInput;
843 return rv ? MeteringInput : MeteringRoute;
847 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
849 if (Route::set_processor_state (node, prop, new_order, must_configure)) {
853 cerr << name() << " looking for state for track procs, DR = " << _disk_reader << endl;
855 if (prop->value() == "diskreader") {
857 _disk_reader->set_state (node, Stateful::current_state_version);
858 new_order.push_back (_disk_reader);
861 } else if (prop->value() == "diskwriter") {
863 _disk_writer->set_state (node, Stateful::current_state_version);
864 new_order.push_back (_disk_writer);
869 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
874 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
880 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
881 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
884 use_captured_audio_sources (srcs, capture_info);
888 use_captured_midi_sources (srcs, capture_info);
893 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
895 if (srcs.empty() || data_type() != DataType::MIDI) {
899 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
900 boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
901 boost::shared_ptr<MidiRegion> midi_region;
902 CaptureInfos::const_iterator ci;
908 samplecnt_t total_capture = 0;
910 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
911 total_capture += (*ci)->samples;
914 /* we will want to be able to keep (over)writing the source
915 but we don't want it to be removable. this also differs
916 from the audio situation, where the source at this point
917 must be considered immutable. luckily, we can rely on
918 MidiSource::mark_streaming_write_completed() to have
919 already done the necessary work for that.
922 string whole_file_region_name;
923 whole_file_region_name = region_name_from_path (mfs->name(), true);
925 /* Register a new region with the Session that
926 describes the entire source. Do this first
927 so that any sub-regions will obviously be
928 children of this one (later!)
934 plist.add (Properties::name, whole_file_region_name);
935 plist.add (Properties::whole_file, true);
936 plist.add (Properties::automatic, true);
937 plist.add (Properties::start, 0);
938 plist.add (Properties::length, total_capture);
939 plist.add (Properties::layer, 0);
941 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
943 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
944 midi_region->special_set_position (capture_info.front()->start);
947 catch (failed_constructor& err) {
948 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
952 pl->clear_changes ();
955 /* Session sample time of the initial capture in this pass, which is where the source starts */
956 samplepos_t initial_capture = 0;
957 if (!capture_info.empty()) {
958 initial_capture = capture_info.front()->start;
961 BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
962 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
964 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
968 RegionFactory::region_name (region_name, mfs->name(), false);
970 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
971 _name, (*ci)->start, (*ci)->samples, region_name));
974 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " add a region\n";
979 /* start of this region is the offset between the start of its capture and the start of the whole pass */
980 plist.add (Properties::start, (*ci)->start - initial_capture);
981 plist.add (Properties::length, (*ci)->samples);
982 plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double());
983 plist.add (Properties::name, region_name);
985 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
986 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
987 if (preroll_off > 0) {
988 midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
992 catch (failed_constructor& err) {
993 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
994 continue; /* XXX is this OK? */
997 cerr << "add new region, len = " << (*ci)->samples << " @ " << (*ci)->start << endl;
999 pl->add_region (midi_region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode ());
1003 _session.add_command (new StatefulDiffCommand (pl));
1007 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1009 if (srcs.empty() || data_type() != DataType::AUDIO) {
1013 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1014 boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1015 boost::shared_ptr<AudioRegion> region;
1021 /* destructive tracks have a single, never changing region */
1023 if (destructive()) {
1025 /* send a signal that any UI can pick up to do the right thing. there is
1026 a small problem here in that a UI may need the peak data to be ready
1027 for the data that was recorded and this isn't interlocked with that
1028 process. this problem is deferred to the UI.
1031 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1035 string whole_file_region_name;
1036 whole_file_region_name = region_name_from_path (afs->name(), true);
1038 /* Register a new region with the Session that
1039 describes the entire source. Do this first
1040 so that any sub-regions will obviously be
1041 children of this one (later!)
1047 plist.add (Properties::start, afs->last_capture_start_sample());
1048 plist.add (Properties::length, afs->length(0));
1049 plist.add (Properties::name, whole_file_region_name);
1050 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1051 rx->set_automatic (true);
1052 rx->set_whole_file (true);
1054 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1055 region->special_set_position (afs->natural_position());
1059 catch (failed_constructor& err) {
1060 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1064 pl->clear_changes ();
1065 pl->set_capture_insertion_in_progress (true);
1068 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
1069 samplecnt_t buffer_position = afs->last_capture_start_sample ();
1070 CaptureInfos::const_iterator ci;
1072 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1076 RegionFactory::region_name (region_name, whole_file_region_name, false);
1078 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1079 _name, (*ci)->start, (*ci)->samples, region_name, buffer_position));
1085 plist.add (Properties::start, buffer_position);
1086 plist.add (Properties::length, (*ci)->samples);
1087 plist.add (Properties::name, region_name);
1089 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1090 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1091 if (preroll_off > 0) {
1092 region->trim_front (buffer_position + preroll_off);
1096 catch (failed_constructor& err) {
1097 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1098 continue; /* XXX is this OK? */
1101 pl->add_region (region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode());
1102 pl->set_layer (region, DBL_MAX);
1104 buffer_position += (*ci)->samples;
1108 pl->set_capture_insertion_in_progress (false);
1109 _session.add_command (new StatefulDiffCommand (pl));