+
+double
+Track::speed () const
+{
+ return _diskstream->speed ();
+}
+
+void
+Track::prepare_to_stop (framepos_t p)
+{
+ _diskstream->prepare_to_stop (p);
+}
+
+void
+Track::set_slaved (bool s)
+{
+ _diskstream->set_slaved (s);
+}
+
+ChanCount
+Track::n_channels ()
+{
+ return _diskstream->n_channels ();
+}
+
+framepos_t
+Track::get_capture_start_frame (uint32_t n) const
+{
+ return _diskstream->get_capture_start_frame (n);
+}
+
+AlignStyle
+Track::alignment_style () const
+{
+ return _diskstream->alignment_style ();
+}
+
+AlignChoice
+Track::alignment_choice () const
+{
+ return _diskstream->alignment_choice ();
+}
+
+framepos_t
+Track::current_capture_start () const
+{
+ return _diskstream->current_capture_start ();
+}
+
+framepos_t
+Track::current_capture_end () const
+{
+ return _diskstream->current_capture_end ();
+}
+
+void
+Track::playlist_modified ()
+{
+ _diskstream->playlist_modified ();
+}
+
+int
+Track::use_playlist (boost::shared_ptr<Playlist> p)
+{
+ int ret = _diskstream->use_playlist (p);
+ if (ret == 0) {
+ p->set_orig_track_id (id());
+ }
+ return ret;
+}
+
+int
+Track::use_copy_playlist ()
+{
+ int ret = _diskstream->use_copy_playlist ();
+
+ if (ret == 0) {
+ _diskstream->playlist()->set_orig_track_id (id());
+ }
+
+ return ret;
+}
+
+int
+Track::use_new_playlist ()
+{
+ int ret = _diskstream->use_new_playlist ();
+
+ if (ret == 0) {
+ _diskstream->playlist()->set_orig_track_id (id());
+ }
+
+ return ret;
+}
+
+void
+Track::set_align_style (AlignStyle s, bool force)
+{
+ _diskstream->set_align_style (s, force);
+}
+
+void
+Track::set_align_choice (AlignChoice s, bool force)
+{
+ _diskstream->set_align_choice (s, force);
+}
+
+bool
+Track::using_diskstream_id (PBD::ID id) const
+{
+ return (id == _diskstream->id ());
+}
+
+void
+Track::set_block_size (pframes_t n)
+{
+ Route::set_block_size (n);
+ _diskstream->set_block_size (n);
+}
+
+void
+Track::adjust_playback_buffering ()
+{
+ if (_diskstream) {
+ _diskstream->adjust_playback_buffering ();
+ }
+}
+
+void
+Track::adjust_capture_buffering ()
+{
+ if (_diskstream) {
+ _diskstream->adjust_capture_buffering ();
+ }
+}
+
+MonitorState
+Track::monitoring_state () const
+{
+ /* Explicit requests */
+
+ if (_monitoring & MonitorInput) {
+ return MonitoringInput;
+ }
+
+ if (_monitoring & MonitorDisk) {
+ return MonitoringDisk;
+ }
+
+ /* This is an implementation of the truth table in doc/monitor_modes.pdf;
+ I don't think it's ever going to be too pretty too look at.
+ */
+
+ bool const roll = _session.transport_rolling ();
+ bool const track_rec = _diskstream->record_enabled ();
+ bool const auto_input = _session.config.get_auto_input ();
+ bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
+ bool const tape_machine_mode = Config->get_tape_machine_mode ();
+ bool session_rec;
+
+ /* I suspect that just use actively_recording() is good enough all the
+ * time, but just to keep the semantics the same as they were before
+ * sept 26th 2012, we differentiate between the cases where punch is
+ * enabled and those where it is not.
+ */
+
+ if (_session.config.get_punch_in() || _session.config.get_punch_out()) {
+ session_rec = _session.actively_recording ();
+ } else {
+ session_rec = _session.get_record_enabled();
+ }
+
+ if (track_rec) {
+
+ if (!session_rec && roll && auto_input) {
+ return MonitoringDisk;
+ } else {
+ return software_monitor ? MonitoringInput : MonitoringSilence;
+ }
+
+ } else {
+
+ if (tape_machine_mode) {
+
+ return MonitoringDisk;
+
+ } else {
+
+ if (!roll && auto_input) {
+ return software_monitor ? MonitoringInput : MonitoringSilence;
+ } else {
+ return MonitoringDisk;
+ }
+
+ }
+ }
+
+ /* NOTREACHED */
+ return MonitoringSilence;
+}
+
+void
+Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
+{
+ /* never declick if there is an internal generator - we just want it to
+ keep generating sound without interruption.
+
+ ditto if we are monitoring inputs.
+ */
+
+ if (_have_internal_generator || monitoring_choice() == MonitorInput) {
+ return;
+ }
+
+ if (!declick) {
+ declick = _pending_declick;
+ }
+
+ if (declick != 0) {
+ Amp::declick (bufs, nframes, declick);
+ }
+}
+
+framecnt_t
+Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
+{
+ if (_roll_delay > nframes) {
+
+ _roll_delay -= nframes;
+ silence_unlocked (nframes);
+ /* transport frame is not legal for caller to use */
+ return 0;
+
+ } else if (_roll_delay > 0) {
+
+ nframes -= _roll_delay;
+ silence_unlocked (_roll_delay);
+ transport_frame += _roll_delay;
+
+ /* shuffle all the port buffers for things that lead "out" of this Route
+ to reflect that we just wrote _roll_delay frames of silence.
+ */
+
+ Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
+ if (iop) {
+ iop->increment_port_buffer_offset (_roll_delay);
+ }
+ }
+ _output->increment_port_buffer_offset (_roll_delay);
+
+ _roll_delay = 0;
+
+ }
+
+ return nframes;
+}
+
+void
+Track::set_monitoring (MonitorChoice mc)
+{
+ if (mc != _monitoring) {
+ _monitoring = mc;
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ (*i)->monitoring_changed ();
+ }
+
+ MonitoringChanged (); /* EMIT SIGNAL */
+ }
+}
+
+MeterState
+Track::metering_state () const
+{
+ bool rv;
+ if (_session.transport_rolling ()) {
+ // audio_track.cc || midi_track.cc roll() runs meter IFF:
+ rv = _meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled());
+ } else {
+ // track no_roll() always metering if
+ rv = _meter_point == MeterInput;
+ }
+ return rv ? MeteringInput : MeteringRoute;
+}
+