Squashed commit of the following:
[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                 passthru_silence (start_frame, end_frame, nframes, 0);
408
409         } else {
410
411                 BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers());
412                 
413                 fill_buffers_with_input (bufs, _input, nframes);
414
415                 if (_meter_point == MeterInput) {
416                         _meter->run (bufs, start_frame, end_frame, nframes, true);
417                 }
418
419                 passthru (bufs, start_frame, end_frame, nframes, false);
420         }
421
422         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
423                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
424                 if (d) {
425                         d->flush_buffers (nframes);
426                 }
427         }
428
429         return 0;
430 }
431
432 int
433 Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
434 {
435         Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
436         if (!lm.locked()) {
437                 return 0;
438         }
439
440         if (n_outputs().n_total() == 0 && _processors.empty()) {
441                 return 0;
442         }
443
444         if (!_active) {
445                 silence (nframes);
446                 return 0;
447         }
448
449         _silent = true;
450         _amp->apply_gain_automation(false);
451
452         silence (nframes);
453
454         framecnt_t playback_distance;
455
456         BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
457
458         int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false);
459         need_butler = _diskstream->commit (playback_distance);
460         return dret;
461 }
462
463 void
464 Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
465 {
466         _diskstream = ds;
467
468         ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
469         diskstream_playlist_changed ();
470         ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
471         ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this));
472         ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this));
473 }
474
475 void
476 Track::diskstream_playlist_changed ()
477 {
478         PlaylistChanged (); /* EMIT SIGNAL */
479 }
480
481 void
482 Track::diskstream_record_enable_changed ()
483 {
484         RecordEnableChanged (); /* EMIT SIGNAL */
485 }
486
487 void
488 Track::diskstream_speed_changed ()
489 {
490         SpeedChanged (); /* EMIT SIGNAL */
491 }
492
493 void
494 Track::diskstream_alignment_style_changed ()
495 {
496         AlignmentStyleChanged (); /* EMIT SIGNAL */
497 }
498
499 boost::shared_ptr<Playlist>
500 Track::playlist ()
501 {
502         return _diskstream->playlist ();
503 }
504
505 void
506 Track::request_jack_monitors_input (bool m)
507 {
508         _diskstream->request_jack_monitors_input (m);
509 }
510
511 void
512 Track::ensure_jack_monitors_input (bool m)
513 {
514         _diskstream->ensure_jack_monitors_input (m);
515 }
516
517 bool
518 Track::destructive () const
519 {
520         return _diskstream->destructive ();
521 }
522
523 list<boost::shared_ptr<Source> > &
524 Track::last_capture_sources ()
525 {
526         return _diskstream->last_capture_sources ();
527 }
528
529 void
530 Track::set_capture_offset ()
531 {
532         _diskstream->set_capture_offset ();
533 }
534
535 list<boost::shared_ptr<Source> >
536 Track::steal_write_sources()
537 {
538         return _diskstream->steal_write_sources ();
539 }
540
541 void
542 Track::reset_write_sources (bool r, bool force)
543 {
544         _diskstream->reset_write_sources (r, force);
545 }
546
547 float
548 Track::playback_buffer_load () const
549 {
550         return _diskstream->playback_buffer_load ();
551 }
552
553 float
554 Track::capture_buffer_load () const
555 {
556         return _diskstream->capture_buffer_load ();
557 }
558
559 int
560 Track::do_refill ()
561 {
562         return _diskstream->do_refill ();
563 }
564
565 int
566 Track::do_flush (RunContext c, bool force)
567 {
568         return _diskstream->do_flush (c, force);
569 }
570
571 void
572 Track::set_pending_overwrite (bool o)
573 {
574         _diskstream->set_pending_overwrite (o);
575 }
576
577 int
578 Track::seek (framepos_t p, bool complete_refill)
579 {
580         return _diskstream->seek (p, complete_refill);
581 }
582
583 bool
584 Track::hidden () const
585 {
586         return _diskstream->hidden ();
587 }
588
589 int
590 Track::can_internal_playback_seek (framecnt_t p)
591 {
592         return _diskstream->can_internal_playback_seek (p);
593 }
594
595 int
596 Track::internal_playback_seek (framecnt_t p)
597 {
598         return _diskstream->internal_playback_seek (p);
599 }
600
601 void
602 Track::non_realtime_input_change ()
603 {
604         _diskstream->non_realtime_input_change ();
605 }
606
607 void
608 Track::non_realtime_locate (framepos_t p)
609 {
610         Route::non_realtime_locate (p);
611
612         if (!hidden()) {
613                 /* don't waste i/o cycles and butler calls
614                    for hidden (secret) tracks
615                 */
616                 _diskstream->non_realtime_locate (p);
617         }
618 }
619
620 void
621 Track::non_realtime_set_speed ()
622 {
623         _diskstream->non_realtime_set_speed ();
624 }
625
626 int
627 Track::overwrite_existing_buffers ()
628 {
629         return _diskstream->overwrite_existing_buffers ();
630 }
631
632 framecnt_t
633 Track::get_captured_frames (uint32_t n) const
634 {
635         return _diskstream->get_captured_frames (n);
636 }
637
638 int
639 Track::set_loop (Location* l)
640 {
641         return _diskstream->set_loop (l);
642 }
643
644 void
645 Track::transport_looped (framepos_t p)
646 {
647         _diskstream->transport_looped (p);
648 }
649
650 bool
651 Track::realtime_set_speed (double s, bool g)
652 {
653         return _diskstream->realtime_set_speed (s, g);
654 }
655
656 void
657 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
658 {
659         _diskstream->transport_stopped_wallclock (n, t, g);
660 }
661
662 bool
663 Track::pending_overwrite () const
664 {
665         return _diskstream->pending_overwrite ();
666 }
667
668 double
669 Track::speed () const
670 {
671         return _diskstream->speed ();
672 }
673
674 void
675 Track::prepare_to_stop (framepos_t p)
676 {
677         _diskstream->prepare_to_stop (p);
678 }
679
680 void
681 Track::set_slaved (bool s)
682 {
683         _diskstream->set_slaved (s);
684 }
685
686 ChanCount
687 Track::n_channels ()
688 {
689         return _diskstream->n_channels ();
690 }
691
692 framepos_t
693 Track::get_capture_start_frame (uint32_t n) const
694 {
695         return _diskstream->get_capture_start_frame (n);
696 }
697
698 AlignStyle
699 Track::alignment_style () const
700 {
701         return _diskstream->alignment_style ();
702 }
703
704 AlignChoice
705 Track::alignment_choice () const
706 {
707         return _diskstream->alignment_choice ();
708 }
709
710 framepos_t
711 Track::current_capture_start () const
712 {
713         return _diskstream->current_capture_start ();
714 }
715
716 framepos_t
717 Track::current_capture_end () const
718 {
719         return _diskstream->current_capture_end ();
720 }
721
722 void
723 Track::playlist_modified ()
724 {
725         _diskstream->playlist_modified ();
726 }
727
728 int
729 Track::use_playlist (boost::shared_ptr<Playlist> p)
730 {
731         int ret = _diskstream->use_playlist (p);
732         if (ret == 0) {
733                 p->set_orig_track_id (id());
734         }
735         return ret;
736 }
737
738 int
739 Track::use_copy_playlist ()
740 {
741         int ret =  _diskstream->use_copy_playlist ();
742
743         if (ret == 0) {
744                 _diskstream->playlist()->set_orig_track_id (id());
745         }
746
747         return ret;
748 }
749
750 int
751 Track::use_new_playlist ()
752 {
753         int ret = _diskstream->use_new_playlist ();
754
755         if (ret == 0) {
756                 _diskstream->playlist()->set_orig_track_id (id());
757         }
758
759         return ret;
760 }
761
762 void
763 Track::set_align_style (AlignStyle s, bool force)
764 {
765         _diskstream->set_align_style (s, force);
766 }
767
768 void
769 Track::set_align_choice (AlignChoice s, bool force)
770 {
771         _diskstream->set_align_choice (s, force);
772 }
773
774 bool
775 Track::using_diskstream_id (PBD::ID id) const
776 {
777         return (id == _diskstream->id ());
778 }
779
780 void
781 Track::set_block_size (pframes_t n)
782 {
783         Route::set_block_size (n);
784         _diskstream->set_block_size (n);
785 }
786
787 void
788 Track::adjust_playback_buffering ()
789 {
790         if (_diskstream) {
791                 _diskstream->adjust_playback_buffering ();
792         }
793 }
794
795 void
796 Track::adjust_capture_buffering ()
797 {
798         if (_diskstream) {
799                 _diskstream->adjust_capture_buffering ();
800         }
801 }
802
803 MonitorState
804 Track::monitoring_state () const
805 {
806         /* Explicit requests */
807         
808         if (_monitoring & MonitorInput) {
809                 return MonitoringInput;
810         }
811                 
812         if (_monitoring & MonitorDisk) {
813                 return MonitoringDisk;
814         }
815
816         /* This is an implementation of the truth table in doc/monitor_modes.pdf;
817            I don't think it's ever going to be too pretty too look at.
818         */
819
820         bool const roll = _session.transport_rolling ();
821         bool const track_rec = _diskstream->record_enabled ();
822         bool const auto_input = _session.config.get_auto_input ();
823         bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
824         bool const tape_machine_mode = Config->get_tape_machine_mode ();
825         bool session_rec;
826
827         /* I suspect that just use actively_recording() is good enough all the
828          * time, but just to keep the semantics the same as they were before
829          * sept 26th 2012, we differentiate between the cases where punch is
830          * enabled and those where it is not.
831          */
832
833         if (_session.config.get_punch_in() || _session.config.get_punch_out()) {
834                 session_rec = _session.actively_recording ();
835         } else {
836                 session_rec = _session.get_record_enabled();
837         }
838
839         if (track_rec) {
840
841                 if (!session_rec && roll && auto_input) {
842                         return MonitoringDisk;
843                 } else {
844                         return software_monitor ? MonitoringInput : MonitoringSilence;
845                 }
846
847         } else {
848
849                 if (tape_machine_mode) {
850
851                         return MonitoringDisk;
852
853                 } else {
854
855                         if (!roll && auto_input) {
856                                 return software_monitor ? MonitoringInput : MonitoringSilence;
857                         } else {
858                                 return MonitoringDisk;
859                         }
860                         
861                 }
862         }
863
864         /* NOTREACHED */
865         return MonitoringSilence;
866 }
867
868 void
869 Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
870 {
871         /* never declick if there is an internal generator - we just want it to
872            keep generating sound without interruption.
873
874            ditto if we are monitoring inputs.
875         */
876
877         if (_have_internal_generator || monitoring_choice() == MonitorInput) {
878                 return;
879         }
880
881         if (!declick) {
882                 declick = _pending_declick;
883         }
884
885         if (declick != 0) {
886                 Amp::declick (bufs, nframes, declick);
887         }
888 }
889
890 framecnt_t
891 Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
892 {
893         if (_roll_delay > nframes) {
894
895                 _roll_delay -= nframes;
896                 silence_unlocked (nframes);
897                 /* transport frame is not legal for caller to use */
898                 return 0;
899
900         } else if (_roll_delay > 0) {
901
902                 nframes -= _roll_delay;
903                 silence_unlocked (_roll_delay);
904                 transport_frame += _roll_delay;
905
906                 /* shuffle all the port buffers for things that lead "out" of this Route
907                    to reflect that we just wrote _roll_delay frames of silence.
908                 */
909
910                 Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
911                 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
912                         boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
913                         if (iop) {
914                                 iop->increment_port_buffer_offset (_roll_delay);
915                         }
916                 }
917                 _output->increment_port_buffer_offset (_roll_delay);
918
919                 _roll_delay = 0;
920
921         }
922
923         return nframes; 
924 }
925
926 void
927 Track::set_monitoring (MonitorChoice mc)
928 {
929         if (mc !=  _monitoring) {
930                 _monitoring = mc;
931
932                 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
933                         (*i)->monitoring_changed ();
934                 }
935
936                 MonitoringChanged (); /* EMIT SIGNAL */
937         }
938 }
939
940 MeterState
941 Track::metering_state () const
942 {
943         return _diskstream->record_enabled() ? MeteringInput : MeteringRoute;
944 }
945