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