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