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