2 Copyright (C) 2006 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.
18 #include "pbd/error.h"
20 #include "ardour/amp.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/audiofilesource.h"
23 #include "ardour/audioplaylist.h"
24 #include "ardour/audioregion.h"
25 #include "ardour/debug.h"
26 #include "ardour/delivery.h"
27 #include "ardour/disk_reader.h"
28 #include "ardour/disk_writer.h"
29 #include "ardour/event_type_map.h"
30 #include "ardour/io_processor.h"
31 #include "ardour/meter.h"
32 #include "ardour/midi_playlist.h"
33 #include "ardour/midi_region.h"
34 #include "ardour/monitor_control.h"
35 #include "ardour/playlist.h"
36 #include "ardour/playlist_factory.h"
37 #include "ardour/port.h"
38 #include "ardour/processor.h"
39 #include "ardour/profile.h"
40 #include "ardour/region_factory.h"
41 #include "ardour/record_enable_control.h"
42 #include "ardour/record_safe_control.h"
43 #include "ardour/route_group_specialized.h"
44 #include "ardour/session.h"
45 #include "ardour/session_playlists.h"
46 #include "ardour/smf_source.h"
47 #include "ardour/track.h"
48 #include "ardour/types_convert.h"
49 #include "ardour/utils.h"
54 using namespace ARDOUR;
57 Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
58 : Route (sess, name, flag, default_type)
59 , _saved_meter_point (_meter_point)
61 , _alignment_choice (Automatic)
63 _freeze_record.state = NoFreeze;
70 DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
73 _disk_reader->set_route (boost::shared_ptr<Route>());
74 _disk_reader.reset ();
78 _disk_writer->set_route (boost::shared_ptr<Route>());
79 _disk_writer.reset ();
90 DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
92 if (_mode == Destructive && !Profile->get_trx()) {
93 dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
96 _disk_reader.reset (new DiskReader (_session, name(), dflags));
97 _disk_reader->set_block_size (_session.get_block_size ());
98 _disk_reader->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
99 _disk_reader->set_owner (this);
101 _disk_writer.reset (new DiskWriter (_session, name(), dflags));
102 _disk_writer->set_block_size (_session.get_block_size ());
103 _disk_writer->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
104 _disk_writer->set_owner (this);
106 set_align_choice_from_io ();
108 use_new_playlist (data_type());
110 boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
111 boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
113 _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
114 add_control (_record_enable_control);
116 _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
117 add_control (_record_safe_control);
119 _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
120 add_control (_monitoring_control);
122 _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
124 _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
125 _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
126 _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
128 _input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this));
134 Track::input_changed ()
136 if (_disk_writer && _alignment_choice == Automatic) {
137 set_align_choice_from_io ();
142 Track::state (bool save_template)
144 XMLNode& root (Route::state (save_template));
146 if (_playlists[DataType::AUDIO]) {
147 root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
150 if (_playlists[DataType::MIDI]) {
151 root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
154 root.add_child_nocopy (_monitoring_control->get_state ());
155 root.add_child_nocopy (_record_safe_control->get_state ());
156 root.add_child_nocopy (_record_enable_control->get_state ());
158 root.set_property (X_("saved-meter-point"), _saved_meter_point);
159 root.set_property (X_("alignment-choice"), _alignment_choice);
165 Track::set_state (const XMLNode& node, int version)
167 if (Route::set_state (node, version)) {
171 if (version >= 3000 && version < 6000) {
172 if (XMLNode* ds_node = find_named_node (node, "Diskstream")) {
174 if (ds_node->get_property ("name", name)) {
176 ds_node->set_property ("active", true);
178 _disk_writer->set_state (*ds_node, version);
179 _disk_reader->set_state (*ds_node, version);
182 if (ds_node->get_property (X_("capture-alignment"), ac)) {
183 set_align_choice (ac, true);
186 if (boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists->by_name (name))) {
187 use_playlist (DataType::AUDIO, pl);
190 if (boost::shared_ptr<MidiPlaylist> pl = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) {
191 use_playlist (DataType::MIDI, pl);
198 std::string playlist_id;
200 if (node.get_property (X_("audio-playlist"), playlist_id)) {
201 find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
204 if (node.get_property (X_("midi-playlist"), playlist_id)) {
205 find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
208 XMLNodeList nlist = node.children();
209 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
212 if (child->name() == Controllable::xml_node_name) {
214 if (!child->get_property ("name", name)) {
218 if (name == _record_enable_control->name()) {
219 _record_enable_control->set_state (*child, version);
220 } else if (name == _record_safe_control->name()) {
221 _record_safe_control->set_state (*child, version);
222 } else if (name == _monitoring_control->name()) {
223 _monitoring_control->set_state (*child, version);
228 if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
229 _saved_meter_point = _meter_point;
235 if (node.get_property (X_("alignment-choice"), ac)) {
236 set_align_choice (ac, true);
242 Track::FreezeRecord::~FreezeRecord ()
244 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
250 Track::freeze_state() const
252 return _freeze_record.state;
258 bool will_record = true;
259 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
268 Track::prep_record_enabled (bool yn)
270 if (yn && _record_safe_control->get_value()) {
274 if (!can_be_record_enabled()) {
278 /* keep track of the meter point as it was before we rec-enabled */
279 if (!_disk_writer->record_enabled()) {
280 _saved_meter_point = _meter_point;
286 will_follow = _disk_writer->prep_record_enable ();
288 will_follow = _disk_writer->prep_record_disable ();
293 if (_meter_point != MeterCustom) {
294 set_meter_point (MeterInput);
297 set_meter_point (_saved_meter_point);
305 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
307 _disk_writer->set_record_enabled (_record_enable_control->get_value());
311 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
313 _disk_writer->set_record_safe (_record_safe_control->get_value());
317 Track::can_be_record_safe ()
319 return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
323 Track::can_be_record_enabled ()
325 return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
329 Track::parameter_changed (string const & p)
331 if (p == "track-name-number") {
332 resync_track_name ();
334 else if (p == "track-name-take") {
335 resync_track_name ();
337 else if (p == "take-name") {
338 if (_session.config.get_track_name_take()) {
339 resync_track_name ();
345 Track::resync_track_name ()
351 Track::set_name (const string& str)
359 if (_record_enable_control->get_value()) {
360 /* when re-arm'ed the file (named after the track) is already ready to rolll */
364 string diskstream_name = "";
365 if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
366 // Note: any text is fine, legalize_for_path() fixes this later
367 diskstream_name += _session.config.get_take_name ();
368 diskstream_name += "_";
370 const int64_t tracknumber = track_number();
371 if (tracknumber > 0 && _session.config.get_track_name_number()) {
372 char num[64], fmt[10];
373 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
374 snprintf(num, sizeof(num), fmt, tracknumber);
375 diskstream_name += num;
376 diskstream_name += "_";
378 diskstream_name += str;
380 if (diskstream_name == _diskstream_name) {
383 _diskstream_name = diskstream_name;
385 _disk_writer->set_write_source_name (diskstream_name);
387 boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
389 if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
390 /* Only rename the diskstream (and therefore the playlist) if
391 a) the playlist has never had a region added to it and
392 b) there is only one playlist for this track.
394 If (a) is not followed, people can get confused if, say,
395 they have notes about a playlist with a given name and then
396 it changes (see mantis #4759).
398 If (b) is not followed, we rename the current playlist and not
399 the other ones, which is a bit confusing (see mantis #4977).
401 _disk_reader->set_name (str);
402 _disk_writer->set_name (str);
405 for (uint32_t n = 0; n < DataType::num_types; ++n) {
407 _playlists[n]->set_name (str);
411 /* save state so that the statefile fully reflects any filename changes */
413 if ((ret = Route::set_name (str)) == 0) {
414 _session.save_state ("");
420 boost::shared_ptr<Playlist>
423 return _playlists[data_type()];
427 Track::request_input_monitoring (bool m)
429 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
430 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
435 Track::ensure_input_monitoring (bool m)
437 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
438 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
443 Track::destructive () const
445 return _disk_writer->destructive ();
448 list<boost::shared_ptr<Source> > &
449 Track::last_capture_sources ()
451 return _disk_writer->last_capture_sources ();
455 Track::steal_write_source_name()
457 return _disk_writer->steal_write_source_name ();
461 Track::reset_write_sources (bool r, bool force)
463 _disk_writer->reset_write_sources (r, force);
467 Track::playback_buffer_load () const
469 return _disk_reader->buffer_load ();
473 Track::capture_buffer_load () const
475 return _disk_writer->buffer_load ();
481 return _disk_reader->do_refill ();
485 Track::do_flush (RunContext c, bool force)
487 return _disk_writer->do_flush (c, force);
491 Track::set_pending_overwrite (bool o)
493 _disk_reader->set_pending_overwrite (o);
497 Track::seek (samplepos_t p, bool complete_refill)
499 if (_disk_reader->seek (p, complete_refill)) {
502 return _disk_writer->seek (p, complete_refill);
506 Track::can_internal_playback_seek (samplecnt_t p)
508 return _disk_reader->can_internal_playback_seek (p);
512 Track::internal_playback_seek (samplecnt_t p)
514 return _disk_reader->internal_playback_seek (p);
518 Track::non_realtime_locate (samplepos_t p)
520 Route::non_realtime_locate (p);
524 Track::non_realtime_speed_change ()
526 _disk_reader->non_realtime_speed_change ();
530 Track::overwrite_existing_buffers ()
532 return _disk_reader->overwrite_existing_buffers ();
536 Track::get_captured_samples (uint32_t n) const
538 return _disk_writer->get_captured_samples (n);
542 Track::transport_looped (samplepos_t p)
544 return _disk_writer->transport_looped (p);
548 Track::realtime_handle_transport_stopped ()
550 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
556 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
557 (*i)->realtime_handle_transport_stopped ();
562 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
564 _disk_writer->transport_stopped_wallclock (n, t, g);
568 Track::pending_overwrite () const
570 return _disk_reader->pending_overwrite ();
574 Track::set_slaved (bool s)
576 _disk_reader->set_slaved (s);
577 _disk_writer->set_slaved (s);
583 return _disk_reader->output_streams();
587 Track::get_capture_start_sample (uint32_t n) const
589 return _disk_writer->get_capture_start_sample (n);
593 Track::alignment_style () const
595 return _disk_writer->alignment_style ();
599 Track::alignment_choice () const
601 return _alignment_choice;
605 Track::current_capture_start () const
607 return _disk_writer->current_capture_start ();
611 Track::current_capture_end () const
613 return _disk_writer->current_capture_end ();
617 Track::playlist_modified ()
619 _disk_reader->playlist_modified ();
623 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
625 boost::shared_ptr<Playlist> playlist;
627 if ((playlist = _session.playlists->by_id (id)) == 0) {
632 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
636 return use_playlist (dt, playlist);
640 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
644 if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
645 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
646 p->set_orig_track_id (id());
654 _session.set_dirty ();
655 PlaylistChanged (); /* EMIT SIGNAL */
661 Track::use_copy_playlist ()
663 assert (_playlists[data_type()]);
665 if (_playlists[data_type()] == 0) {
666 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
671 boost::shared_ptr<Playlist> playlist;
673 newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
675 if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
679 playlist->reset_shares();
681 return use_playlist (data_type(), playlist);
685 Track::use_new_playlist (DataType dt)
688 boost::shared_ptr<Playlist> playlist = _playlists[dt];
691 newname = Playlist::bump_name (playlist->name(), _session);
693 newname = Playlist::bump_name (_name, _session);
696 playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
702 return use_playlist (dt, playlist);
706 Track::set_align_choice (AlignChoice ac, bool force)
708 _alignment_choice = ac;
711 set_align_choice_from_io ();
714 _disk_writer->set_align_style (CaptureTime, force);
716 case UseExistingMaterial:
717 _disk_writer->set_align_style (ExistingMaterial, force);
723 Track::set_align_style (AlignStyle s, bool force)
725 _disk_writer->set_align_style (s, force);
729 Track::set_align_choice_from_io ()
731 bool have_physical = false;
735 vector<string> connections;
736 boost::shared_ptr<Port> p;
740 p = _input->nth (n++);
746 if (p->get_connections (connections) != 0) {
747 if (AudioEngine::instance()->port_is_physical (connections[0])) {
748 have_physical = true;
753 connections.clear ();
758 // compensate for latency when bouncing from master or mixbus.
759 // we need to use "ExistingMaterial" to pick up the master bus' latency
760 // see also Route::direct_feeds_according_to_reality
762 ios.push_back (_input);
763 if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
764 have_physical = true;
766 for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
767 if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
768 have_physical = true;
774 _disk_writer->set_align_style (ExistingMaterial);
776 _disk_writer->set_align_style (CaptureTime);
781 Track::set_block_size (pframes_t n)
783 Route::set_block_size (n);
784 _disk_reader->set_block_size (n);
785 _disk_writer->set_block_size (n);
789 Track::adjust_playback_buffering ()
792 _disk_reader->adjust_buffering ();
797 Track::adjust_capture_buffering ()
800 _disk_writer->adjust_buffering ();
806 Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)
808 /* never declick if there is an internal generator - we just want it to
809 keep generating sound without interruption.
811 ditto if we are monitoring inputs.
814 if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
819 declick = _pending_declick;
823 Amp::declick (bufs, nframes, declick);
828 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
830 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
831 (*i)->monitoring_changed ();
836 Track::metering_state () const
839 if (_session.transport_rolling ()) {
840 // audio_track.cc || midi_track.cc roll() runs meter IFF:
841 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
843 // track no_roll() always metering if
844 rv = _meter_point == MeterInput;
846 return rv ? MeteringInput : MeteringRoute;
850 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
852 if (Route::set_processor_state (node, prop, new_order, must_configure)) {
856 cerr << name() << " looking for state for track procs, DR = " << _disk_reader << endl;
858 if (prop->value() == "diskreader") {
860 _disk_reader->set_state (node, Stateful::current_state_version);
861 new_order.push_back (_disk_reader);
864 } else if (prop->value() == "diskwriter") {
866 _disk_writer->set_state (node, Stateful::current_state_version);
867 new_order.push_back (_disk_writer);
872 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
877 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
883 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
884 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
887 use_captured_audio_sources (srcs, capture_info);
891 use_captured_midi_sources (srcs, capture_info);
896 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
898 if (srcs.empty() || data_type() != DataType::MIDI) {
902 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
903 boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
904 boost::shared_ptr<MidiRegion> midi_region;
905 CaptureInfos::const_iterator ci;
911 samplecnt_t total_capture = 0;
913 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
914 total_capture += (*ci)->samples;
917 /* we will want to be able to keep (over)writing the source
918 but we don't want it to be removable. this also differs
919 from the audio situation, where the source at this point
920 must be considered immutable. luckily, we can rely on
921 MidiSource::mark_streaming_write_completed() to have
922 already done the necessary work for that.
925 string whole_file_region_name;
926 whole_file_region_name = region_name_from_path (mfs->name(), true);
928 /* Register a new region with the Session that
929 describes the entire source. Do this first
930 so that any sub-regions will obviously be
931 children of this one (later!)
937 plist.add (Properties::name, whole_file_region_name);
938 plist.add (Properties::whole_file, true);
939 plist.add (Properties::automatic, true);
940 plist.add (Properties::start, 0);
941 plist.add (Properties::length, total_capture);
942 plist.add (Properties::layer, 0);
944 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
946 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
947 midi_region->special_set_position (capture_info.front()->start);
950 catch (failed_constructor& err) {
951 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
955 pl->clear_changes ();
958 /* Session sample time of the initial capture in this pass, which is where the source starts */
959 samplepos_t initial_capture = 0;
960 if (!capture_info.empty()) {
961 initial_capture = capture_info.front()->start;
964 BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
965 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
967 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
971 RegionFactory::region_name (region_name, mfs->name(), false);
973 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
974 _name, (*ci)->start, (*ci)->samples, region_name));
977 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " add a region\n";
982 /* start of this region is the offset between the start of its capture and the start of the whole pass */
983 plist.add (Properties::start, (*ci)->start - initial_capture);
984 plist.add (Properties::length, (*ci)->samples);
985 plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double());
986 plist.add (Properties::name, region_name);
988 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
989 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
990 if (preroll_off > 0) {
991 midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
995 catch (failed_constructor& err) {
996 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
997 continue; /* XXX is this OK? */
1000 cerr << "add new region, len = " << (*ci)->samples << " @ " << (*ci)->start << endl;
1002 pl->add_region (midi_region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode ());
1006 _session.add_command (new StatefulDiffCommand (pl));
1010 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1012 if (srcs.empty() || data_type() != DataType::AUDIO) {
1016 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1017 boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1018 boost::shared_ptr<AudioRegion> region;
1024 /* destructive tracks have a single, never changing region */
1026 if (destructive()) {
1028 /* send a signal that any UI can pick up to do the right thing. there is
1029 a small problem here in that a UI may need the peak data to be ready
1030 for the data that was recorded and this isn't interlocked with that
1031 process. this problem is deferred to the UI.
1034 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1038 string whole_file_region_name;
1039 whole_file_region_name = region_name_from_path (afs->name(), true);
1041 /* Register a new region with the Session that
1042 describes the entire source. Do this first
1043 so that any sub-regions will obviously be
1044 children of this one (later!)
1050 plist.add (Properties::start, afs->last_capture_start_sample());
1051 plist.add (Properties::length, afs->length(0));
1052 plist.add (Properties::name, whole_file_region_name);
1053 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1054 rx->set_automatic (true);
1055 rx->set_whole_file (true);
1057 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1058 region->special_set_position (afs->natural_position());
1062 catch (failed_constructor& err) {
1063 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1067 pl->clear_changes ();
1068 pl->set_capture_insertion_in_progress (true);
1071 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
1072 samplecnt_t buffer_position = afs->last_capture_start_sample ();
1073 CaptureInfos::const_iterator ci;
1075 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1079 RegionFactory::region_name (region_name, whole_file_region_name, false);
1081 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1082 _name, (*ci)->start, (*ci)->samples, region_name, buffer_position));
1088 plist.add (Properties::start, buffer_position);
1089 plist.add (Properties::length, (*ci)->samples);
1090 plist.add (Properties::name, region_name);
1092 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1093 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1094 if (preroll_off > 0) {
1095 region->trim_front (buffer_position + preroll_off);
1099 catch (failed_constructor& err) {
1100 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1101 continue; /* XXX is this OK? */
1104 pl->add_region (region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode());
1105 pl->set_layer (region, DBL_MAX);
1107 buffer_position += (*ci)->samples;
1111 pl->set_capture_insertion_in_progress (false);
1112 _session.add_command (new StatefulDiffCommand (pl));