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);
94 } else if (_mode == NonLayered){
95 dflags = DiskIOProcessor::Flag(dflags | DiskIOProcessor::NonLayered);
98 _disk_reader.reset (new DiskReader (_session, name(), dflags));
99 _disk_reader->set_block_size (_session.get_block_size ());
100 _disk_reader->set_route (boost::dynamic_pointer_cast<Route> (shared_from_this()));
102 _disk_writer.reset (new DiskWriter (_session, name(), dflags));
103 _disk_writer->set_block_size (_session.get_block_size ());
104 _disk_writer->set_route (boost::dynamic_pointer_cast<Route> (shared_from_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 ();
148 Track::state (bool full)
150 XMLNode& root (Route::state (full));
152 if (_playlists[DataType::AUDIO]) {
153 root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
156 if (_playlists[DataType::MIDI]) {
157 root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
160 root.add_child_nocopy (_monitoring_control->get_state ());
161 root.add_child_nocopy (_record_safe_control->get_state ());
162 root.add_child_nocopy (_record_enable_control->get_state ());
164 root.set_property (X_("saved-meter-point"), _saved_meter_point);
165 root.set_property (X_("alignment-choice"), _alignment_choice);
171 Track::set_state (const XMLNode& node, int version)
173 if (Route::set_state (node, version)) {
177 if (version >= 3000 && version < 6000) {
178 if (XMLNode* ds_node = find_named_node (node, "Diskstream")) {
180 if (ds_node->get_property ("name", name)) {
182 ds_node->set_property ("active", true);
184 _disk_writer->set_state (*ds_node, version);
185 _disk_reader->set_state (*ds_node, version);
188 if (ds_node->get_property (X_("capture-alignment"), ac)) {
189 set_align_choice (ac, true);
192 if (boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists->by_name (name))) {
193 use_playlist (DataType::AUDIO, pl);
196 if (boost::shared_ptr<MidiPlaylist> pl = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists->by_name (name))) {
197 use_playlist (DataType::MIDI, pl);
204 std::string playlist_id;
206 if (node.get_property (X_("audio-playlist"), playlist_id)) {
207 find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
210 if (node.get_property (X_("midi-playlist"), playlist_id)) {
211 find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
214 XMLNodeList nlist = node.children();
215 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
218 if (child->name() == Controllable::xml_node_name) {
220 if (!child->get_property ("name", name)) {
224 if (name == _record_enable_control->name()) {
225 _record_enable_control->set_state (*child, version);
226 } else if (name == _record_safe_control->name()) {
227 _record_safe_control->set_state (*child, version);
228 } else if (name == _monitoring_control->name()) {
229 _monitoring_control->set_state (*child, version);
234 if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
235 _saved_meter_point = _meter_point;
241 if (node.get_property (X_("alignment-choice"), ac)) {
242 set_align_choice (ac, true);
249 Track::get_template ()
251 return state (false);
254 Track::FreezeRecord::~FreezeRecord ()
256 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
262 Track::freeze_state() const
264 return _freeze_record.state;
270 bool will_record = true;
271 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
280 Track::prep_record_enabled (bool yn)
282 if (yn && _record_safe_control->get_value()) {
286 if (!can_be_record_enabled()) {
290 /* keep track of the meter point as it was before we rec-enabled */
291 if (!_disk_writer->record_enabled()) {
292 _saved_meter_point = _meter_point;
298 will_follow = _disk_writer->prep_record_enable ();
300 will_follow = _disk_writer->prep_record_disable ();
305 if (_meter_point != MeterCustom) {
306 set_meter_point (MeterInput);
309 set_meter_point (_saved_meter_point);
317 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
319 _disk_writer->set_record_enabled (_record_enable_control->get_value());
323 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
325 _disk_writer->set_record_safe (_record_safe_control->get_value());
329 Track::can_be_record_safe ()
331 return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
335 Track::can_be_record_enabled ()
337 return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
341 Track::parameter_changed (string const & p)
343 if (p == "track-name-number") {
344 resync_track_name ();
346 else if (p == "track-name-take") {
347 resync_track_name ();
349 else if (p == "take-name") {
350 if (_session.config.get_track_name_take()) {
351 resync_track_name ();
357 Track::resync_track_name ()
363 Track::set_name (const string& str)
371 if (_record_enable_control->get_value()) {
372 /* when re-arm'ed the file (named after the track) is already ready to rolll */
376 string diskstream_name = "";
377 if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
378 // Note: any text is fine, legalize_for_path() fixes this later
379 diskstream_name += _session.config.get_take_name ();
380 diskstream_name += "_";
382 const int64_t tracknumber = track_number();
383 if (tracknumber > 0 && _session.config.get_track_name_number()) {
384 char num[64], fmt[10];
385 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
386 snprintf(num, sizeof(num), fmt, tracknumber);
387 diskstream_name += num;
388 diskstream_name += "_";
390 diskstream_name += str;
392 if (diskstream_name == _diskstream_name) {
395 _diskstream_name = diskstream_name;
397 _disk_writer->set_write_source_name (diskstream_name);
399 boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
401 if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
402 /* Only rename the diskstream (and therefore the playlist) if
403 a) the playlist has never had a region added to it and
404 b) there is only one playlist for this track.
406 If (a) is not followed, people can get confused if, say,
407 they have notes about a playlist with a given name and then
408 it changes (see mantis #4759).
410 If (b) is not followed, we rename the current playlist and not
411 the other ones, which is a bit confusing (see mantis #4977).
413 _disk_reader->set_name (str);
414 _disk_writer->set_name (str);
417 for (uint32_t n = 0; n < DataType::num_types; ++n) {
419 _playlists[n]->set_name (str);
423 /* save state so that the statefile fully reflects any filename changes */
425 if ((ret = Route::set_name (str)) == 0) {
426 _session.save_state ("");
433 Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing)
435 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
441 /* no outputs? nothing to do ... what happens if we have sends etc. ? */
443 if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) {
444 //Note: Mixbus has its own output mechanism, so we should operate even if no explicit outputs are assigned
448 /* not active ... do the minimum possible by just outputting silence */
452 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
458 if (session_state_changing) {
459 if (_session.transport_speed() != 0.0f) {
460 /* we're rolling but some state is changing (e.g. our
461 disk reader contents) so we cannot use them. Be
462 silent till this is over. Don't declick.
464 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
466 passthru_silence (start_sample, end_sample, nframes, 0);
469 /* we're really not rolling, so we're either delivery silence or actually
470 monitoring, both of which are safe to do while session_state_changing is true.
475 MonitorState const s = monitoring_state ();
476 /* we are not rolling, so be silent even if we are monitoring disk, as there
477 will be no disk data coming in.
480 case MonitoringSilence:
486 case MonitoringInput:
494 //if we have an internal generator, let it play regardless of monitoring state
495 if (_have_internal_generator) {
499 /* if have_internal_generator, or .. */
503 if (_meter_point == MeterInput) {
504 /* still need input monitoring and metering */
506 bool const track_rec = _disk_writer->record_enabled ();
507 bool const auto_input = _session.config.get_auto_input ();
508 bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
509 bool const tape_machine_mode = Config->get_tape_machine_mode ();
510 bool no_meter = false;
512 /* this needs a proper K-map
513 * and should be separated into a function similar to monitoring_state()
514 * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc
516 * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf
518 if (!auto_input && !track_rec) {
521 else if (tape_machine_mode && !track_rec && auto_input) {
524 else if (!software_monitor && tape_machine_mode && !track_rec) {
527 else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) {
532 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
533 _meter->run (bufs, start_sample, end_sample, 1.0, nframes, true);
534 _input->process_input (boost::shared_ptr<Processor>(), start_sample, end_sample, _session.transport_speed(), nframes);
536 _input->process_input (_meter, start_sample, end_sample, _session.transport_speed(), nframes);
540 passthru_silence (start_sample, end_sample, nframes, 0);
544 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
546 fill_buffers_with_input (bufs, _input, nframes);
548 if (_meter_point == MeterInput) {
549 _meter->run (bufs, start_sample, end_sample, _session.transport_speed(), nframes, true);
552 passthru (bufs, start_sample, end_sample, nframes, false, true, false);
555 flush_processor_buffers_locked (nframes);
560 boost::shared_ptr<Playlist>
563 return _playlists[data_type()];
567 Track::request_input_monitoring (bool m)
569 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
570 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
575 Track::ensure_input_monitoring (bool m)
577 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
578 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
583 Track::destructive () const
585 return _disk_writer->destructive ();
588 list<boost::shared_ptr<Source> > &
589 Track::last_capture_sources ()
591 return _disk_writer->last_capture_sources ();
595 Track::steal_write_source_name()
597 return _disk_writer->steal_write_source_name ();
601 Track::reset_write_sources (bool r, bool force)
603 _disk_writer->reset_write_sources (r, force);
607 Track::playback_buffer_load () const
609 return _disk_reader->buffer_load ();
613 Track::capture_buffer_load () const
615 return _disk_writer->buffer_load ();
621 return _disk_reader->do_refill ();
625 Track::do_flush (RunContext c, bool force)
627 return _disk_writer->do_flush (c, force);
631 Track::set_pending_overwrite (bool o)
633 _disk_reader->set_pending_overwrite (o);
637 Track::seek (samplepos_t p, bool complete_refill)
639 if (_disk_reader->seek (p, complete_refill)) {
642 return _disk_writer->seek (p, complete_refill);
646 Track::can_internal_playback_seek (samplecnt_t p)
648 return _disk_reader->can_internal_playback_seek (p);
652 Track::internal_playback_seek (samplecnt_t p)
654 return _disk_reader->internal_playback_seek (p);
658 Track::non_realtime_locate (samplepos_t p)
660 Route::non_realtime_locate (p);
662 if (!is_private_route()) {
663 /* don't waste i/o cycles and butler calls
664 for private tracks (e.g.auditioner)
666 _disk_reader->non_realtime_locate (p);
667 _disk_writer->non_realtime_locate (p);
672 Track::non_realtime_speed_change ()
674 _disk_reader->non_realtime_speed_change ();
678 Track::overwrite_existing_buffers ()
680 return _disk_reader->overwrite_existing_buffers ();
684 Track::get_captured_samples (uint32_t n) const
686 return _disk_writer->get_captured_samples (n);
690 Track::set_loop (Location* l)
692 if (_disk_reader->set_loop (l)) {
695 return _disk_writer->set_loop (l);
699 Track::transport_looped (samplepos_t p)
701 return _disk_writer->transport_looped (p);
705 Track::realtime_speed_change ()
707 if (_disk_reader->realtime_speed_change ()) {
710 return _disk_writer->realtime_speed_change ();
714 Track::realtime_handle_transport_stopped ()
716 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
722 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
723 (*i)->realtime_handle_transport_stopped ();
728 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
730 _disk_writer->transport_stopped_wallclock (n, t, g);
734 Track::pending_overwrite () const
736 return _disk_reader->pending_overwrite ();
740 Track::set_slaved (bool s)
742 _disk_reader->set_slaved (s);
743 _disk_writer->set_slaved (s);
749 return _disk_reader->output_streams();
753 Track::get_capture_start_sample (uint32_t n) const
755 return _disk_writer->get_capture_start_sample (n);
759 Track::alignment_style () const
761 return _disk_writer->alignment_style ();
765 Track::alignment_choice () const
767 return _alignment_choice;
771 Track::current_capture_start () const
773 return _disk_writer->current_capture_start ();
777 Track::current_capture_end () const
779 return _disk_writer->current_capture_end ();
783 Track::playlist_modified ()
785 _disk_reader->playlist_modified ();
789 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
791 boost::shared_ptr<Playlist> playlist;
793 if ((playlist = _session.playlists->by_id (id)) == 0) {
798 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
802 return use_playlist (dt, playlist);
806 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
810 if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
811 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
812 p->set_orig_track_id (id());
820 _session.set_dirty ();
821 PlaylistChanged (); /* EMIT SIGNAL */
827 Track::use_copy_playlist ()
829 assert (_playlists[data_type()]);
831 if (_playlists[data_type()] == 0) {
832 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
837 boost::shared_ptr<Playlist> playlist;
839 newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
841 if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
845 playlist->reset_shares();
847 return use_playlist (data_type(), playlist);
851 Track::use_new_playlist (DataType dt)
854 boost::shared_ptr<Playlist> playlist = _playlists[dt];
857 newname = Playlist::bump_name (playlist->name(), _session);
859 newname = Playlist::bump_name (_name, _session);
862 playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
868 return use_playlist (dt, playlist);
872 Track::set_align_choice (AlignChoice ac, bool force)
874 _alignment_choice = ac;
877 set_align_choice_from_io ();
880 _disk_writer->set_align_style (CaptureTime, force);
882 case UseExistingMaterial:
883 _disk_writer->set_align_style (ExistingMaterial, force);
889 Track::set_align_style (AlignStyle s, bool force)
891 _disk_writer->set_align_style (s, force);
895 Track::set_align_choice_from_io ()
897 bool have_physical = false;
901 vector<string> connections;
902 boost::shared_ptr<Port> p;
906 p = _input->nth (n++);
912 if (p->get_connections (connections) != 0) {
913 if (AudioEngine::instance()->port_is_physical (connections[0])) {
914 have_physical = true;
919 connections.clear ();
924 // compensate for latency when bouncing from master or mixbus.
925 // we need to use "ExistingMaterial" to pick up the master bus' latency
926 // see also Route::direct_feeds_according_to_reality
928 ios.push_back (_input);
929 if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
930 have_physical = true;
932 for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
933 if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
934 have_physical = true;
940 _disk_writer->set_align_style (ExistingMaterial);
942 _disk_writer->set_align_style (CaptureTime);
947 Track::set_block_size (pframes_t n)
949 Route::set_block_size (n);
950 _disk_reader->set_block_size (n);
951 _disk_writer->set_block_size (n);
955 Track::adjust_playback_buffering ()
958 _disk_reader->adjust_buffering ();
963 Track::adjust_capture_buffering ()
966 _disk_writer->adjust_buffering ();
972 Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)
974 /* never declick if there is an internal generator - we just want it to
975 keep generating sound without interruption.
977 ditto if we are monitoring inputs.
980 if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
985 declick = _pending_declick;
989 Amp::declick (bufs, nframes, declick);
994 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
996 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
997 (*i)->monitoring_changed ();
1002 Track::metering_state () const
1005 if (_session.transport_rolling ()) {
1006 // audio_track.cc || midi_track.cc roll() runs meter IFF:
1007 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
1009 // track no_roll() always metering if
1010 rv = _meter_point == MeterInput;
1012 return rv ? MeteringInput : MeteringRoute;
1016 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
1018 if (Route::set_processor_state (node, prop, new_order, must_configure)) {
1022 cerr << name() << " looking for state for track procs, DR = " << _disk_reader << endl;
1024 if (prop->value() == "diskreader") {
1026 _disk_reader->set_state (node, Stateful::current_state_version);
1027 new_order.push_back (_disk_reader);
1030 } else if (prop->value() == "diskwriter") {
1032 _disk_writer->set_state (node, Stateful::current_state_version);
1033 new_order.push_back (_disk_writer);
1038 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
1043 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
1049 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1050 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
1053 use_captured_audio_sources (srcs, capture_info);
1057 use_captured_midi_sources (srcs, capture_info);
1062 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
1064 if (srcs.empty() || data_type() != DataType::MIDI) {
1068 boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
1069 boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
1070 boost::shared_ptr<MidiRegion> midi_region;
1071 CaptureInfos::const_iterator ci;
1077 samplecnt_t total_capture = 0;
1079 for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1080 total_capture += (*ci)->samples;
1083 /* we will want to be able to keep (over)writing the source
1084 but we don't want it to be removable. this also differs
1085 from the audio situation, where the source at this point
1086 must be considered immutable. luckily, we can rely on
1087 MidiSource::mark_streaming_write_completed() to have
1088 already done the necessary work for that.
1091 string whole_file_region_name;
1092 whole_file_region_name = region_name_from_path (mfs->name(), true);
1094 /* Register a new region with the Session that
1095 describes the entire source. Do this first
1096 so that any sub-regions will obviously be
1097 children of this one (later!)
1103 plist.add (Properties::name, whole_file_region_name);
1104 plist.add (Properties::whole_file, true);
1105 plist.add (Properties::automatic, true);
1106 plist.add (Properties::start, 0);
1107 plist.add (Properties::length, total_capture);
1108 plist.add (Properties::layer, 0);
1110 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1112 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1113 midi_region->special_set_position (capture_info.front()->start);
1116 catch (failed_constructor& err) {
1117 error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
1121 pl->clear_changes ();
1124 /* Session sample time of the initial capture in this pass, which is where the source starts */
1125 samplepos_t initial_capture = 0;
1126 if (!capture_info.empty()) {
1127 initial_capture = capture_info.front()->start;
1130 BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
1131 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
1133 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1137 RegionFactory::region_name (region_name, mfs->name(), false);
1139 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
1140 _name, (*ci)->start, (*ci)->samples, region_name));
1143 // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " add a region\n";
1148 /* start of this region is the offset between the start of its capture and the start of the whole pass */
1149 plist.add (Properties::start, (*ci)->start - initial_capture);
1150 plist.add (Properties::length, (*ci)->samples);
1151 plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double());
1152 plist.add (Properties::name, region_name);
1154 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1155 midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
1156 if (preroll_off > 0) {
1157 midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
1161 catch (failed_constructor& err) {
1162 error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1163 continue; /* XXX is this OK? */
1166 // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
1168 pl->add_region (midi_region, (*ci)->start + preroll_off, _disk_writer->non_layered());
1172 _session.add_command (new StatefulDiffCommand (pl));
1176 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1178 if (srcs.empty() || data_type() != DataType::AUDIO) {
1182 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1183 boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1184 boost::shared_ptr<AudioRegion> region;
1190 /* destructive tracks have a single, never changing region */
1192 if (destructive()) {
1194 /* send a signal that any UI can pick up to do the right thing. there is
1195 a small problem here in that a UI may need the peak data to be ready
1196 for the data that was recorded and this isn't interlocked with that
1197 process. this problem is deferred to the UI.
1200 pl->LayeringChanged(); // XXX this may not get the UI to do the right thing
1204 string whole_file_region_name;
1205 whole_file_region_name = region_name_from_path (afs->name(), true);
1207 /* Register a new region with the Session that
1208 describes the entire source. Do this first
1209 so that any sub-regions will obviously be
1210 children of this one (later!)
1216 plist.add (Properties::start, afs->last_capture_start_sample());
1217 plist.add (Properties::length, afs->length(0));
1218 plist.add (Properties::name, whole_file_region_name);
1219 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1220 rx->set_automatic (true);
1221 rx->set_whole_file (true);
1223 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1224 region->special_set_position (afs->natural_position());
1228 catch (failed_constructor& err) {
1229 error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1233 pl->clear_changes ();
1234 pl->set_capture_insertion_in_progress (true);
1237 const samplepos_t preroll_off = _session.preroll_record_trim_len ();
1238 samplecnt_t buffer_position = afs->last_capture_start_sample ();
1239 CaptureInfos::const_iterator ci;
1241 for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1245 RegionFactory::region_name (region_name, whole_file_region_name, false);
1247 DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture bufpos %5 start @ %2 length %3 add new region %4\n",
1248 _name, (*ci)->start, (*ci)->samples, region_name, buffer_position));
1254 plist.add (Properties::start, buffer_position);
1255 plist.add (Properties::length, (*ci)->samples);
1256 plist.add (Properties::name, region_name);
1258 boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1259 region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1260 if (preroll_off > 0) {
1261 region->trim_front (buffer_position + preroll_off);
1265 catch (failed_constructor& err) {
1266 error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1267 continue; /* XXX is this OK? */
1270 pl->add_region (region, (*ci)->start + preroll_off, 1, _disk_writer->non_layered());
1271 pl->set_layer (region, DBL_MAX);
1273 buffer_position += (*ci)->samples;
1277 pl->set_capture_insertion_in_progress (false);
1278 _session.add_command (new StatefulDiffCommand (pl));