c0468c9af42de728b96892b32d09567e5052abf5
[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         , _rec_enable_control (new RecEnableControllable(*this))
48 {
49         _freeze_record.state = NoFreeze;
50         _declickable = true;
51
52         Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
53 }
54
55 Track::~Track ()
56 {
57         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
58 }
59
60 int
61 Track::init ()
62 {
63         if (Route::init ()) {
64                 return -1;
65         }
66
67         return 0;
68 }
69
70 void
71 Track::use_new_diskstream ()
72 {
73         boost::shared_ptr<Diskstream> ds = create_diskstream ();
74
75         ds->do_refill_with_alloc ();
76         ds->set_block_size (_session.get_block_size ());
77         ds->playlist()->set_orig_track_id (id());
78
79         set_diskstream (ds);
80 }
81
82 XMLNode&
83 Track::get_state ()
84 {
85         return state (true);
86 }
87
88 XMLNode&
89 Track::state (bool full)
90 {
91         XMLNode& root (Route::state (full));
92         root.add_property (X_("monitoring"), enum_2_string (_monitoring));
93         root.add_property (X_("saved-meter-point"), enum_2_string (_saved_meter_point));
94         root.add_child_nocopy (_rec_enable_control->get_state());
95         root.add_child_nocopy (_diskstream->get_state ());
96
97         if (!_deactivated_processors.empty ()) {
98                 XMLNode* node = new XMLNode (X_("DeactivatedProcessors"));
99                 for (list<boost::weak_ptr<Processor> >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) {
100                         boost::shared_ptr<Processor> p = i->lock ();
101                         if (p) {
102                                 XMLNode* c = new XMLNode (X_("Processor"));
103                                 c->add_property (X_("id"), p->id().to_s());
104                                 node->add_child_nocopy (*c);
105                         }
106                 }
107                 root.add_child_nocopy (*node);
108         }
109         
110         return root;
111 }       
112
113 int
114 Track::set_state (const XMLNode& node, int version)
115 {
116         if (Route::set_state (node, version)) {
117                 return -1;
118         }
119
120         XMLNode* child;
121
122         if (version >= 3000) {
123                 if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
124                         boost::shared_ptr<Diskstream> ds = diskstream_factory (*child);
125                         ds->do_refill_with_alloc ();
126                         set_diskstream (ds);
127                 }
128         }
129
130         if (_diskstream) {
131                 _diskstream->playlist()->set_orig_track_id (id());
132         }
133
134         /* set rec-enable control *AFTER* setting up diskstream, because it may
135            want to operate on the diskstream as it sets its own state
136         */
137
138         XMLNodeList nlist = node.children();
139         for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
140                 child = *niter;
141
142                 XMLProperty* prop;
143                 if (child->name() == Controllable::xml_node_name && (prop = child->property ("name")) != 0) {
144                         if (prop->value() == X_("recenable")) {
145                                 _rec_enable_control->set_state (*child, version);
146                         }
147                 }
148
149                 if (child->name() == X_("DeactivatedProcessors")) {
150                         XMLNodeList dp = child->children ();
151                         for (XMLNodeConstIterator i = dp.begin(); i != dp.end(); ++i) {
152                                 assert ((*i)->name() == X_("Processor"));
153                                 XMLProperty* prop = (*i)->property (X_("id"));
154                                 boost::shared_ptr<Processor> p = processor_by_id (PBD::ID (prop->value ()));
155                                 if (p) {
156                                         _deactivated_processors.push_back (p);
157                                 }
158                         }
159                 }
160         }
161         
162         const XMLProperty* prop;
163
164         if ((prop = node.property (X_("monitoring"))) != 0) {
165                 _monitoring = MonitorChoice (string_2_enum (prop->value(), _monitoring));
166         } else {
167                 _monitoring = MonitorAuto;
168         }
169
170         if ((prop = node.property (X_("saved-meter-point"))) != 0) {
171                 _saved_meter_point = MeterPoint (string_2_enum (prop->value(), _saved_meter_point));
172         } else {
173                 _saved_meter_point = _meter_point;
174         }
175
176         return 0;
177 }
178
179 XMLNode&
180 Track::get_template ()
181 {
182         return state (false);
183 }
184
185 Track::FreezeRecord::~FreezeRecord ()
186 {
187         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
188                 delete *i;
189         }
190 }
191
192 Track::FreezeState
193 Track::freeze_state() const
194 {
195         return _freeze_record.state;
196 }
197
198 Track::RecEnableControllable::RecEnableControllable (Track& s)
199         : Controllable (X_("recenable")), track (s)
200 {
201 }
202
203 void
204 Track::RecEnableControllable::set_value (double val)
205 {
206         bool bval = ((val >= 0.5) ? true: false);
207         track.set_record_enabled (bval, this);
208 }
209
210 double
211 Track::RecEnableControllable::get_value (void) const
212 {
213         if (track.record_enabled()) { return 1.0; }
214         return 0.0;
215 }
216
217 bool
218 Track::record_enabled () const
219 {
220         return _diskstream && _diskstream->record_enabled ();
221 }
222
223 bool
224 Track::can_record()
225 {
226         bool will_record = true;
227         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
228                 if (!i->connected())
229                         will_record = false;
230         }
231
232         return will_record;
233 }
234
235 /* Turn off visible processors (except Fader), keeping track of the old states */
236 void
237 Track::deactivate_visible_processors ()
238 {
239         _deactivated_processors.clear ();
240         Glib::RWLock::ReaderLock lm (_processor_lock);
241         
242         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
243                 if ((*i)->active() && (*i)->display_to_user() && boost::dynamic_pointer_cast<Amp> (*i) == 0) {
244                         (*i)->deactivate ();
245                         _deactivated_processors.push_back (*i);
246                 }
247         }
248 }
249
250 /* Turn deactivated processors back on again */
251 void
252 Track::activate_deactivated_processors ()
253 {
254         for (list<boost::weak_ptr<Processor> >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) {
255                 boost::shared_ptr<Processor> p = i->lock ();
256                 if (p) {
257                         p->activate ();
258                 }
259         }
260 }
261
262 void
263 Track::set_record_enabled (bool yn, void *src)
264 {
265         if (!_session.writable()) {
266                 return;
267         }
268
269         if (_freeze_record.state == Frozen) {
270                 return;
271         }
272
273         if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
274                 _route_group->apply (&Track::set_record_enabled, yn, _route_group);
275                 return;
276         }
277
278         /* keep track of the meter point as it was before we rec-enabled */
279         if (!_diskstream->record_enabled()) {
280                 _saved_meter_point = _meter_point;
281         }
282
283         if (Config->get_do_not_record_plugins ()) {
284                 if (yn) {
285                         deactivate_visible_processors ();
286                 } else {
287                         activate_deactivated_processors ();
288                 }
289         }
290
291         _diskstream->set_record_enabled (yn);
292
293         if (_diskstream->record_enabled()) {
294                 if (_meter_point != MeterCustom) {
295                         set_meter_point (MeterInput);
296                 }
297         } else {
298                 set_meter_point (_saved_meter_point);
299         }
300
301         _rec_enable_control->Changed ();
302 }
303
304
305 bool
306 Track::set_name (const string& str)
307 {
308         bool ret;
309
310         if (record_enabled() && _session.actively_recording()) {
311                 /* this messes things up if done while recording */
312                 return false;
313         }
314
315         _diskstream->set_name (str);
316
317         /* save state so that the statefile fully reflects any filename changes */
318
319         if ((ret = Route::set_name (str)) == 0) {
320                 _session.save_state ("");
321         }
322
323         return ret;
324 }
325
326 void
327 Track::set_latency_compensation (framecnt_t longest_session_latency)
328 {
329         Route::set_latency_compensation (longest_session_latency);
330         _diskstream->set_roll_delay (_roll_delay);
331 }
332
333 int
334 Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
335 {
336         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
337         if (!lm.locked()) {
338                 return 0;
339         }
340
341         bool can_record = _session.actively_recording ();
342
343         if (n_outputs().n_total() == 0) {
344                 return 0;
345         }
346
347         if (!_active) {
348                 silence (nframes);
349                 return 0;
350         }
351
352         if (session_state_changing) {
353                 if (_session.transport_speed() != 0.0f) {
354                         /* we're rolling but some state is changing (e.g. our diskstream contents)
355                            so we cannot use them. Be silent till this is over. Don't declick.
356
357                            XXX note the absurdity of ::no_roll() being called when we ARE rolling!
358                         */
359                         passthru_silence (start_frame, end_frame, nframes, 0);
360                         return 0;
361                 }
362                 /* we're really not rolling, so we're either delivery silence or actually
363                    monitoring, both of which are safe to do while session_state_changing is true.
364                 */
365         }
366
367         _diskstream->check_record_status (start_frame, can_record);
368
369         bool be_silent;
370
371         if (_have_internal_generator) {
372                 /* since the instrument has no input streams,
373                    there is no reason to send any signal
374                    into the route.
375                 */
376                 be_silent = true;
377         } else {
378                 be_silent = send_silence ();
379         }
380
381         _amp->apply_gain_automation(false);
382
383         if (be_silent) {
384
385                 /* if we're sending silence, but we want the meters to show levels for the signal,
386                    meter right here.
387                 */
388
389                 if (_have_internal_generator) {
390                         passthru_silence (start_frame, end_frame, nframes, 0);
391                 } else {
392                         if (_meter_point == MeterInput) {
393                                 _input->process_input (_meter, start_frame, end_frame, nframes);
394                         }
395                         passthru_silence (start_frame, end_frame, nframes, 0);
396                 }
397
398         } else {
399
400                 /* we're sending signal, but we may still want to meter the input.
401                  */
402
403                 passthru (start_frame, end_frame, nframes, false);
404         }
405
406         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
407                 boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
408                 if (d) {
409                         d->flush_buffers (nframes, end_frame - start_frame - 1);
410                 }
411         }
412
413         return 0;
414 }
415
416 int
417 Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
418 {
419         Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK);
420         if (!lm.locked()) {
421                 return 0;
422         }
423
424         if (n_outputs().n_total() == 0 && _processors.empty()) {
425                 return 0;
426         }
427
428         if (!_active) {
429                 silence (nframes);
430                 return 0;
431         }
432
433         _silent = true;
434         _amp->apply_gain_automation(false);
435
436         silence (nframes);
437
438         framecnt_t playback_distance;
439         int const dret = _diskstream->process (_session.transport_frame(), nframes, playback_distance);
440         need_butler = _diskstream->commit (playback_distance);
441         return dret;
442 }
443
444 void
445 Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
446 {
447         _diskstream = ds;
448
449         ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
450         diskstream_playlist_changed ();
451         ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
452         ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this));
453         ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this));
454 }
455
456 void
457 Track::diskstream_playlist_changed ()
458 {
459         PlaylistChanged (); /* EMIT SIGNAL */
460 }
461
462 void
463 Track::diskstream_record_enable_changed ()
464 {
465         RecordEnableChanged (); /* EMIT SIGNAL */
466 }
467
468 void
469 Track::diskstream_speed_changed ()
470 {
471         SpeedChanged (); /* EMIT SIGNAL */
472 }
473
474 void
475 Track::diskstream_alignment_style_changed ()
476 {
477         AlignmentStyleChanged (); /* EMIT SIGNAL */
478 }
479
480 boost::shared_ptr<Playlist>
481 Track::playlist ()
482 {
483         return _diskstream->playlist ();
484 }
485
486 void
487 Track::monitor_input (bool m)
488 {
489         _diskstream->monitor_input (m);
490 }
491
492 bool
493 Track::destructive () const
494 {
495         return _diskstream->destructive ();
496 }
497
498 list<boost::shared_ptr<Source> > &
499 Track::last_capture_sources ()
500 {
501         return _diskstream->last_capture_sources ();
502 }
503
504 void
505 Track::set_capture_offset ()
506 {
507         _diskstream->set_capture_offset ();
508 }
509
510 list<boost::shared_ptr<Source> >
511 Track::steal_write_sources()
512 {
513         return _diskstream->steal_write_sources ();
514 }
515
516 void
517 Track::reset_write_sources (bool r, bool force)
518 {
519         _diskstream->reset_write_sources (r, force);
520 }
521
522 float
523 Track::playback_buffer_load () const
524 {
525         return _diskstream->playback_buffer_load ();
526 }
527
528 float
529 Track::capture_buffer_load () const
530 {
531         return _diskstream->capture_buffer_load ();
532 }
533
534 int
535 Track::do_refill ()
536 {
537         return _diskstream->do_refill ();
538 }
539
540 int
541 Track::do_flush (RunContext c, bool force)
542 {
543         return _diskstream->do_flush (c, force);
544 }
545
546 void
547 Track::set_pending_overwrite (bool o)
548 {
549         _diskstream->set_pending_overwrite (o);
550 }
551
552 int
553 Track::seek (framepos_t p, bool complete_refill)
554 {
555         return _diskstream->seek (p, complete_refill);
556 }
557
558 bool
559 Track::hidden () const
560 {
561         return _diskstream->hidden ();
562 }
563
564 int
565 Track::can_internal_playback_seek (framepos_t p)
566 {
567         return _diskstream->can_internal_playback_seek (p);
568 }
569
570 int
571 Track::internal_playback_seek (framepos_t p)
572 {
573         return _diskstream->internal_playback_seek (p);
574 }
575
576 void
577 Track::non_realtime_input_change ()
578 {
579         _diskstream->non_realtime_input_change ();
580 }
581
582 void
583 Track::non_realtime_locate (framepos_t p)
584 {
585         _diskstream->non_realtime_locate (p);
586 }
587
588 void
589 Track::non_realtime_set_speed ()
590 {
591         _diskstream->non_realtime_set_speed ();
592 }
593
594 int
595 Track::overwrite_existing_buffers ()
596 {
597         return _diskstream->overwrite_existing_buffers ();
598 }
599
600 framecnt_t
601 Track::get_captured_frames (uint32_t n) const
602 {
603         return _diskstream->get_captured_frames (n);
604 }
605
606 int
607 Track::set_loop (Location* l)
608 {
609         return _diskstream->set_loop (l);
610 }
611
612 void
613 Track::transport_looped (framepos_t p)
614 {
615         _diskstream->transport_looped (p);
616 }
617
618 bool
619 Track::realtime_set_speed (double s, bool g)
620 {
621         return _diskstream->realtime_set_speed (s, g);
622 }
623
624 void
625 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
626 {
627         _diskstream->transport_stopped_wallclock (n, t, g);
628 }
629
630 bool
631 Track::pending_overwrite () const
632 {
633         return _diskstream->pending_overwrite ();
634 }
635
636 double
637 Track::speed () const
638 {
639         return _diskstream->speed ();
640 }
641
642 void
643 Track::prepare_to_stop (framepos_t p)
644 {
645         _diskstream->prepare_to_stop (p);
646 }
647
648 void
649 Track::set_slaved (bool s)
650 {
651         _diskstream->set_slaved (s);
652 }
653
654 ChanCount
655 Track::n_channels ()
656 {
657         return _diskstream->n_channels ();
658 }
659
660 framepos_t
661 Track::get_capture_start_frame (uint32_t n) const
662 {
663         return _diskstream->get_capture_start_frame (n);
664 }
665
666 AlignStyle
667 Track::alignment_style () const
668 {
669         return _diskstream->alignment_style ();
670 }
671
672 AlignChoice
673 Track::alignment_choice () const
674 {
675         return _diskstream->alignment_choice ();
676 }
677
678 framepos_t
679 Track::current_capture_start () const
680 {
681         return _diskstream->current_capture_start ();
682 }
683
684 framepos_t
685 Track::current_capture_end () const
686 {
687         return _diskstream->current_capture_end ();
688 }
689
690 void
691 Track::playlist_modified ()
692 {
693         _diskstream->playlist_modified ();
694 }
695
696 int
697 Track::use_playlist (boost::shared_ptr<Playlist> p)
698 {
699         int ret = _diskstream->use_playlist (p);
700         if (ret == 0) {
701                 p->set_orig_track_id (id());
702         }
703         return ret;
704 }
705
706 int
707 Track::use_copy_playlist ()
708 {
709         int ret =  _diskstream->use_copy_playlist ();
710
711         if (ret == 0) {
712                 _diskstream->playlist()->set_orig_track_id (id());
713         }
714
715         return ret;
716 }
717
718 int
719 Track::use_new_playlist ()
720 {
721         int ret = _diskstream->use_new_playlist ();
722
723         if (ret == 0) {
724                 _diskstream->playlist()->set_orig_track_id (id());
725         }
726
727         return ret;
728 }
729
730 void
731 Track::set_align_style (AlignStyle s, bool force)
732 {
733         _diskstream->set_align_style (s, force);
734 }
735
736 void
737 Track::set_align_choice (AlignChoice s, bool force)
738 {
739         _diskstream->set_align_choice (s, force);
740 }
741
742 bool
743 Track::using_diskstream_id (PBD::ID id) const
744 {
745         return (id == _diskstream->id ());
746 }
747
748 void
749 Track::set_block_size (pframes_t n)
750 {
751         Route::set_block_size (n);
752         _diskstream->set_block_size (n);
753 }
754
755 void
756 Track::adjust_playback_buffering ()
757 {
758         if (_diskstream) {
759                 _diskstream->adjust_playback_buffering ();
760         }
761 }
762
763 void
764 Track::adjust_capture_buffering ()
765 {
766         if (_diskstream) {
767                 _diskstream->adjust_capture_buffering ();
768         }
769 }
770
771 bool
772 Track::send_silence () const
773 {
774         bool send_silence;
775
776         if (Config->get_tape_machine_mode()) {
777
778                 /* ADATs work in a strange way..
779                    they monitor input always when stopped.and auto-input is engaged.
780                 */
781                 
782                 if ((Config->get_monitoring_model() == SoftwareMonitoring)
783                     && ((_monitoring & MonitorInput) || (_diskstream->record_enabled()))) {
784                         send_silence = false;
785                 } else {
786                         send_silence = true;
787                 }
788                 
789                 
790         } else {
791                 
792                 /* Other machines switch to input on stop if the track is record enabled,
793                    regardless of the auto input setting (auto input only changes the
794                    monitoring state when the transport is rolling)
795                 */
796                 
797                 if ((Config->get_monitoring_model() == SoftwareMonitoring)
798                     && ((_monitoring & MonitorInput) || 
799                         (!(_monitoring & MonitorDisk) && (_session.config.get_auto_input () || _diskstream->record_enabled())))){
800
801                         DEBUG_TRACE (DEBUG::Monitor, 
802                                      string_compose ("%1: no roll, use silence = FALSE,  monitoring choice %2 recenable %3 sRA %4 autoinput %5\n",
803                                                      name(), enum_2_string (_monitoring), 
804                                                      _diskstream->record_enabled(), _session.actively_recording(),
805                                                      _session.config.get_auto_input()));
806
807                         send_silence = false;
808                 } else {
809                         DEBUG_TRACE (DEBUG::Monitor, 
810                                      string_compose ("%1: no roll, use silence = TRUE,  monitoring choice %2 recenable %3 sRA %4 autoinput %5\n",
811                                                      name(), enum_2_string (_monitoring), 
812                                                      _diskstream->record_enabled(), _session.actively_recording(),
813                                                      _session.config.get_auto_input()));
814                         send_silence = true;
815                 }
816         }
817
818         return send_silence;
819 }
820
821 MonitorState
822 Track::monitoring_state ()
823 {
824         MonitorState ms = MonitoringSilence;
825
826         if (_session.transport_rolling()) {
827                 
828                 /* roll case */
829                 
830                 if (_monitoring & MonitorInput) { // explicitly requested input monitoring
831                         
832                         ms = MonitoringInput;
833
834                 } else if (_monitoring & MonitorDisk) { // explicitly requested disk monitoring
835                         
836                         ms = MonitoringDisk;
837
838                 } else if (_diskstream->record_enabled() && _session.actively_recording()) { // Track actually recording
839                         
840                         ms = MonitoringInput;
841
842                 } else if (_diskstream->record_enabled() && !_session.actively_recording() && _session.config.get_auto_input()) { // Track armed but not recording, with auto input enabled
843                         
844                         ms = MonitoringInput;
845
846                 } else { // Every other state
847                         
848                         ms = MonitoringDisk; 
849
850                 }
851
852         } else {
853
854                 /* no-roll case */
855
856                 if (send_silence()) {
857                         
858                         ms = MonitoringSilence;
859                 } else {
860                         
861                         ms = MonitoringInput;
862                 }
863         }
864
865         return ms;
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, framecnt_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::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                 MonitoringChanged (); /* EMIT SIGNAL */
932         }
933 }
934
935 void
936 Track::parameter_changed (string p)
937 {
938         if (p != "do-not-record-plugins") {
939                 return;
940         }
941
942         if (record_enabled ()) {
943                 if (Config->get_do_not_record_plugins ()) {
944                         deactivate_visible_processors ();
945                 } else {
946                         activate_deactivated_processors ();
947                 }
948         }
949 }
950         
951