backend check for rec-safe (only allow to lock if not armed)
[ardour.git] / libs / ardour / track.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3
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.
8
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.
13
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.
17 */
18 #include "pbd/error.h"
19
20 #include "ardour/amp.h"
21 #include "ardour/debug.h"
22 #include "ardour/delivery.h"
23 #include "ardour/diskstream.h"
24 #include "ardour/io_processor.h"
25 #include "ardour/meter.h"
26 #include "ardour/playlist.h"
27 #include "ardour/port.h"
28 #include "ardour/processor.h"
29 #include "ardour/route_group_specialized.h"
30 #include "ardour/session.h"
31 #include "ardour/session_playlists.h"
32 #include "ardour/track.h"
33 #include "ardour/utils.h"
34
35 #include "i18n.h"
36
37 using namespace std;
38 using namespace ARDOUR;
39 using namespace PBD;
40
41 Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
42         : Route (sess, name, flag, default_type)
43         , _saved_meter_point (_meter_point)
44         , _mode (mode)
45         , _monitoring (MonitorAuto)
46 {
47         _freeze_record.state = NoFreeze;
48         _declickable = true;
49 }
50
51 Track::~Track ()
52 {
53         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
54 }
55
56 int
57 Track::init ()
58 {
59         if (Route::init ()) {
60                 return -1;
61         }
62
63         boost::shared_ptr<Route> rp (shared_from_this());
64         boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
65         _rec_enable_control = boost::shared_ptr<RecEnableControl> (new RecEnableControl(rt));
66         _rec_enable_control->set_flags (Controllable::Toggle);
67         _monitoring_control.reset (new MonitoringControllable (X_("monitoring"), rt));
68
69         /* don't add rec_enable_control to controls because we don't want it to
70          * appear as an automatable parameter
71          */
72         track_number_changed.connect_same_thread (*this, boost::bind (&Track::resync_track_name, this));
73         _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
74
75         return 0;
76 }
77
78 void
79 Track::use_new_diskstream ()
80 {
81         boost::shared_ptr<Diskstream> ds = create_diskstream ();
82
83         ds->do_refill_with_alloc ();
84         ds->set_block_size (_session.get_block_size ());
85         ds->playlist()->set_orig_track_id (id());
86
87         set_diskstream (ds);
88 }
89
90 XMLNode&
91 Track::get_state ()
92 {
93         return state (true);
94 }
95
96 XMLNode&
97 Track::state (bool full)
98 {
99         XMLNode& root (Route::state (full));
100         root.add_property (X_("monitoring"), enum_2_string (_monitoring));
101         root.add_property (X_("saved-meter-point"), enum_2_string (_saved_meter_point));
102         root.add_child_nocopy (_rec_enable_control->get_state());
103         root.add_child_nocopy (_diskstream->get_state ());
104
105         return root;
106 }
107
108 int
109 Track::set_state (const XMLNode& node, int version)
110 {
111         if (Route::set_state (node, version)) {
112                 return -1;
113         }
114
115         XMLNode* child;
116
117         if (version >= 3000) {
118                 if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
119                         boost::shared_ptr<Diskstream> ds = diskstream_factory (*child);
120                         ds->do_refill_with_alloc ();
121                         set_diskstream (ds);
122                 }
123         }
124
125         if (_diskstream) {
126                 _diskstream->playlist()->set_orig_track_id (id());
127         }
128
129         /* set rec-enable control *AFTER* setting up diskstream, because it may
130            want to operate on the diskstream as it sets its own state
131         */
132
133         XMLNodeList nlist = node.children();
134         for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
135                 child = *niter;
136
137                 XMLProperty const * prop;
138                 if (child->name() == Controllable::xml_node_name && (prop = child->property ("name")) != 0) {
139                         if (prop->value() == X_("recenable")) {
140                                 _rec_enable_control->set_state (*child, version);
141                         }
142                 }
143         }
144
145         XMLProperty const * prop;
146
147         if ((prop = node.property (X_("monitoring"))) != 0) {
148                 _monitoring = MonitorChoice (string_2_enum (prop->value(), _monitoring));
149         } else {
150                 _monitoring = MonitorAuto;
151         }
152
153         if ((prop = node.property (X_("saved-meter-point"))) != 0) {
154                 _saved_meter_point = MeterPoint (string_2_enum (prop->value(), _saved_meter_point));
155         } else {
156                 _saved_meter_point = _meter_point;
157         }
158
159         return 0;
160 }
161
162 XMLNode&
163 Track::get_template ()
164 {
165         return state (false);
166 }
167
168 Track::FreezeRecord::~FreezeRecord ()
169 {
170         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
171                 delete *i;
172         }
173 }
174
175 Track::FreezeState
176 Track::freeze_state() const
177 {
178         return _freeze_record.state;
179 }
180
181 Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t)
182         : AutomationControl (t->session(),
183                              RecEnableAutomation,
184                              ParameterDescriptor(Evoral::Parameter(RecEnableAutomation)),
185                              boost::shared_ptr<AutomationList>(),
186                              X_("recenable"))
187         , track (t)
188 {
189         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(RecEnableAutomation)));
190         set_list (gl);
191 }
192
193 void
194 Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition group_override)
195 {
196         if (writable()) {
197                 _set_value (val, group_override);
198         }
199 }
200
201 void
202 Track::RecEnableControl::set_value_unchecked (double val)
203 {
204         if (writable()) {
205                 _set_value (val, Controllable::NoGroup);
206         }
207 }
208
209 void
210 Track::RecEnableControl::_set_value (double val, Controllable::GroupControlDisposition group_override)
211 {
212         boost::shared_ptr<Track> t = track.lock ();
213         if (!t) {
214                 return;
215         }
216
217         t->set_record_enabled (val >= 0.5 ? true : false, group_override);
218 }
219
220 double
221 Track::RecEnableControl::get_value () const
222 {
223         boost::shared_ptr<Track> t = track.lock ();
224         if (!t) {
225                 return 0;
226         }
227
228         return (t->record_enabled() ? 1.0 : 0.0);
229 }
230
231 bool
232 Track::record_enabled () const
233 {
234         return _diskstream && _diskstream->record_enabled ();
235 }
236
237 bool
238 Track::can_record()
239 {
240         bool will_record = true;
241         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
242                 if (!i->connected())
243                         will_record = false;
244         }
245
246         return will_record;
247 }
248
249 void
250 Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
251 {
252         if (yn && record_safe ()) {
253             return;
254         }
255
256         if (!_session.writable()) {
257                 return;
258         }
259
260         if (_freeze_record.state == Frozen) {
261                 return;
262         }
263
264         if (use_group (group_override, &RouteGroup::is_recenable)) {
265                 _route_group->apply (&Track::prep_record_enabled, yn, Controllable::NoGroup);
266                 return;
267         }
268
269         /* keep track of the meter point as it was before we rec-enabled */
270         if (!_diskstream->record_enabled()) {
271                 _saved_meter_point = _meter_point;
272         }
273
274         bool will_follow;
275
276         if (yn) {
277                 will_follow = _diskstream->prep_record_enable ();
278         } else {
279                 will_follow = _diskstream->prep_record_disable ();
280         }
281
282         if (will_follow) {
283                 if (yn) {
284                         if (_meter_point != MeterCustom) {
285                                 set_meter_point (MeterInput);
286                         }
287                 } else {
288                         set_meter_point (_saved_meter_point);
289                 }
290         }
291 }
292
293 void
294 Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
295 {
296         if (_diskstream->record_safe ()) {
297             return;
298         }
299
300         if (!_session.writable()) {
301                 return;
302         }
303
304         if (_freeze_record.state == Frozen) {
305                 return;
306         }
307
308         if (use_group (group_override, &RouteGroup::is_recenable)) {
309                 _route_group->apply (&Track::set_record_enabled, yn, Controllable::NoGroup);
310                 return;
311         }
312
313         _diskstream->set_record_enabled (yn);
314
315         _rec_enable_control->Changed ();
316 }
317
318 bool
319 Track::record_safe () const
320 {
321         return _diskstream && _diskstream->record_safe ();
322 }
323
324 void
325 Track::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override)
326 {
327         if (!_session.writable()) {
328                 return;
329         }
330
331         if (_freeze_record.state == Frozen) {
332                 return;
333         }
334
335         if (record_enabled ()) {
336                 return;
337         }
338
339         if (use_group (group_override, &RouteGroup::is_recenable)) {
340                 _route_group->apply (&Track::set_record_safe, yn, Controllable::NoGroup);
341                 return;
342         }
343
344         _diskstream->set_record_safe (yn);
345 }
346
347 void
348 Track::parameter_changed (string const & p)
349 {
350         if (p == "track-name-number") {
351                 resync_track_name ();
352         }
353         else if (p == "track-name-take") {
354                 resync_track_name ();
355         }
356         else if (p == "take-name") {
357                 if (_session.config.get_track_name_take()) {
358                         resync_track_name ();
359                 }
360         }
361 }
362
363 void
364 Track::resync_track_name ()
365 {
366         set_name(name());
367 }
368
369 bool
370 Track::set_name (const string& str)
371 {
372         bool ret;
373
374         if (record_enabled() && _session.actively_recording()) {
375                 /* this messes things up if done while recording */
376                 return false;
377         }
378
379         string diskstream_name = "";
380         if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
381                 // Note: any text is fine, legalize_for_path() fixes this later
382                 diskstream_name += _session.config.get_take_name ();
383                 diskstream_name += "_";
384         }
385         const int64_t tracknumber = track_number();
386         if (tracknumber > 0 && _session.config.get_track_name_number()) {
387                 char num[64], fmt[10];
388                 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
389                 snprintf(num, sizeof(num), fmt, tracknumber);
390                 diskstream_name += num;
391                 diskstream_name += "_";
392         }
393         diskstream_name += str;
394
395         if (diskstream_name == _diskstream_name) {
396                 return true;
397         }
398         _diskstream_name = diskstream_name;
399
400         _diskstream->set_write_source_name (diskstream_name);
401
402         boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
403         if (_diskstream->playlist()->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
404                 /* Only rename the diskstream (and therefore the playlist) if
405                    a) the playlist has never had a region added to it and
406                    b) there is only one playlist for this track.
407
408                    If (a) is not followed, people can get confused if, say,
409                    they have notes about a playlist with a given name and then
410                    it changes (see mantis #4759).
411
412                    If (b) is not followed, we rename the current playlist and not
413                    the other ones, which is a bit confusing (see mantis #4977).
414                 */
415                 _diskstream->set_name (str);
416         }
417
418         /* save state so that the statefile fully reflects any filename changes */
419
420         if ((ret = Route::set_name (str)) == 0) {
421                 _session.save_state ("");
422         }
423
424         return ret;
425 }
426
427 void
428 Track::set_latency_compensation (framecnt_t longest_session_latency)
429 {
430         Route::set_latency_compensation (longest_session_latency);
431         _diskstream->set_roll_delay (_roll_delay);
432 }
433
434 int
435 Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
436 {
437         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
438
439         if (!lm.locked()) {
440                 return 0;
441         }
442
443         bool can_record = _session.actively_recording ();
444
445         /* no outputs? nothing to do ... what happens if we have sends etc. ? */
446
447         if (n_outputs().n_total() == 0) {
448                 return 0;
449         }
450
451         /* not active ... do the minimum possible by just outputting silence */
452
453         if (!_active) {
454                 silence (nframes);
455                 if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
456                         _meter->reset();
457                 }
458                 return 0;
459         }
460
461         if (session_state_changing) {
462                 if (_session.transport_speed() != 0.0f) {
463                         /* we're rolling but some state is changing (e.g. our diskstream contents)
464                            so we cannot use them. Be silent till this is over. Don't declick.
465
466                            XXX note the absurdity of ::no_roll() being called when we ARE rolling!
467                         */
468                         passthru_silence (start_frame, end_frame, nframes, 0);
469                         return 0;
470                 }
471                 /* we're really not rolling, so we're either delivery silence or actually
472                    monitoring, both of which are safe to do while session_state_changing is true.
473                 */
474         }
475
476         _diskstream->check_record_status (start_frame, can_record);
477
478         bool be_silent;
479
480         MonitorState const s = monitoring_state ();
481         /* we are not rolling, so be silent even if we are monitoring disk, as there
482            will be no disk data coming in.
483         */
484         switch (s) {
485         case MonitoringSilence:
486                 be_silent = true;
487                 break;
488         case MonitoringDisk:
489                 be_silent = true;
490                 break;
491         case MonitoringInput:
492                 be_silent = false;
493                 break;
494         default:
495                 be_silent = false;
496                 break;
497         }
498
499         //if we have an internal generator, let it play regardless of monitoring state
500         if (_have_internal_generator) {
501                 be_silent = false;
502         }
503
504         _amp->apply_gain_automation (false);
505
506         /* if have_internal_generator, or .. */
507
508         if (be_silent) {
509
510                 if (_meter_point == MeterInput) {
511                         /* still need input monitoring and metering */
512
513                         bool const track_rec = _diskstream->record_enabled ();
514                         bool const auto_input = _session.config.get_auto_input ();
515                         bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
516                         bool const tape_machine_mode = Config->get_tape_machine_mode ();
517                         bool no_meter = false;
518
519                         /* this needs a proper K-map
520                          * and should be separated into a function similar to monitoring_state()
521                          * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc
522                          *
523                          * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf
524                          */
525                         if (!auto_input && !track_rec) {
526                                 no_meter=true;
527                         }
528                         else if (tape_machine_mode && !track_rec && auto_input) {
529                                 no_meter=true;
530                         }
531                         else if (!software_monitor && tape_machine_mode && !track_rec) {
532                                 no_meter=true;
533                         }
534                         else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) {
535                                 no_meter=true;
536                         }
537
538                         if (no_meter) {
539                                 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
540                                 _meter->run (bufs, 0, 0, nframes, true);
541                                 _input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, nframes);
542                         } else {
543                                 _input->process_input (_meter, start_frame, end_frame, nframes);
544                         }
545                 }
546
547                 passthru_silence (start_frame, end_frame, nframes, 0);
548
549         } else {
550
551                 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
552
553                 fill_buffers_with_input (bufs, _input, nframes);
554
555                 if (_meter_point == MeterInput) {
556                         _meter->run (bufs, start_frame, end_frame, nframes, true);
557                 }
558
559                 passthru (bufs, start_frame, end_frame, nframes, false);
560         }
561
562         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
563                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
564                 if (d) {
565                         d->flush_buffers (nframes);
566                 }
567         }
568
569         return 0;
570 }
571
572 int
573 Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
574 {
575         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
576         if (!lm.locked()) {
577                 framecnt_t playback_distance = _diskstream->calculate_playback_distance(nframes);
578                 if (can_internal_playback_seek(playback_distance)) {
579                         internal_playback_seek(playback_distance);
580                 }
581                 return 0;
582         }
583
584         if (n_outputs().n_total() == 0 && _processors.empty()) {
585                 return 0;
586         }
587
588         if (!_active) {
589                 silence (nframes);
590                 return 0;
591         }
592
593         _silent = true;
594         _amp->apply_gain_automation(false);
595
596         silence (nframes);
597
598         framecnt_t playback_distance;
599
600         BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
601
602         int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false);
603         need_butler = _diskstream->commit (playback_distance);
604         return dret;
605 }
606
607 void
608 Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
609 {
610         _diskstream = ds;
611
612         ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
613         diskstream_playlist_changed ();
614         ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
615         ds->RecordSafeChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_safe_changed, this));
616         ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this));
617         ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this));
618 }
619
620 void
621 Track::diskstream_playlist_changed ()
622 {
623         PlaylistChanged (); /* EMIT SIGNAL */
624 }
625
626 void
627 Track::diskstream_record_enable_changed ()
628 {
629         RecordEnableChanged (); /* EMIT SIGNAL */
630 }
631
632 void
633 Track::diskstream_record_safe_changed ()
634 {
635         RecordSafeChanged (); /* EMIT SIGNAL */
636 }
637
638 void
639 Track::diskstream_speed_changed ()
640 {
641         SpeedChanged (); /* EMIT SIGNAL */
642 }
643
644 void
645 Track::diskstream_alignment_style_changed ()
646 {
647         AlignmentStyleChanged (); /* EMIT SIGNAL */
648 }
649
650 boost::shared_ptr<Playlist>
651 Track::playlist ()
652 {
653         return _diskstream->playlist ();
654 }
655
656 void
657 Track::request_input_monitoring (bool m)
658 {
659         _diskstream->request_input_monitoring (m);
660 }
661
662 void
663 Track::ensure_input_monitoring (bool m)
664 {
665         _diskstream->ensure_input_monitoring (m);
666 }
667
668 bool
669 Track::destructive () const
670 {
671         return _diskstream->destructive ();
672 }
673
674 list<boost::shared_ptr<Source> > &
675 Track::last_capture_sources ()
676 {
677         return _diskstream->last_capture_sources ();
678 }
679
680 void
681 Track::set_capture_offset ()
682 {
683         _diskstream->set_capture_offset ();
684 }
685
686 std::string
687 Track::steal_write_source_name()
688 {
689         return _diskstream->steal_write_source_name ();
690 }
691
692 void
693 Track::reset_write_sources (bool r, bool force)
694 {
695         _diskstream->reset_write_sources (r, force);
696 }
697
698 float
699 Track::playback_buffer_load () const
700 {
701         return _diskstream->playback_buffer_load ();
702 }
703
704 float
705 Track::capture_buffer_load () const
706 {
707         return _diskstream->capture_buffer_load ();
708 }
709
710 int
711 Track::do_refill ()
712 {
713         return _diskstream->do_refill ();
714 }
715
716 int
717 Track::do_flush (RunContext c, bool force)
718 {
719         return _diskstream->do_flush (c, force);
720 }
721
722 void
723 Track::set_pending_overwrite (bool o)
724 {
725         _diskstream->set_pending_overwrite (o);
726 }
727
728 int
729 Track::seek (framepos_t p, bool complete_refill)
730 {
731         return _diskstream->seek (p, complete_refill);
732 }
733
734 bool
735 Track::hidden () const
736 {
737         return _diskstream->hidden ();
738 }
739
740 int
741 Track::can_internal_playback_seek (framecnt_t p)
742 {
743         return _diskstream->can_internal_playback_seek (p);
744 }
745
746 int
747 Track::internal_playback_seek (framecnt_t p)
748 {
749         return _diskstream->internal_playback_seek (p);
750 }
751
752 void
753 Track::non_realtime_input_change ()
754 {
755         _diskstream->non_realtime_input_change ();
756 }
757
758 void
759 Track::non_realtime_locate (framepos_t p)
760 {
761         Route::non_realtime_locate (p);
762
763         if (!hidden()) {
764                 /* don't waste i/o cycles and butler calls
765                    for hidden (secret) tracks
766                 */
767                 _diskstream->non_realtime_locate (p);
768         }
769 }
770
771 void
772 Track::non_realtime_set_speed ()
773 {
774         _diskstream->non_realtime_set_speed ();
775 }
776
777 int
778 Track::overwrite_existing_buffers ()
779 {
780         return _diskstream->overwrite_existing_buffers ();
781 }
782
783 framecnt_t
784 Track::get_captured_frames (uint32_t n) const
785 {
786         return _diskstream->get_captured_frames (n);
787 }
788
789 int
790 Track::set_loop (Location* l)
791 {
792         return _diskstream->set_loop (l);
793 }
794
795 void
796 Track::transport_looped (framepos_t p)
797 {
798         _diskstream->transport_looped (p);
799 }
800
801 bool
802 Track::realtime_set_speed (double s, bool g)
803 {
804         return _diskstream->realtime_set_speed (s, g);
805 }
806
807 void
808 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
809 {
810         _diskstream->transport_stopped_wallclock (n, t, g);
811 }
812
813 bool
814 Track::pending_overwrite () const
815 {
816         return _diskstream->pending_overwrite ();
817 }
818
819 double
820 Track::speed () const
821 {
822         return _diskstream->speed ();
823 }
824
825 void
826 Track::prepare_to_stop (framepos_t t, framepos_t a)
827 {
828         _diskstream->prepare_to_stop (t, a);
829 }
830
831 void
832 Track::set_slaved (bool s)
833 {
834         _diskstream->set_slaved (s);
835 }
836
837 ChanCount
838 Track::n_channels ()
839 {
840         return _diskstream->n_channels ();
841 }
842
843 framepos_t
844 Track::get_capture_start_frame (uint32_t n) const
845 {
846         return _diskstream->get_capture_start_frame (n);
847 }
848
849 AlignStyle
850 Track::alignment_style () const
851 {
852         return _diskstream->alignment_style ();
853 }
854
855 AlignChoice
856 Track::alignment_choice () const
857 {
858         return _diskstream->alignment_choice ();
859 }
860
861 framepos_t
862 Track::current_capture_start () const
863 {
864         return _diskstream->current_capture_start ();
865 }
866
867 framepos_t
868 Track::current_capture_end () const
869 {
870         return _diskstream->current_capture_end ();
871 }
872
873 void
874 Track::playlist_modified ()
875 {
876         _diskstream->playlist_modified ();
877 }
878
879 int
880 Track::use_playlist (boost::shared_ptr<Playlist> p)
881 {
882         int ret = _diskstream->use_playlist (p);
883         if (ret == 0) {
884                 p->set_orig_track_id (id());
885         }
886         return ret;
887 }
888
889 int
890 Track::use_copy_playlist ()
891 {
892         int ret =  _diskstream->use_copy_playlist ();
893
894         if (ret == 0) {
895                 _diskstream->playlist()->set_orig_track_id (id());
896         }
897
898         return ret;
899 }
900
901 int
902 Track::use_new_playlist ()
903 {
904         int ret = _diskstream->use_new_playlist ();
905
906         if (ret == 0) {
907                 _diskstream->playlist()->set_orig_track_id (id());
908         }
909
910         return ret;
911 }
912
913 void
914 Track::set_align_style (AlignStyle s, bool force)
915 {
916         _diskstream->set_align_style (s, force);
917 }
918
919 void
920 Track::set_align_choice (AlignChoice s, bool force)
921 {
922         _diskstream->set_align_choice (s, force);
923 }
924
925 bool
926 Track::using_diskstream_id (PBD::ID id) const
927 {
928         return (id == _diskstream->id ());
929 }
930
931 void
932 Track::set_block_size (pframes_t n)
933 {
934         Route::set_block_size (n);
935         _diskstream->set_block_size (n);
936 }
937
938 void
939 Track::adjust_playback_buffering ()
940 {
941         if (_diskstream) {
942                 _diskstream->adjust_playback_buffering ();
943         }
944 }
945
946 void
947 Track::adjust_capture_buffering ()
948 {
949         if (_diskstream) {
950                 _diskstream->adjust_capture_buffering ();
951         }
952 }
953
954 #ifdef USE_TRACKS_CODE_FEATURES
955
956 /* This is the Tracks version of Track::monitoring_state().
957  *
958  * Ardour developers: try to flag or fix issues if parts of the libardour API
959  * change in ways that invalidate this
960  */
961
962 MonitorState
963 Track::monitoring_state () const
964 {
965         /* Explicit requests */
966
967         if (_monitoring & MonitorInput) {
968                 return MonitoringInput;
969         }
970
971         if (_monitoring & MonitorDisk) {
972                 return MonitoringDisk;
973         }
974
975         /* This is an implementation of the truth table in doc/monitor_modes.pdf;
976            I don't think it's ever going to be too pretty too look at.
977         */
978
979         // GZ: NOT USED IN TRACKS
980         //bool const auto_input = _session.config.get_auto_input ();
981         //bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
982         //bool const tape_machine_mode = Config->get_tape_machine_mode ();
983
984         bool const roll = _session.transport_rolling ();
985         bool const track_rec = _diskstream->record_enabled ();
986         bool session_rec = _session.actively_recording ();
987
988         if (track_rec) {
989
990                 if (!session_rec && roll) {
991                         return MonitoringDisk;
992                 } else {
993                         return MonitoringInput;
994                 }
995
996         } else {
997
998                 if (roll) {
999                         return MonitoringDisk;
1000                 }
1001         }
1002
1003         return MonitoringSilence;
1004 }
1005
1006 #else
1007
1008 /* This is the Ardour/Mixbus version of Track::monitoring_state().
1009  *
1010  * Tracks developers: do NOT modify this method under any circumstances.
1011  */
1012
1013 MonitorState
1014 Track::monitoring_state () const
1015 {
1016         /* Explicit requests */
1017
1018         if (_monitoring & MonitorInput) {
1019                 return MonitoringInput;
1020         }
1021
1022         if (_monitoring & MonitorDisk) {
1023                 return MonitoringDisk;
1024         }
1025
1026         /* This is an implementation of the truth table in doc/monitor_modes.pdf;
1027            I don't think it's ever going to be too pretty too look at.
1028         */
1029
1030         bool const roll = _session.transport_rolling ();
1031         bool const track_rec = _diskstream->record_enabled ();
1032         bool const auto_input = _session.config.get_auto_input ();
1033         bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
1034         bool const tape_machine_mode = Config->get_tape_machine_mode ();
1035         bool session_rec;
1036
1037         /* I suspect that just use actively_recording() is good enough all the
1038          * time, but just to keep the semantics the same as they were before
1039          * sept 26th 2012, we differentiate between the cases where punch is
1040          * enabled and those where it is not.
1041          */
1042
1043         if (_session.config.get_punch_in() || _session.config.get_punch_out()) {
1044                 session_rec = _session.actively_recording ();
1045         } else {
1046                 session_rec = _session.get_record_enabled();
1047         }
1048
1049         if (track_rec) {
1050
1051                 if (!session_rec && roll && auto_input) {
1052                         return MonitoringDisk;
1053                 } else {
1054                         return software_monitor ? MonitoringInput : MonitoringSilence;
1055                 }
1056
1057         } else {
1058
1059                 if (tape_machine_mode) {
1060
1061                         return MonitoringDisk;
1062
1063                 } else {
1064
1065                         if (!roll && auto_input) {
1066                                 return software_monitor ? MonitoringInput : MonitoringSilence;
1067                         } else {
1068                                 return MonitoringDisk;
1069                         }
1070
1071                 }
1072         }
1073
1074         abort(); /* NOTREACHED */
1075         return MonitoringSilence;
1076 }
1077
1078 #endif
1079
1080 void
1081 Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
1082 {
1083         /* never declick if there is an internal generator - we just want it to
1084            keep generating sound without interruption.
1085
1086            ditto if we are monitoring inputs.
1087         */
1088
1089         if (_have_internal_generator || monitoring_choice() == MonitorInput) {
1090                 return;
1091         }
1092
1093         if (!declick) {
1094                 declick = _pending_declick;
1095         }
1096
1097         if (declick != 0) {
1098                 Amp::declick (bufs, nframes, declick);
1099         }
1100 }
1101
1102 framecnt_t
1103 Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
1104 {
1105         if (_roll_delay > nframes) {
1106
1107                 _roll_delay -= nframes;
1108                 silence_unlocked (nframes);
1109                 /* transport frame is not legal for caller to use */
1110                 return 0;
1111
1112         } else if (_roll_delay > 0) {
1113
1114                 nframes -= _roll_delay;
1115                 silence_unlocked (_roll_delay);
1116                 transport_frame += _roll_delay;
1117
1118                 /* shuffle all the port buffers for things that lead "out" of this Route
1119                    to reflect that we just wrote _roll_delay frames of silence.
1120                 */
1121
1122                 Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
1123                 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1124                         boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
1125                         if (iop) {
1126                                 iop->increment_port_buffer_offset (_roll_delay);
1127                         }
1128                 }
1129                 _output->increment_port_buffer_offset (_roll_delay);
1130
1131                 _roll_delay = 0;
1132
1133         }
1134
1135         return nframes;
1136 }
1137
1138 void
1139 Track::set_monitoring (MonitorChoice mc, Controllable::GroupControlDisposition gcd)
1140 {
1141         if (use_group (gcd, &RouteGroup::is_monitoring)) {
1142                 _route_group->apply (&Track::set_monitoring, mc, Controllable::NoGroup);
1143                 return;
1144         }
1145
1146         if (mc !=  _monitoring) {
1147                 _monitoring = mc;
1148
1149                 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1150                         (*i)->monitoring_changed ();
1151                 }
1152
1153                 MonitoringChanged (); /* EMIT SIGNAL */
1154                 _monitoring_control->Changed (); /* EMIT SIGNAL */
1155         }
1156 }
1157
1158 MeterState
1159 Track::metering_state () const
1160 {
1161         bool rv;
1162         if (_session.transport_rolling ()) {
1163                 // audio_track.cc || midi_track.cc roll() runs meter IFF:
1164                 rv = _meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled());
1165         } else {
1166                 // track no_roll() always metering if
1167                 rv = _meter_point == MeterInput;
1168         }
1169         return rv ? MeteringInput : MeteringRoute;
1170 }
1171
1172 Track::MonitoringControllable::MonitoringControllable (std::string name, boost::shared_ptr<Track> r)
1173         : RouteAutomationControl (name, MonitoringAutomation, boost::shared_ptr<AutomationList>(), r)
1174 {
1175         boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(MonitoringAutomation)));
1176         gl->set_interpolation(Evoral::ControlList::Discrete);
1177         set_list (gl);
1178 }
1179
1180 void
1181 Track::MonitoringControllable::set_value (double val, Controllable::GroupControlDisposition gcd)
1182 {
1183         _set_value (val, gcd);
1184 }
1185
1186 void
1187 Track::MonitoringControllable::_set_value (double val, Controllable::GroupControlDisposition gcd)
1188 {
1189         boost::shared_ptr<Route> r = _route.lock();
1190         if (!r) {
1191                 return;
1192         }
1193
1194         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (r);
1195         if (!t) {
1196                 return;
1197         }
1198
1199         int mc = (int) val;
1200
1201         if (mc < MonitorAuto || mc > MonitorDisk) {
1202                 return;
1203         }
1204
1205         /* no group effect at present */
1206
1207         t->set_monitoring ((MonitorChoice) mc, gcd);
1208 }
1209
1210 double
1211 Track::MonitoringControllable::get_value () const
1212 {
1213         boost::shared_ptr<Route> r = _route.lock();
1214         if (!r) {
1215                 return 0.0;
1216         }
1217
1218         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (r);
1219         if (!t) {
1220                 return 0.0;
1221         }
1222
1223         return t->monitoring_choice();
1224 }