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