2 Copyright (C) 2006 Paul Davis
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.
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.
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.
18 #include "pbd/error.h"
20 #include "ardour/amp.h"
21 #include "ardour/audioengine.h"
22 #include "ardour/debug.h"
23 #include "ardour/delivery.h"
24 #include "ardour/disk_reader.h"
25 #include "ardour/disk_writer.h"
26 #include "ardour/event_type_map.h"
27 #include "ardour/io_processor.h"
28 #include "ardour/meter.h"
29 #include "ardour/monitor_control.h"
30 #include "ardour/playlist.h"
31 #include "ardour/playlist_factory.h"
32 #include "ardour/port.h"
33 #include "ardour/processor.h"
34 #include "ardour/profile.h"
35 #include "ardour/record_enable_control.h"
36 #include "ardour/record_safe_control.h"
37 #include "ardour/route_group_specialized.h"
38 #include "ardour/session.h"
39 #include "ardour/session_playlists.h"
40 #include "ardour/track.h"
41 #include "ardour/types_convert.h"
42 #include "ardour/utils.h"
47 using namespace ARDOUR;
50 Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
51 : Route (sess, name, flag, default_type)
52 , _saved_meter_point (_meter_point)
55 _freeze_record.state = NoFreeze;
61 DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
71 DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
73 if (_mode == Destructive && !Profile->get_trx()) {
74 dflags = DiskIOProcessor::Flag (dflags | DiskIOProcessor::Destructive);
75 } else if (_mode == NonLayered){
76 dflags = DiskIOProcessor::Flag(dflags | DiskIOProcessor::NonLayered);
79 _disk_reader.reset (new DiskReader (_session, name(), dflags));
80 _disk_reader->set_block_size (_session.get_block_size ());
81 _disk_reader->set_route (shared_from_this());
83 _disk_writer.reset (new DiskWriter (_session, name(), dflags));
84 _disk_writer->set_block_size (_session.get_block_size ());
85 _disk_writer->set_route (shared_from_this());
89 add_processor (_disk_writer, PreFader);
90 add_processor (_disk_reader, PreFader);
92 boost::shared_ptr<Route> rp (boost::dynamic_pointer_cast<Route> (shared_from_this()));
93 boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
95 _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this));
96 add_control (_record_enable_control);
98 _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this));
99 add_control (_record_safe_control);
101 _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this));
102 add_control (_monitoring_control);
104 _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
106 _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
107 _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2));
108 _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2));
120 Track::state (bool full)
122 XMLNode& root (Route::state (full));
124 if (_playlists[DataType::AUDIO]) {
125 root.add_property (X_("audio-playlist"), _playlists[DataType::AUDIO]->id().to_s());
128 if (_playlists[DataType::MIDI]) {
129 root.add_property (X_("midi-playlist"), _playlists[DataType::MIDI]->id().to_s());
132 root.add_child_nocopy (_monitoring_control->get_state ());
133 root.add_child_nocopy (_record_safe_control->get_state ());
134 root.add_child_nocopy (_record_enable_control->get_state ());
136 root.set_property (X_("saved-meter-point"), _saved_meter_point);
142 Track::set_state (const XMLNode& node, int version)
144 if (Route::set_state (node, version)) {
149 XMLProperty const * prop;
151 if (version >= 3000 && version < 4000) {
152 if ((child = find_named_node (node, X_("Diskstream"))) != 0) {
153 /* XXX DISK ... setup reader/writer from XML */
157 if ((prop = node.property (X_("audio-playlist")))) {
158 find_and_use_playlist (DataType::AUDIO, PBD::ID (prop->value()));
161 if ((prop = node.property (X_("midi-playlist")))) {
162 find_and_use_playlist (DataType::MIDI, PBD::ID (prop->value()));
165 XMLNodeList nlist = node.children();
166 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
169 if (child->name() == Controllable::xml_node_name) {
171 if (!child->get_property ("name", name)) {
175 if (name == _record_enable_control->name()) {
176 _record_enable_control->set_state (*child, version);
177 } else if (name == _record_safe_control->name()) {
178 _record_safe_control->set_state (*child, version);
179 } else if (name == _monitoring_control->name()) {
180 _monitoring_control->set_state (*child, version);
185 if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) {
186 _saved_meter_point = _meter_point;
193 Track::get_template ()
195 return state (false);
198 Track::FreezeRecord::~FreezeRecord ()
200 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
206 Track::freeze_state() const
208 return _freeze_record.state;
214 bool will_record = true;
215 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
224 Track::prep_record_enabled (bool yn)
226 if (yn && _record_safe_control->get_value()) {
230 if (!can_be_record_enabled()) {
234 /* keep track of the meter point as it was before we rec-enabled */
235 if (!_disk_writer->record_enabled()) {
236 _saved_meter_point = _meter_point;
242 will_follow = _disk_writer->prep_record_enable ();
244 will_follow = _disk_writer->prep_record_disable ();
249 if (_meter_point != MeterCustom) {
250 set_meter_point (MeterInput);
253 set_meter_point (_saved_meter_point);
261 Track::record_enable_changed (bool, Controllable::GroupControlDisposition)
263 _disk_writer->set_record_enabled (_record_enable_control->get_value());
267 Track::record_safe_changed (bool, Controllable::GroupControlDisposition)
269 _disk_writer->set_record_safe (_record_safe_control->get_value());
273 Track::can_be_record_safe ()
275 return !_record_enable_control->get_value() && _disk_writer && _session.writable() && (_freeze_record.state != Frozen);
279 Track::can_be_record_enabled ()
281 return !_record_safe_control->get_value() && _disk_writer && !_disk_writer->record_safe() && _session.writable() && (_freeze_record.state != Frozen);
285 Track::parameter_changed (string const & p)
287 if (p == "track-name-number") {
288 resync_track_name ();
290 else if (p == "track-name-take") {
291 resync_track_name ();
293 else if (p == "take-name") {
294 if (_session.config.get_track_name_take()) {
295 resync_track_name ();
301 Track::resync_track_name ()
307 Track::set_name (const string& str)
315 if (_record_enable_control->get_value()) {
316 /* when re-arm'ed the file (named after the track) is already ready to rolll */
320 string diskstream_name = "";
321 if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) {
322 // Note: any text is fine, legalize_for_path() fixes this later
323 diskstream_name += _session.config.get_take_name ();
324 diskstream_name += "_";
326 const int64_t tracknumber = track_number();
327 if (tracknumber > 0 && _session.config.get_track_name_number()) {
328 char num[64], fmt[10];
329 snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals());
330 snprintf(num, sizeof(num), fmt, tracknumber);
331 diskstream_name += num;
332 diskstream_name += "_";
334 diskstream_name += str;
336 if (diskstream_name == _diskstream_name) {
339 _diskstream_name = diskstream_name;
341 _disk_writer->set_write_source_name (diskstream_name);
343 boost::shared_ptr<Track> me = boost::dynamic_pointer_cast<Track> (shared_from_this ());
345 if (_playlists[data_type()]->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) {
346 /* Only rename the diskstream (and therefore the playlist) if
347 a) the playlist has never had a region added to it and
348 b) there is only one playlist for this track.
350 If (a) is not followed, people can get confused if, say,
351 they have notes about a playlist with a given name and then
352 it changes (see mantis #4759).
354 If (b) is not followed, we rename the current playlist and not
355 the other ones, which is a bit confusing (see mantis #4977).
357 _disk_reader->set_name (str);
358 _disk_writer->set_name (str);
361 for (uint32_t n = 0; n < DataType::num_types; ++n) {
363 _playlists[n]->set_name (str);
367 /* save state so that the statefile fully reflects any filename changes */
369 if ((ret = Route::set_name (str)) == 0) {
370 _session.save_state ("");
377 Track::set_latency_compensation (framecnt_t longest_session_latency)
379 Route::set_latency_compensation (longest_session_latency);
380 _disk_reader->set_roll_delay (_roll_delay);
384 Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing)
386 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
392 bool can_record = _session.actively_recording ();
394 /* no outputs? nothing to do ... what happens if we have sends etc. ? */
396 if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) {
397 //Note: Mixbus has its own output mechanism, so we should operate even if no explicit outputs are assigned
401 /* not active ... do the minimum possible by just outputting silence */
405 if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled())) {
411 if (session_state_changing) {
412 if (_session.transport_speed() != 0.0f) {
413 /* we're rolling but some state is changing (e.g. our
414 disk reader contents) so we cannot use them. Be
415 silent till this is over. Don't declick.
417 XXX note the absurdity of ::no_roll() being called when we ARE rolling!
419 passthru_silence (start_frame, end_frame, nframes, 0);
422 /* we're really not rolling, so we're either delivery silence or actually
423 monitoring, both of which are safe to do while session_state_changing is true.
427 _disk_writer->check_record_status (start_frame, can_record);
431 MonitorState const s = monitoring_state ();
432 /* we are not rolling, so be silent even if we are monitoring disk, as there
433 will be no disk data coming in.
436 case MonitoringSilence:
442 case MonitoringInput:
450 //if we have an internal generator, let it play regardless of monitoring state
451 if (_have_internal_generator) {
455 _amp->apply_gain_automation (false);
457 /* if have_internal_generator, or .. */
461 if (_meter_point == MeterInput) {
462 /* still need input monitoring and metering */
464 bool const track_rec = _disk_writer->record_enabled ();
465 bool const auto_input = _session.config.get_auto_input ();
466 bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
467 bool const tape_machine_mode = Config->get_tape_machine_mode ();
468 bool no_meter = false;
470 /* this needs a proper K-map
471 * and should be separated into a function similar to monitoring_state()
472 * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc
474 * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf
476 if (!auto_input && !track_rec) {
479 else if (tape_machine_mode && !track_rec && auto_input) {
482 else if (!software_monitor && tape_machine_mode && !track_rec) {
485 else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) {
490 BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
491 _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
492 _input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, _session.transport_speed(), nframes);
494 _input->process_input (_meter, start_frame, end_frame, _session.transport_speed(), nframes);
498 passthru_silence (start_frame, end_frame, nframes, 0);
502 BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
504 fill_buffers_with_input (bufs, _input, nframes);
506 if (_meter_point == MeterInput) {
507 _meter->run (bufs, start_frame, end_frame, _session.transport_speed(), nframes, true);
510 passthru (bufs, start_frame, end_frame, nframes, false);
513 flush_processor_buffers_locked (nframes);
519 Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler)
521 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
523 // XXX DISK reader needs to seek ahead the correct distance ?? OR DOES IT ?
524 //framecnt_t playback_distance = _disk_reader->calculate_playback_distance(nframes);
525 //if (can_internal_playback_seek(playback_distance)) {
526 // internal_playback_seek(playback_distance);
531 if (n_outputs().n_total() == 0 && _processors.empty()) {
541 _amp->apply_gain_automation(false);
544 flush_processor_buffers_locked (nframes);
546 //BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true));
547 // XXXX DISKWRITER/READER ADVANCE, SET need_butler
551 boost::shared_ptr<Playlist>
554 return _playlists[data_type()];
558 Track::request_input_monitoring (bool m)
560 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
561 AudioEngine::instance()->request_input_monitoring ((*i)->name(), m);
566 Track::ensure_input_monitoring (bool m)
568 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
569 AudioEngine::instance()->ensure_input_monitoring ((*i)->name(), m);
574 Track::destructive () const
576 return _disk_writer->destructive ();
579 list<boost::shared_ptr<Source> > &
580 Track::last_capture_sources ()
582 return _disk_writer->last_capture_sources ();
586 Track::set_capture_offset ()
588 _disk_writer->set_capture_offset ();
592 Track::steal_write_source_name()
594 return _disk_writer->steal_write_source_name ();
598 Track::reset_write_sources (bool r, bool force)
600 _disk_writer->reset_write_sources (r, force);
604 Track::playback_buffer_load () const
606 return _disk_reader->buffer_load ();
610 Track::capture_buffer_load () const
612 return _disk_writer->buffer_load ();
618 return _disk_reader->do_refill ();
622 Track::do_flush (RunContext c, bool force)
624 return _disk_writer->do_flush (c, force);
628 Track::set_pending_overwrite (bool o)
630 _disk_reader->set_pending_overwrite (o);
634 Track::seek (framepos_t p, bool complete_refill)
636 if (_disk_reader->seek (p, complete_refill)) {
639 return _disk_writer->seek (p, complete_refill);
643 Track::hidden () const
645 return _disk_writer->hidden () || _disk_reader->hidden();
649 Track::can_internal_playback_seek (framecnt_t p)
651 return _disk_reader->can_internal_playback_seek (p);
655 Track::internal_playback_seek (framecnt_t p)
657 return _disk_reader->internal_playback_seek (p);
661 Track::non_realtime_locate (framepos_t p)
663 Route::non_realtime_locate (p);
666 /* don't waste i/o cycles and butler calls
667 for hidden (secret) tracks
669 _disk_reader->non_realtime_locate (p);
670 _disk_writer->non_realtime_locate (p);
675 Track::non_realtime_set_speed ()
677 _disk_reader->non_realtime_set_speed ();
681 Track::overwrite_existing_buffers ()
683 return _disk_reader->overwrite_existing_buffers ();
687 Track::get_captured_frames (uint32_t n) const
689 return _disk_writer->get_captured_frames (n);
693 Track::set_loop (Location* l)
695 if (_disk_reader->set_loop (l)) {
698 return _disk_writer->set_loop (l);
702 Track::transport_looped (framepos_t p)
704 return _disk_writer->transport_looped (p);
708 Track::realtime_set_speed (double s, bool g)
710 if (_disk_reader->realtime_set_speed (s, g)) {
713 return _disk_writer->realtime_set_speed (s, g);
717 Track::realtime_handle_transport_stopped ()
719 Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
725 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
726 (*i)->realtime_handle_transport_stopped ();
731 Track::transport_stopped_wallclock (struct tm & n, time_t t, bool g)
733 _disk_writer->transport_stopped_wallclock (n, t, g);
737 Track::pending_overwrite () const
739 return _disk_reader->pending_overwrite ();
743 Track::prepare_to_stop (framepos_t t, framepos_t a)
745 _disk_writer->prepare_to_stop (t, a);
749 Track::set_slaved (bool s)
751 _disk_reader->set_slaved (s);
752 _disk_writer->set_slaved (s);
758 return _disk_reader->output_streams(); // XXX DISK
762 Track::get_capture_start_frame (uint32_t n) const
764 return _disk_writer->get_capture_start_frame (n);
768 Track::alignment_style () const
770 return _disk_writer->alignment_style ();
774 Track::alignment_choice () const
776 return _disk_writer->alignment_choice ();
780 Track::current_capture_start () const
782 return _disk_writer->current_capture_start ();
786 Track::current_capture_end () const
788 return _disk_writer->current_capture_end ();
792 Track::playlist_modified ()
794 _disk_reader->playlist_modified ();
798 Track::find_and_use_playlist (DataType dt, PBD::ID const & id)
800 boost::shared_ptr<Playlist> playlist;
802 if ((playlist = _session.playlists->by_id (id)) == 0) {
807 error << string_compose(_("DiskIOProcessor: \"%1\" isn't an playlist"), id.to_s()) << endmsg;
811 return use_playlist (dt, playlist);
815 Track::use_playlist (DataType dt, boost::shared_ptr<Playlist> p)
819 if ((ret = _disk_reader->use_playlist (dt, p)) == 0) {
820 if ((ret = _disk_writer->use_playlist (dt, p)) == 0) {
821 p->set_orig_track_id (id());
833 Track::use_copy_playlist ()
835 assert (_playlists[data_type()]);
837 if (_playlists[data_type()] == 0) {
838 error << string_compose(_("DiskIOProcessor %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
843 boost::shared_ptr<Playlist> playlist;
845 newname = Playlist::bump_name (_playlists[data_type()]->name(), _session);
847 if ((playlist = PlaylistFactory::create (_playlists[data_type()], newname)) == 0) {
851 playlist->reset_shares();
853 return use_playlist (data_type(), playlist);
857 Track::use_new_playlist ()
860 boost::shared_ptr<Playlist> playlist = _playlists[data_type()];
863 newname = Playlist::bump_name (playlist->name(), _session);
865 newname = Playlist::bump_name (_name, _session);
868 playlist = PlaylistFactory::create (data_type(), _session, newname, hidden());
874 return use_playlist (data_type(), playlist);
878 Track::set_align_style (AlignStyle s, bool force)
884 Track::set_align_choice (AlignChoice s, bool force)
890 Track::set_block_size (pframes_t n)
892 Route::set_block_size (n);
893 _disk_reader->set_block_size (n);
894 _disk_writer->set_block_size (n);
898 Track::adjust_playback_buffering ()
901 _disk_reader->adjust_buffering ();
906 Track::adjust_capture_buffering ()
909 _disk_writer->adjust_buffering ();
913 #ifdef USE_TRACKS_CODE_FEATURES
915 /* This is the Tracks version of Track::monitoring_state().
917 * Ardour developers: try to flag or fix issues if parts of the libardour API
918 * change in ways that invalidate this
922 Track::monitoring_state () const
924 /* Explicit requests */
926 if (_monitoring & MonitorInput) {
927 return MonitoringInput;
930 if (_monitoring & MonitorDisk) {
931 return MonitoringDisk;
934 /* This is an implementation of the truth table in doc/monitor_modes.pdf;
935 I don't think it's ever going to be too pretty too look at.
938 // GZ: NOT USED IN TRACKS
939 //bool const auto_input = _session.config.get_auto_input ();
940 //bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
941 //bool const tape_machine_mode = Config->get_tape_machine_mode ();
943 bool const roll = _session.transport_rolling ();
944 bool const track_rec = _diskstream->record_enabled ();
945 bool session_rec = _session.actively_recording ();
949 if (!session_rec && roll) {
950 return MonitoringDisk;
952 return MonitoringInput;
958 return MonitoringDisk;
962 return MonitoringSilence;
967 /* This is the Ardour/Mixbus version of Track::monitoring_state().
969 * Tracks developers: do NOT modify this method under any circumstances.
973 Track::monitoring_state () const
975 /* Explicit requests */
976 MonitorChoice m (_monitoring_control->monitoring_choice());
978 if (m & MonitorInput) {
979 return MonitoringInput;
982 if (m & MonitorDisk) {
983 return MonitoringDisk;
986 switch (_session.config.get_session_monitoring ()) {
988 return MonitoringDisk;
991 return MonitoringInput;
997 /* This is an implementation of the truth table in doc/monitor_modes.pdf;
998 I don't think it's ever going to be too pretty too look at.
1001 bool const roll = _session.transport_rolling ();
1002 bool const track_rec = _disk_writer->record_enabled ();
1003 bool const auto_input = _session.config.get_auto_input ();
1004 bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
1005 bool const tape_machine_mode = Config->get_tape_machine_mode ();
1008 /* I suspect that just use actively_recording() is good enough all the
1009 * time, but just to keep the semantics the same as they were before
1010 * sept 26th 2012, we differentiate between the cases where punch is
1011 * enabled and those where it is not.
1013 * rg: I suspect this is not the case: monitoring may differ
1016 if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_punch_enabled ()) {
1017 session_rec = _session.actively_recording ();
1019 session_rec = _session.get_record_enabled();
1024 if (!session_rec && roll && auto_input) {
1025 return MonitoringDisk;
1027 return software_monitor ? MonitoringInput : MonitoringSilence;
1032 if (tape_machine_mode) {
1034 return MonitoringDisk;
1038 if (!roll && auto_input) {
1039 return software_monitor ? MonitoringInput : MonitoringSilence;
1041 return MonitoringDisk;
1047 abort(); /* NOTREACHED */
1048 return MonitoringSilence;
1054 Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
1056 /* never declick if there is an internal generator - we just want it to
1057 keep generating sound without interruption.
1059 ditto if we are monitoring inputs.
1062 if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
1067 declick = _pending_declick;
1071 Amp::declick (bufs, nframes, declick);
1076 Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
1078 if (_roll_delay > nframes) {
1080 _roll_delay -= nframes;
1081 silence_unlocked (nframes);
1082 /* transport frame is not legal for caller to use */
1085 } else if (_roll_delay > 0) {
1087 nframes -= _roll_delay;
1088 silence_unlocked (_roll_delay);
1089 transport_frame += _roll_delay;
1091 /* shuffle all the port buffers for things that lead "out" of this Route
1092 to reflect that we just wrote _roll_delay frames of silence.
1095 Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
1096 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1097 boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
1099 iop->increment_port_buffer_offset (_roll_delay);
1102 _output->increment_port_buffer_offset (_roll_delay);
1112 Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
1114 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
1115 (*i)->monitoring_changed ();
1120 Track::metering_state () const
1123 if (_session.transport_rolling ()) {
1124 // audio_track.cc || midi_track.cc roll() runs meter IFF:
1125 rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _disk_writer->record_enabled());
1127 // track no_roll() always metering if
1128 rv = _meter_point == MeterInput;
1130 return rv ? MeteringInput : MeteringRoute;
1134 Track::set_processor_state (XMLNode const & node, XMLProperty const* prop, ProcessorList& new_order, bool& must_configure)
1136 if (Route::set_processor_state (node, prop, new_order, must_configure)) {
1140 if (prop->value() == "diskreader") {
1142 _disk_reader->set_state (node, Stateful::current_state_version);
1143 new_order.push_back (_disk_reader);
1146 } else if (prop->value() == "diskwriter") {
1148 _disk_writer->set_state (node, Stateful::current_state_version);
1149 new_order.push_back (_disk_writer);
1154 error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;