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