1 /*
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>
8  *
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.
13  *
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.
18  *
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.
22  */
23 #include "pbd/error.h"
24 
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"
55 
56 #include "pbd/i18n.h"
57 
58 using namespace std;
59 using namespace ARDOUR;
60 using namespace PBD;
61 
Track(Session & sess,string name,PresentationInfo::Flag flag,TrackMode mode,DataType default_type)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)
65 	, _mode (mode)
66 	, _alignment_choice (Automatic)
67 	, _pending_name_change (false)
68 {
69 	_freeze_record.state = NoFreeze;
70 }
71 
~Track()72 Track::~Track ()
73 {
74 	DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
75 
76 	if (_disk_reader) {
77 		_disk_reader.reset ();
78 	}
79 
80 	if (_disk_writer) {
81 		_disk_writer.reset ();
82 	}
83 }
84 
85 int
init()86 Track::init ()
87 {
88 	if (Route::init ()) {
89 		return -1;
90 	}
91 
92 	DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
93 
94 	_disk_reader.reset (new DiskReader (_session, *this, name(), dflags));
95 	_disk_reader->set_block_size (_session.get_block_size ());
96 	_disk_reader->set_owner (this);
97 
98 	_disk_writer.reset (new DiskWriter (_session, *this, name(), dflags));
99 	_disk_writer->set_block_size (_session.get_block_size ());
100 	_disk_writer->set_owner (this);
101 
102 	set_align_choice_from_io ();
103 
104 	boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
105 	boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
106 
107 	_record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
108 	add_control (_record_enable_control);
109 
110 	_record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
111 	add_control (_record_safe_control);
112 
113 	_monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
114 	add_control (_monitoring_control);
115 
116 	if (!name().empty()) {
117 		/* an empty name means that we are being constructed via
118 		 * serialized state (XML). Don't create a playlist, because one
119 		 * will be created or discovered during ::set_state().
120 		 */
121 		use_new_playlist (data_type());
122 		/* set disk-I/O and diskstream name */
123 		set_name (name ());
124 	}
125 
126 	_session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
127 
128 	_monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
129 	_record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
130 	_record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
131 
132 	_input->changed.connect_same_thread (*this, boost::bind (&Track::input_changed, this));
133 
134 	_disk_reader->ConfigurationChanged.connect_same_thread (*this, boost::bind (&Track::chan_count_changed, this));
135 
136 	return 0;
137 }
138 
139 void
input_changed()140 Track::input_changed ()
141 {
142 	if (_disk_writer && _alignment_choice == Automatic) {
143 		set_align_choice_from_io ();
144 	}
145 }
146 
147 void
chan_count_changed()148 Track::chan_count_changed ()
149 {
150 	ChanCountChanged (); /* EMIT SIGNAL */
151 }
152 
153 XMLNode&
state(bool save_template)154 Track::state (bool save_template)
155 {
156 	XMLNode& root (Route::state (save_template));
157 
158 	if (_playlists[DataType::AUDIO]) {
159 		root.set_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
160 	}
161 
162 	if (_playlists[DataType::MIDI]) {
163 		root.set_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
164 	}
165 
166 	root.add_child_nocopy (_monitoring_control->get_state ());
167 	root.add_child_nocopy (_record_safe_control->get_state ());
168 	root.add_child_nocopy (_record_enable_control->get_state ());
169 
170 	root.set_property (X_("saved-meter-point"), _saved_meter_point);
171 	root.set_property (X_("alignment-choice"), _alignment_choice);
172 
173 	return root;
174 }
175 
176 int
set_state(const XMLNode & node,int version)177 Track::set_state (const XMLNode& node, int version)
178 {
179 	if (Route::set_state (node, version)) {
180 		return -1;
181 	}
182 
183 	if (version >= 3000 && version < 6000) {
184 		if (XMLNode* ds_node = find_named_node (node, "Diskstream")) {
185 			std::string name;
186 			if (ds_node->get_property ("playlist", name)) {
187 
188 				ds_node->set_property ("active", true);
189 
190 				_disk_writer->set_state (*ds_node, version);
191 				_disk_reader->set_state (*ds_node, version);
192 
193 				AlignChoice ac;
194 				if (ds_node->get_property (X_("capture-alignment"), ac)) {
195 					set_align_choice (ac, true);
196 				}
197 
198 				if (boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlists()->by_name (name))) {
199 					use_playlist (DataType::AUDIO, pl);
200 				}
201 
202 				if (boost::shared_ptr<MidiPlaylist> pl = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlists()->by_name (name))) {
203 					use_playlist (DataType::MIDI, pl);
204 				}
205 			}
206 		}
207 	}
208 
209 	XMLNode* child;
210 	std::string playlist_id;
211 
212 	if (node.get_property (X_("audio-playlist"), playlist_id)) {
213 		find_and_use_playlist (DataType::AUDIO, PBD::ID (playlist_id));
214 	}
215 
216 	if (node.get_property (X_("midi-playlist"), playlist_id)) {
217 		find_and_use_playlist (DataType::MIDI, PBD::ID (playlist_id));
218 	}
219 
220 	XMLNodeList nlist = node.children();
221 	for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
222 		child = *niter;
223 
224 		if (child->name() == Controllable::xml_node_name) {
225 			std::string name;
226 			if (!child->get_property ("name", name)) {
227 				continue;
228 			}
229 
230 			if (name == _record_enable_control->name()) {
231 				_record_enable_control->set_state (*child, version);
232 			} else if (name == _record_safe_control->name()) {
233 				_record_safe_control->set_state (*child, version);
234 			} else if (name == _monitoring_control->name()) {
235 				_monitoring_control->set_state (*child, version);
236 			}
237 		}
238 	}
239 
240 	if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
241 		_saved_meter_point = _meter_point;
242 	}
243 
244 
245 	AlignChoice ac;
246 
247 	if (node.get_property (X_("alignment-choice"), ac)) {
248 		set_align_choice (ac, true);
249 	}
250 
251 	return 0;
252 }
253 
~FreezeRecord()254 Track::FreezeRecord::~FreezeRecord ()
255 {
256 	for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
257 		delete *i;
258 	}
259 }
260 
261 Track::FreezeState
freeze_state() const262 Track::freeze_state() const
263 {
264 	return _freeze_record.state;
265 }
266 
267 bool
declick_in_progress() const268 Track::declick_in_progress () const
269 {
270 	return active() && _disk_reader->declick_in_progress ();
271 }
272 
273 bool
can_record()274 Track::can_record()
275 {
276 	bool will_record = true;
277 	for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
278 		if (!i->connected())
279 			will_record = false;
280 	}
281 
282 	return will_record;
283 }
284 
285 int
prep_record_enabled(bool yn)286 Track::prep_record_enabled (bool yn)
287 {
288 	if (yn && _record_safe_control->get_value()) {
289 		return -1;
290 	}
291 
292 	if (!can_be_record_enabled()) {
293 		return -1;
294 	}
295 
296 	/* keep track of the meter point as it was before we rec-enabled */
297 	if (!_disk_writer->record_enabled()) {
298 		_saved_meter_point = _meter_point;
299 	}
300 
301 	bool will_follow;
302 
303 	if (yn) {
304 		will_follow = _disk_writer->prep_record_enable ();
305 	} else {
306 		will_follow = _disk_writer->prep_record_disable ();
307 	}
308 
309 	if (will_follow) {
310 		if (yn) {
311 			if (_meter_point != MeterCustom) {
312 				set_meter_point (MeterInput);
313 			}
314 		} else {
315 			set_meter_point (_saved_meter_point);
316 		}
317 	}
318 
319 	return 0;
320 }
321 
322 void
record_enable_changed(bool,Controllable::GroupControlDisposition)323 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
324 {
325 	_disk_writer->set_record_enabled (_record_enable_control->get_value());
326 }
327 
328 void
record_safe_changed(bool,Controllable::GroupControlDisposition)329 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
330 {
331 	_disk_writer->set_record_safe (_record_safe_control->get_value());
332 }
333 
334 bool
can_be_record_safe()335 Track::can_be_record_safe ()
336 {
337 	return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
338 }
339 
340 bool
can_be_record_enabled()341 Track::can_be_record_enabled ()
342 {
343 	return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
344 }
345 
346 void
parameter_changed(string const & p)347 Track::parameter_changed (string const & p)
348 {
349 	if (p == "track-name-number") {
350 		resync_take_name ();
351 	}
352 	else if (p == "track-name-take") {
353 		resync_take_name ();
354 	}
355 	else if (p == "take-name") {
356 		if (_session.config.get_track_name_take()) {
357 			resync_take_name ();
358 		}
359 	}
360 }
361 
362 int
resync_take_name(std::string n)363 Track::resync_take_name (std::string n)
364 {
365 	if (n.empty ()) {
366 		n = name ();
367 	}
368 
369 	if (_record_enable_control->get_value() && _session.actively_recording ()) {
370 		_pending_name_change = true;
371 		return -1;
372 	}
373 
374 	string diskstream_name = "";
375 	if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
376 		// Note: any text is fine, legalize_for_path() fixes this later
377 		diskstream_name += _session.config.get_take_name ();
378 		diskstream_name += "_";
379 	}
380 	const int64_t tracknumber = track_number();
381 	if (tracknumber > 0 && _session.config.get_track_name_number()) {
382 		char num[64], fmt[10];
383 		snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
384 		snprintf(num, sizeof(num), fmt, tracknumber);
385 		diskstream_name += num;
386 		diskstream_name += "_";
387 	}
388 
389 	diskstream_name += n;
390 
391 	if (diskstream_name == _diskstream_name) {
392 		return 1;
393 	}
394 
395 	_diskstream_name = diskstream_name;
396 	_disk_writer->set_write_source_name (diskstream_name);
397 	return 0;
398 }
399 
400 bool
set_name(const string & str)401 Track::set_name (const string& str)
402 {
403 	if (str.empty ()) {
404 		return false;
405 	}
406 
407 	switch (resync_take_name (str)) {
408 		case -1:
409 			return false;
410 		case 1:
411 			return true;
412 		default:
413 			break;
414 	}
415 
416 	boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
417 
418 	if (_playlists[data_type()]) {
419 		if (_playlists[data_type()]->all_regions_empty () && _session.playlists()->playlists_for_track (me).size() == 1) {
420 			/* Only rename the diskstream (and therefore the playlist) if
421 			   a) the playlist has never had a region added to it and
422 			   b) there is only one playlist for this track.
423 
424 			   If (a) is not followed, people can get confused if, say,
425 			   they have notes about a playlist with a given name and then
426 			   it changes (see mantis #4759).
427 
428 			   If (b) is not followed, we rename the current playlist and not
429 			   the other ones, which is a bit confusing (see mantis #4977).
430 			*/
431 			_disk_reader->set_name (str);
432 			_disk_writer->set_name (str);
433 		}
434 	}
435 
436 	/* When creating a track during session-load, do not change playlist's name.
437 	 *
438 	 * Changing the playlist name from 'toBeResetFroXML' breaks loading
439 	 * Ardour v2..5 sessions. Older versions of Arodur identified playlist
440 	 * by name, and this causes duplicate names and name conflicts.
441 	 * (new track name -> new playlist name  != old playlist)
442 	 */
443 	if (_session.loading ()) {
444 		return Route::set_name (str);
445 	}
446 
447 	for (uint32_t n = 0; n < DataType::num_types; ++n) {
448 		if (_playlists[n]) {
449 			_playlists[n]->set_name (str);
450 		}
451 	}
452 
453 	return Route::set_name (str);
454 }
455 
456 boost::shared_ptr<Playlist>
playlist()457 Track::playlist ()
458 {
459 	return _playlists[data_type()];
460 }
461 
462 void
request_input_monitoring(bool m)463 Track::request_input_monitoring (bool m)
464 {
465 	for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
466 		AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
467 	}
468 }
469 
470 void
ensure_input_monitoring(bool m)471 Track::ensure_input_monitoring (bool m)
472 {
473 	for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
474 		AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
475 	}
476 }
477 
478 list<boost::shared_ptr<Source> > &
last_capture_sources()479 Track::last_capture_sources ()
480 {
481 	return _disk_writer->last_capture_sources ();
482 }
483 
484 std::string
steal_write_source_name()485 Track::steal_write_source_name()
486 {
487         return _disk_writer->steal_write_source_name ();
488 }
489 
490 void
reset_write_sources(bool r,bool force)491 Track::reset_write_sources (bool r, bool force)
492 {
493 	_disk_writer->reset_write_sources (r, force);
494 }
495 
496 float
playback_buffer_load() const497 Track::playback_buffer_load () const
498 {
499 	return _disk_reader->buffer_load ();
500 }
501 
502 float
capture_buffer_load() const503 Track::capture_buffer_load () const
504 {
505 	return _disk_writer->buffer_load ();
506 }
507 
508 int
do_refill()509 Track::do_refill ()
510 {
511 	return _disk_reader->do_refill ();
512 }
513 
514 int
do_flush(RunContext c,bool force)515 Track::do_flush (RunContext c, bool force)
516 {
517 	return _disk_writer->do_flush (c, force);
518 }
519 
520 void
set_pending_overwrite(OverwriteReason why)521 Track::set_pending_overwrite (OverwriteReason why)
522 {
523 	_disk_reader->set_pending_overwrite (why);
524 }
525 
526 int
seek(samplepos_t p,bool complete_refill)527 Track::seek (samplepos_t p, bool complete_refill)
528 {
529 	if (_disk_reader->seek (p, complete_refill)) {
530 		return -1;
531 	}
532 	return _disk_writer->seek (p, complete_refill);
533 }
534 
535 bool
can_internal_playback_seek(samplecnt_t p)536 Track::can_internal_playback_seek (samplecnt_t p)
537 {
538 	return _disk_reader->can_internal_playback_seek (p);
539 }
540 
541 void
internal_playback_seek(samplecnt_t p)542 Track::internal_playback_seek (samplecnt_t p)
543 {
544 	return _disk_reader->internal_playback_seek (p);
545 }
546 
547 void
non_realtime_locate(samplepos_t p)548 Track::non_realtime_locate (samplepos_t p)
549 {
550 	Route::non_realtime_locate (p);
551 }
552 
553 bool
overwrite_existing_buffers()554 Track::overwrite_existing_buffers ()
555 {
556 	return _disk_reader->overwrite_existing_buffers ();
557 }
558 
559 samplecnt_t
get_captured_samples(uint32_t n) const560 Track::get_captured_samples (uint32_t n) const
561 {
562 	return _disk_writer->get_captured_samples (n);
563 }
564 
565 void
transport_looped(samplepos_t p)566 Track::transport_looped (samplepos_t p)
567 {
568 	return _disk_writer->transport_looped (p);
569 }
570 
571 void
transport_stopped_wallclock(struct tm & n,time_t t,bool g)572 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
573 {
574 	_disk_writer->transport_stopped_wallclock (n, t, g);
575 
576 	if (_pending_name_change) {
577 		resync_take_name ();
578 		_pending_name_change = false;
579 	}
580 }
581 
582 void
mark_capture_xrun()583 Track::mark_capture_xrun ()
584 {
585 	if (_disk_writer->record_enabled ()) {
586 		_disk_writer->mark_capture_xrun ();
587 	}
588 }
589 
590 bool
pending_overwrite() const591 Track::pending_overwrite () const
592 {
593 	return _disk_reader->pending_overwrite ();
594 }
595 
596 void
set_slaved(bool s)597 Track::set_slaved (bool s)
598 {
599 	_disk_reader->set_slaved (s);
600 	_disk_writer->set_slaved (s);
601 }
602 
603 ChanCount
n_channels()604 Track::n_channels ()
605 {
606 	return _disk_reader->output_streams();
607 }
608 
609 samplepos_t
get_capture_start_sample(uint32_t n) const610 Track::get_capture_start_sample (uint32_t n) const
611 {
612 	return _disk_writer->get_capture_start_sample (n);
613 }
614 
615 AlignStyle
alignment_style() const616 Track::alignment_style () const
617 {
618 	return _disk_writer->alignment_style ();
619 }
620 
621 AlignChoice
alignment_choice() const622 Track::alignment_choice () const
623 {
624 	return _alignment_choice;
625 }
626 
627 samplepos_t
current_capture_start() const628 Track::current_capture_start () const
629 {
630 	return _disk_writer->current_capture_start ();
631 }
632 
633 samplepos_t
current_capture_end() const634 Track::current_capture_end () const
635 {
636 	return _disk_writer->current_capture_end ();
637 }
638 
639 void
playlist_modified()640 Track::playlist_modified ()
641 {
642 	_disk_reader->playlist_modified ();
643 }
644 
645 int
find_and_use_playlist(DataType dt,PBD::ID const & id)646 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
647 {
648 	boost::shared_ptr<Playlist> playlist;
649 
650 	if ((playlist = _session.playlists()->by_id (id)) == 0) {
651 		return -1;
652 	}
653 
654 	if (!playlist) {
655 		error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
656 		return -1;
657 	}
658 
659 	return use_playlist (dt, playlist);
660 }
661 
662 int
use_playlist(DataType dt,boost::shared_ptr<Playlist> p,bool set_orig)663 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p, bool set_orig)
664 {
665 	int ret;
666 
667 	if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
668 		if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
669 			if (set_orig) {
670 				p->set_orig_track_id (id());
671 			}
672 		}
673 	}
674 
675 	boost::shared_ptr<Playlist> old = _playlists[dt];
676 
677 	if (ret == 0) {
678 		_playlists[dt] = p;
679 	}
680 
681 	if (old) {
682 		boost::shared_ptr<RegionList> rl (new RegionList (old->region_list_property ().rlist ()));
683 		if (rl->size () > 0) {
684 			Region::RegionsPropertyChanged (rl, Properties::hidden);
685 		}
686 	}
687 	if (p) {
688 		boost::shared_ptr<RegionList> rl (new RegionList (p->region_list_property ().rlist ()));
689 		if (rl->size () > 0) {
690 			Region::RegionsPropertyChanged (rl, Properties::hidden);
691 		}
692 	}
693 
694 	_session.set_dirty ();
695 	PlaylistChanged (); /* EMIT SIGNAL */
696 
697 	return ret;
698 }
699 
700 int
use_copy_playlist()701 Track::use_copy_playlist ()
702 {
703 	assert (_playlists[data_type()]);
704 
705 	if (_playlists[data_type()] == 0) {
706 		error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
707 		return -1;
708 	}
709 
710 	string newname;
711 	boost::shared_ptr<Playlist> playlist;
712 
713 	newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
714 
715 	if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
716 		return -1;
717 	}
718 
719 	playlist->reset_shares();
720 
721 	int rv = use_playlist (data_type(), playlist);
722 	PlaylistAdded (); /* EMIT SIGNAL */
723 	return rv;
724 }
725 
726 int
use_new_playlist(DataType dt)727 Track::use_new_playlist (DataType dt)
728 {
729 	string newname;
730 	boost::shared_ptr<Playlist> playlist = _playlists[dt];
731 
732 	if (playlist) {
733 		newname = Playlist::bump_name (playlist->name(), _session);
734 	} else {
735 		newname = Playlist::bump_name (_name, _session);
736 	}
737 
738 	playlist = PlaylistFactory::create (dt, _session, newname, is_private_route());
739 
740 	if (!playlist) {
741 		return -1;
742 	}
743 
744 	int rv = use_playlist (dt, playlist);
745 	PlaylistAdded (); /* EMIT SIGNAL */
746 	return rv;
747 }
748 
749 void
set_align_choice(AlignChoice ac,bool force)750 Track::set_align_choice (AlignChoice ac, bool force)
751 {
752 	_alignment_choice = ac;
753 	switch (ac) {
754 		case Automatic:
755 			set_align_choice_from_io ();
756 			break;
757 		case UseCaptureTime:
758 			_disk_writer->set_align_style (CaptureTime, force);
759 			break;
760 		case UseExistingMaterial:
761 			_disk_writer->set_align_style (ExistingMaterial, force);
762 			break;
763 	}
764 }
765 
766 void
set_align_style(AlignStyle s,bool force)767 Track::set_align_style (AlignStyle s, bool force)
768 {
769 	_disk_writer->set_align_style (s, force);
770 }
771 
772 void
set_align_choice_from_io()773 Track::set_align_choice_from_io ()
774 {
775 	bool have_physical = false;
776 
777 	if (_input) {
778 		uint32_t n = 0;
779 		boost::shared_ptr<Port> p;
780 
781 		while (0 != (p = _input->nth (n++))) {
782 			/* In case of JACK all ports not owned by Ardour may be re-sampled,
783 			 * and latency is added. External JACK ports need to be treated
784 			 * like physical ports: I/O latency needs to be taken into account.
785 			 *
786 			 * When not using JACK, all external ports are physical ports
787 			 * so this is a NO-OP for other backends.
788 			 */
789 			if (p->externally_connected () || p->physically_connected ()) {
790 				have_physical = true;
791 				break;
792 			}
793 		}
794 	}
795 
796 #ifdef MIXBUS
797 	// compensate for latency when bouncing from master or mixbus.
798 	// we need to use "ExistingMaterial" to pick up the master bus' latency
799 	// see also Route::direct_feeds_according_to_reality
800 	IOVector ios;
801 	ios.push_back (_input);
802 	if (_session.master_out() && ios.fed_by (_session.master_out()->output())) {
803 		have_physical = true;
804 	}
805 	for (uint32_t n = 0; n < NUM_MIXBUSES && !have_physical; ++n) {
806 		if (_session.get_mixbus (n) && ios.fed_by (_session.get_mixbus(n)->output())) {
807 			have_physical = true;
808 		}
809 	}
810 #endif
811 
812 	if (have_physical) {
813 		_disk_writer->set_align_style (ExistingMaterial);
814 	} else {
815 		_disk_writer->set_align_style (CaptureTime);
816 	}
817 }
818 
819 void
set_block_size(pframes_t n)820 Track::set_block_size (pframes_t n)
821 {
822 	Route::set_block_size (n);
823 	_disk_reader->set_block_size (n);
824 	_disk_writer->set_block_size (n);
825 }
826 
827 void
adjust_playback_buffering()828 Track::adjust_playback_buffering ()
829 {
830         if (_disk_reader) {
831                 _disk_reader->adjust_buffering ();
832         }
833 }
834 
835 void
adjust_capture_buffering()836 Track::adjust_capture_buffering ()
837 {
838         if (_disk_writer) {
839                 _disk_writer->adjust_buffering ();
840         }
841 }
842 
843 void
monitoring_changed(bool,Controllable::GroupControlDisposition)844 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
845 {
846 	for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
847 		(*i)->monitoring_changed ();
848 	}
849 }
850 
851 bool
set_processor_state(XMLNode const & node,int version,XMLProperty const * prop,ProcessorList & new_order,bool & must_configure)852 Track::set_processor_state (XMLNode const& node, int version, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
853 {
854 	if (Route::set_processor_state (node, version, prop, new_order, must_configure)) {
855 		return true;
856 	}
857 
858 	cerr << name() << " looking for state for track procs, DR = " << _disk_reader << endl;
859 
860 	if (prop->value() == "diskreader") {
861 		if (_disk_reader) {
862 			_disk_reader->set_state (node, version);
863 			new_order.push_back (_disk_reader);
864 			return true;
865 		}
866 	} else if (prop->value() == "diskwriter") {
867 		if (_disk_writer) {
868 			_disk_writer->set_state (node, version);
869 			new_order.push_back (_disk_writer);
870 			return true;
871 		}
872 	}
873 
874 	error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
875 	return false;
876 }
877 
878 void
use_captured_sources(SourceList & srcs,CaptureInfos const & capture_info)879 Track::use_captured_sources (SourceList& srcs, CaptureInfos const & capture_info)
880 {
881 	if (srcs.empty()) {
882 		return;
883 	}
884 
885 	boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
886 	boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
887 
888 	if (afs) {
889 		use_captured_audio_sources (srcs, capture_info);
890 	}
891 
892 	if (mfs) {
893 		use_captured_midi_sources (srcs, capture_info);
894 	}
895 }
896 
897 void
use_captured_midi_sources(SourceList & srcs,CaptureInfos const & capture_info)898 Track::use_captured_midi_sources (SourceList& srcs, CaptureInfos const & capture_info)
899 {
900 	if (srcs.empty() || data_type() != DataType::MIDI) {
901 		return;
902 	}
903 
904 	boost::shared_ptr<SMFSource> mfs = boost::dynamic_pointer_cast<SMFSource> (srcs.front());
905 	boost::shared_ptr<Playlist> pl = _playlists[DataType::MIDI];
906 	boost::shared_ptr<MidiRegion> midi_region;
907 	CaptureInfos::const_iterator ci;
908 
909 	if (!mfs || !pl) {
910 		return;
911 	}
912 
913 	samplecnt_t total_capture = 0;
914 
915 	for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
916 		total_capture += (*ci)->samples;
917 	}
918 
919 	/* we will want to be able to keep (over)writing the source
920 	   but we don't want it to be removable. this also differs
921 	   from the audio situation, where the source at this point
922 	   must be considered immutable. luckily, we can rely on
923 	   MidiSource::mark_streaming_write_completed() to have
924 	   already done the necessary work for that.
925 	*/
926 
927 	string whole_file_region_name;
928 	whole_file_region_name = region_name_from_path (mfs->name(), true);
929 
930 	/* Register a new region with the Session that
931 	   describes the entire source. Do this first
932 	   so that any sub-regions will obviously be
933 	   children of this one (later!)
934 	*/
935 
936 	try {
937 		PropertyList plist;
938 
939 		plist.add (Properties::name, whole_file_region_name);
940 		plist.add (Properties::whole_file, true);
941 		plist.add (Properties::automatic, true);
942 		plist.add (Properties::start, 0);
943 		plist.add (Properties::length, total_capture);
944 		plist.add (Properties::layer, 0);
945 
946 		boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
947 
948 		midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
949 		midi_region->special_set_position (capture_info.front()->start);
950 	}
951 
952 	catch (failed_constructor& err) {
953 		error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg;
954 		/* XXX what now? */
955 	}
956 
957 	pl->clear_changes ();
958 	pl->freeze ();
959 
960 	/* Session sample time of the initial capture in this pass, which is where the source starts */
961 	samplepos_t initial_capture = 0;
962 	if (!capture_info.empty()) {
963 		initial_capture = capture_info.front()->start;
964 	}
965 
966 	BeatsSamplesConverter converter (_session.tempo_map(), capture_info.front()->start);
967 	const samplepos_t preroll_off = _session.preroll_record_trim_len ();
968 
969 	for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
970 
971 		string region_name;
972 
973 		RegionFactory::region_name (region_name, mfs->name(), false);
974 
975 		DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1 capture start @ %2 length %3 add new region %4\n",
976 		                                                      _name, (*ci)->start, (*ci)->samples, region_name));
977 
978 
979 		// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->samples << " start: " << (*ci)->loop_offset << " add MIDI region\n";
980 
981 		try {
982 			PropertyList plist;
983 
984 			/* start of this region is the offset between the start of its capture and the start of the whole pass */
985 			samplecnt_t start_off = (*ci)->start - initial_capture + (*ci)->loop_offset;
986 			plist.add (Properties::start, start_off);
987 			plist.add (Properties::length, (*ci)->samples);
988 			plist.add (Properties::length_beats, converter.from((*ci)->samples).to_double());
989 			plist.add (Properties::start_beats, converter.from(start_off).to_double());
990 			plist.add (Properties::name, region_name);
991 
992 			boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
993 			midi_region = boost::dynamic_pointer_cast<MidiRegion> (rx);
994 			if (preroll_off > 0) {
995 				midi_region->trim_front ((*ci)->start - initial_capture + preroll_off);
996 			}
997 		}
998 
999 		catch (failed_constructor& err) {
1000 			error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
1001 			continue; /* XXX is this OK? */
1002 		}
1003 
1004 		cerr << "add new region, len = " << (*ci)->samples << " @ " << (*ci)->start << endl;
1005 
1006 		pl->add_region (midi_region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode ());
1007 	}
1008 
1009 	pl->thaw ();
1010 	_session.add_command (new StatefulDiffCommand (pl));
1011 }
1012 
1013 void
use_captured_audio_sources(SourceList & srcs,CaptureInfos const & capture_info)1014 Track::use_captured_audio_sources (SourceList& srcs, CaptureInfos const & capture_info)
1015 {
1016 	if (srcs.empty() || data_type() != DataType::AUDIO) {
1017 		return;
1018 	}
1019 
1020 	boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (srcs.front());
1021 	boost::shared_ptr<Playlist> pl = _playlists[DataType::AUDIO];
1022 	boost::shared_ptr<AudioRegion> region;
1023 
1024 	if (!afs || !pl) {
1025 		return;
1026 	}
1027 
1028 	string whole_file_region_name;
1029 	whole_file_region_name = region_name_from_path (afs->name(), true);
1030 
1031 	/* Register a new region with the Session that
1032 	   describes the entire source. Do this first
1033 	   so that any sub-regions will obviously be
1034 	   children of this one (later!)
1035 	*/
1036 
1037 	try {
1038 		PropertyList plist;
1039 
1040 		plist.add (Properties::start, afs->last_capture_start_sample());
1041 		plist.add (Properties::length, afs->length(0));
1042 		plist.add (Properties::name, whole_file_region_name);
1043 		boost::shared_ptr<Region> rx (RegionFactory::create (srcs, plist));
1044 		rx->set_automatic (true);
1045 		rx->set_whole_file (true);
1046 
1047 		region = boost::dynamic_pointer_cast<AudioRegion> (rx);
1048 		region->special_set_position (afs->natural_position());
1049 	}
1050 
1051 
1052 	catch (failed_constructor& err) {
1053 		error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
1054 		/* XXX what now? */
1055 	}
1056 
1057 	/* If this playlist doesn't already have a pgroup (a new track won't) then
1058 	 * assign it one, using the take-id of the first recording)
1059 	 */
1060 	if (pl->pgroup_id().length() == 0) {
1061 		pl->set_pgroup_id (afs->take_id ());
1062 	}
1063 
1064 	pl->clear_changes ();
1065 	pl->set_capture_insertion_in_progress (true);
1066 	pl->freeze ();
1067 
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;
1071 
1072 	for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
1073 
1074 		string region_name;
1075 
1076 		RegionFactory::region_name (region_name, whole_file_region_name, false);
1077 
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));
1080 
1081 		try {
1082 
1083 			PropertyList plist;
1084 
1085 			plist.add (Properties::start, buffer_position);
1086 			plist.add (Properties::length, (*ci)->samples);
1087 			plist.add (Properties::name, region_name);
1088 
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);
1093 			}
1094 		}
1095 
1096 		catch (failed_constructor& err) {
1097 			error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
1098 			continue; /* XXX is this OK? */
1099 		}
1100 
1101 		pl->add_region (region, (*ci)->start + preroll_off, 1, _session.config.get_layered_record_mode());
1102 		pl->set_layer (region, DBL_MAX);
1103 
1104 		buffer_position += (*ci)->samples;
1105 	}
1106 
1107 	pl->thaw ();
1108 	pl->set_capture_insertion_in_progress (false);
1109 	_session.add_command (new StatefulDiffCommand (pl));
1110 }
1111