X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftrack.cc;h=d7d9a0a9d14686b04ba78f8aba3521367b4d36e1;hb=1399ef391de5b05888ea2e13e6ff80f14b6e84d9;hp=7f307f3edc745563d7ecef5a132ba25893ffdd40;hpb=f2f35e50a0e2d6e0b2c7f02b5e6c76e82643c80a;p=ardour.git diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 7f307f3edc..d7d9a0a9d1 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -21,32 +21,36 @@ #include "ardour/debug.h" #include "ardour/delivery.h" #include "ardour/diskstream.h" +#include "ardour/event_type_map.h" #include "ardour/io_processor.h" #include "ardour/meter.h" +#include "ardour/monitor_control.h" #include "ardour/playlist.h" #include "ardour/port.h" #include "ardour/processor.h" +#include "ardour/profile.h" +#include "ardour/record_enable_control.h" +#include "ardour/record_safe_control.h" #include "ardour/route_group_specialized.h" #include "ardour/session.h" +#include "ardour/session_playlists.h" #include "ardour/track.h" +#include "ardour/types_convert.h" #include "ardour/utils.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; -Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type) +Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type) : Route (sess, name, flag, default_type) , _saved_meter_point (_meter_point) , _mode (mode) - , _monitoring (MonitorAuto) { _freeze_record.state = NoFreeze; _declickable = true; - - Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1)); } Track::~Track () @@ -61,14 +65,23 @@ Track::init () return -1; } - boost::shared_ptr rp (shared_from_this()); + boost::shared_ptr rp (boost::dynamic_pointer_cast (shared_from_this())); boost::shared_ptr rt = boost::dynamic_pointer_cast (rp); - _rec_enable_control = boost::shared_ptr (new RecEnableControl(rt)); - _rec_enable_control->set_flags (Controllable::Toggle); - /* don't add rec_enable_control to controls because we don't want it to - * appear as an automatable parameter - */ + _record_enable_control.reset (new RecordEnableControl (_session, EventTypeMap::instance().to_symbol (RecEnableAutomation), *this)); + add_control (_record_enable_control); + + _record_safe_control.reset (new RecordSafeControl (_session, EventTypeMap::instance().to_symbol (RecSafeAutomation), *this)); + add_control (_record_safe_control); + + _monitoring_control.reset (new MonitorControl (_session, EventTypeMap::instance().to_symbol (MonitoringAutomation), *this)); + add_control (_monitoring_control); + + _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1)); + + _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2)); + _record_safe_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_safe_changed, this, _1, _2)); + _record_enable_control->Changed.connect_same_thread (*this, boost::bind (&Track::record_enable_changed, this, _1, _2)); return 0; } @@ -95,36 +108,26 @@ XMLNode& Track::state (bool full) { XMLNode& root (Route::state (full)); - root.add_property (X_("monitoring"), enum_2_string (_monitoring)); - root.add_property (X_("saved-meter-point"), enum_2_string (_saved_meter_point)); - root.add_child_nocopy (_rec_enable_control->get_state()); + + root.add_child_nocopy (_monitoring_control->get_state ()); + root.add_child_nocopy (_record_safe_control->get_state ()); + root.add_child_nocopy (_record_enable_control->get_state ()); + + root.set_property (X_("saved-meter-point"), _saved_meter_point); root.add_child_nocopy (_diskstream->get_state ()); - if (!_deactivated_processors.empty ()) { - XMLNode* node = new XMLNode (X_("DeactivatedProcessors")); - for (list >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) { - boost::shared_ptr p = i->lock (); - if (p) { - XMLNode* c = new XMLNode (X_("Processor")); - c->add_property (X_("id"), p->id().to_s()); - node->add_child_nocopy (*c); - } - } - root.add_child_nocopy (*node); - } - return root; -} +} int Track::set_state (const XMLNode& node, int version) { + if (Route::set_state (node, version)) { + return -1; + } + XMLNode* child; - /* Create the diskstream before calling Route::set_state, as MidiTrack - needs it if the track is muted (it ends up calling MidiTrack::get_channel_mask) - */ - if (version >= 3000) { if ((child = find_named_node (node, X_("Diskstream"))) != 0) { boost::shared_ptr ds = diskstream_factory (*child); @@ -133,10 +136,6 @@ Track::set_state (const XMLNode& node, int version) } } - if (Route::set_state (node, version)) { - return -1; - } - if (_diskstream) { _diskstream->playlist()->set_orig_track_id (id()); } @@ -149,37 +148,32 @@ Track::set_state (const XMLNode& node, int version) for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { child = *niter; - XMLProperty* prop; - if (child->name() == Controllable::xml_node_name && (prop = child->property ("name")) != 0) { - if (prop->value() == X_("recenable")) { - _rec_enable_control->set_state (*child, version); + if (child->name() == Controllable::xml_node_name) { + std::string name; + if (!child->get_property ("name", name)) { + continue; } - } - if (child->name() == X_("DeactivatedProcessors")) { - XMLNodeList dp = child->children (); - for (XMLNodeConstIterator i = dp.begin(); i != dp.end(); ++i) { - assert ((*i)->name() == X_("Processor")); - XMLProperty* prop = (*i)->property (X_("id")); - boost::shared_ptr p = processor_by_id (PBD::ID (prop->value ())); - if (p) { - _deactivated_processors.push_back (p); - } + if (name == _record_enable_control->name()) { + _record_enable_control->set_state (*child, version); + } else if (name == _record_safe_control->name()) { + _record_safe_control->set_state (*child, version); + } else if (name == _monitoring_control->name()) { + _monitoring_control->set_state (*child, version); } } } - - const XMLProperty* prop; - if ((prop = node.property (X_("monitoring"))) != 0) { - _monitoring = MonitorChoice (string_2_enum (prop->value(), _monitoring)); - } else { - _monitoring = MonitorAuto; + /* convert old 3001 state */ + MonitorChoice monitoring; + if (node.get_property (X_("monitoring"), monitoring)) { + XMLNode mon_node ("backwardscompat"); + mon_node.set_property (X_("monitoring"), monitoring); + mon_node.set_property (X_("value"), (int) monitoring); + _monitoring_control->set_state (mon_node, version); } - if ((prop = node.property (X_("saved-meter-point"))) != 0) { - _saved_meter_point = MeterPoint (string_2_enum (prop->value(), _saved_meter_point)); - } else { + if (!node.get_property (X_("saved-meter-point"), _saved_meter_point)) { _saved_meter_point = _meter_point; } @@ -205,42 +199,6 @@ Track::freeze_state() const return _freeze_record.state; } -Track::RecEnableControl::RecEnableControl (boost::shared_ptr t) - : AutomationControl (t->session(), RecEnableAutomation, boost::shared_ptr(), X_("recenable")) - , track (t) -{ - boost::shared_ptr gl(new AutomationList(Evoral::Parameter(RecEnableAutomation))); - set_list (gl); -} - -void -Track::RecEnableControl::set_value (double val) -{ - boost::shared_ptr t = track.lock (); - if (!t) { - return; - } - - t->set_record_enabled (val >= 0.5 ? true : false, this); -} - -double -Track::RecEnableControl::get_value () const -{ - boost::shared_ptr t = track.lock (); - if (!t) { - return 0; - } - - return (t->record_enabled() ? 1.0 : 0.0); -} - -bool -Track::record_enabled () const -{ - return _diskstream && _diskstream->record_enabled (); -} - bool Track::can_record() { @@ -253,47 +211,15 @@ Track::can_record() return will_record; } -/* Turn off visible processors (except Fader), keeping track of the old states */ -void -Track::deactivate_visible_processors () -{ - _deactivated_processors.clear (); - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->active() && (*i)->display_to_user() && boost::dynamic_pointer_cast (*i) == 0) { - (*i)->deactivate (); - _deactivated_processors.push_back (*i); - } - } -} - -/* Turn deactivated processors back on again */ -void -Track::activate_deactivated_processors () -{ - for (list >::iterator i = _deactivated_processors.begin(); i != _deactivated_processors.end(); ++i) { - boost::shared_ptr p = i->lock (); - if (p) { - p->activate (); - } - } -} - -void -Track::set_record_enabled (bool yn, void *src) +int +Track::prep_record_enabled (bool yn) { - if (!_session.writable()) { - return; - } - - if (_freeze_record.state == Frozen) { - return; + if (yn && _record_safe_control->get_value()) { + return -1; } - if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) { - _route_group->apply (&Track::set_record_enabled, yn, _route_group); - return; + if (!can_be_record_enabled()) { + return -1; } /* keep track of the meter point as it was before we rec-enabled */ @@ -301,44 +227,122 @@ Track::set_record_enabled (bool yn, void *src) _saved_meter_point = _meter_point; } - if (Config->get_do_not_record_plugins ()) { + bool will_follow; + + if (yn) { + will_follow = _diskstream->prep_record_enable (); + } else { + will_follow = _diskstream->prep_record_disable (); + } + + if (will_follow) { if (yn) { - deactivate_visible_processors (); + if (_meter_point != MeterCustom) { + set_meter_point (MeterInput); + } } else { - activate_deactivated_processors (); + set_meter_point (_saved_meter_point); } } - _diskstream->set_record_enabled (yn); + return 0; +} - if (_diskstream->record_enabled()) { - if (_meter_point != MeterCustom) { - set_meter_point (MeterInput); +void +Track::record_enable_changed (bool, Controllable::GroupControlDisposition) +{ + _diskstream->set_record_enabled (_record_enable_control->get_value()); +} + +void +Track::record_safe_changed (bool, Controllable::GroupControlDisposition) +{ + _diskstream->set_record_safe (_record_safe_control->get_value()); +} + +bool +Track::can_be_record_safe () +{ + return !_record_enable_control->get_value() && _diskstream && _session.writable() && (_freeze_record.state != Frozen); +} + +bool +Track::can_be_record_enabled () +{ + return !_record_safe_control->get_value() && _diskstream && !_diskstream->record_safe() && _session.writable() && (_freeze_record.state != Frozen); +} + +void +Track::parameter_changed (string const & p) +{ + if (p == "track-name-number") { + resync_track_name (); + } + else if (p == "track-name-take") { + resync_track_name (); + } + else if (p == "take-name") { + if (_session.config.get_track_name_take()) { + resync_track_name (); } - } else { - set_meter_point (_saved_meter_point); } - - _rec_enable_control->Changed (); } +void +Track::resync_track_name () +{ + set_name(name()); +} bool Track::set_name (const string& str) { bool ret; - if (record_enabled() && _session.actively_recording()) { - /* this messes things up if done while recording */ + if (str.empty ()) { + return false; + } + + if (_record_enable_control->get_value()) { + /* when re-arm'ed the file (named after the track) is already ready to rolll */ return false; } - if (_diskstream->playlist()->all_regions_empty ()) { + string diskstream_name = ""; + if (_session.config.get_track_name_take () && !_session.config.get_take_name ().empty()) { + // Note: any text is fine, legalize_for_path() fixes this later + diskstream_name += _session.config.get_take_name (); + diskstream_name += "_"; + } + const int64_t tracknumber = track_number(); + if (tracknumber > 0 && _session.config.get_track_name_number()) { + char num[64], fmt[10]; + snprintf(fmt, sizeof(fmt), "%%0%d" PRId64, _session.track_number_decimals()); + snprintf(num, sizeof(num), fmt, tracknumber); + diskstream_name += num; + diskstream_name += "_"; + } + diskstream_name += str; + + if (diskstream_name == _diskstream_name) { + return true; + } + _diskstream_name = diskstream_name; + + _diskstream->set_write_source_name (diskstream_name); + + boost::shared_ptr me = boost::dynamic_pointer_cast (shared_from_this ()); + if (_diskstream->playlist()->all_regions_empty () && _session.playlists->playlists_for_track (me).size() == 1) { /* Only rename the diskstream (and therefore the playlist) if - the playlist has never had a region added to it. Otherwise - people can get confused if, say, they have notes about a - playlist with a given name and then it changes (see mantis - #4759). + a) the playlist has never had a region added to it and + b) there is only one playlist for this track. + + If (a) is not followed, people can get confused if, say, + they have notes about a playlist with a given name and then + it changes (see mantis #4759). + + If (b) is not followed, we rename the current playlist and not + the other ones, which is a bit confusing (see mantis #4977). */ _diskstream->set_name (str); } @@ -362,19 +366,28 @@ Track::set_latency_compensation (framecnt_t longest_session_latency) int Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool session_state_changing) { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); + if (!lm.locked()) { return 0; } bool can_record = _session.actively_recording (); - if (n_outputs().n_total() == 0) { + /* no outputs? nothing to do ... what happens if we have sends etc. ? */ + + if (n_outputs().n_total() == 0 && !ARDOUR::Profile->get_mixbus()) { + //Note: Mixbus has its own output mechanism, so we should operate even if no explicit outputs are assigned return 0; } + /* not active ... do the minimum possible by just outputting silence */ + if (!_active) { silence (nframes); + if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) { + _meter->reset(); + } return 0; } @@ -397,56 +410,102 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, bool be_silent; - if (_have_internal_generator) { - /* since the instrument has no input streams, - there is no reason to send any signal - into the route. - */ + MonitorState const s = monitoring_state (); + /* we are not rolling, so be silent even if we are monitoring disk, as there + will be no disk data coming in. + */ + switch (s) { + case MonitoringSilence: be_silent = true; - } else { - MonitorState const s = monitoring_state (); - /* we are not rolling, so be silent even if we are monitoring disk, as there - will be no disk data coming in. - */ - be_silent = (s == MonitoringSilence || s == MonitoringDisk); + break; + case MonitoringDisk: + be_silent = true; + break; + case MonitoringInput: + be_silent = false; + break; + default: + be_silent = false; + break; } - - if (!_have_internal_generator && metering_state() == MeteringInput) { - _input->process_input (_meter, start_frame, end_frame, nframes); + + //if we have an internal generator, let it play regardless of monitoring state + if (_have_internal_generator) { + be_silent = false; } - _amp->apply_gain_automation(false); + _amp->apply_gain_automation (false); /* if have_internal_generator, or .. */ - //_input->process_input (_meter, start_frame, end_frame, nframes); if (be_silent) { + if (_meter_point == MeterInput) { + /* still need input monitoring and metering */ + + 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 no_meter = false; + + /* this needs a proper K-map + * and should be separated into a function similar to monitoring_state() + * that also handles roll() states in audio_track.cc, midi_track.cc and route.cc + * + * see http://www.oofus.co.uk/ardour/Ardour3MonitorModesV3.pdf + */ + if (!auto_input && !track_rec) { + no_meter=true; + } + else if (tape_machine_mode && !track_rec && auto_input) { + no_meter=true; + } + else if (!software_monitor && tape_machine_mode && !track_rec) { + no_meter=true; + } + else if (!software_monitor && !tape_machine_mode && !track_rec && !auto_input) { + no_meter=true; + } + + if (no_meter) { + BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); + _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true); + _input->process_input (boost::shared_ptr(), start_frame, end_frame, speed(), nframes); + } else { + _input->process_input (_meter, start_frame, end_frame, speed(), nframes); + } + } + passthru_silence (start_frame, end_frame, nframes, 0); } else { - /* we're sending signal, but we may still want to meter the input. - */ + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); - passthru (start_frame, end_frame, nframes, false); - } + fill_buffers_with_input (bufs, _input, nframes); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr d = boost::dynamic_pointer_cast (*i); - if (d) { - d->flush_buffers (nframes); + if (_meter_point == MeterInput) { + _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true); } + + passthru (bufs, start_frame, end_frame, nframes, false); } + flush_processor_buffers_locked (nframes); + return 0; } int Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, bool& need_butler) { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { + framecnt_t playback_distance = _diskstream->calculate_playback_distance(nframes); + if (can_internal_playback_seek(playback_distance)) { + internal_playback_seek(playback_distance); + } return 0; } @@ -463,9 +522,13 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /* _amp->apply_gain_automation(false); silence (nframes); + flush_processor_buffers_locked (nframes); framecnt_t playback_distance; - int const dret = _diskstream->process (_session.transport_frame(), nframes, playback_distance); + + BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true)); + + int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false); need_butler = _diskstream->commit (playback_distance); return dret; } @@ -477,7 +540,6 @@ Track::set_diskstream (boost::shared_ptr ds) ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this)); diskstream_playlist_changed (); - ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this)); ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this)); ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this)); } @@ -488,12 +550,6 @@ Track::diskstream_playlist_changed () PlaylistChanged (); /* EMIT SIGNAL */ } -void -Track::diskstream_record_enable_changed () -{ - RecordEnableChanged (); /* EMIT SIGNAL */ -} - void Track::diskstream_speed_changed () { @@ -513,15 +569,15 @@ Track::playlist () } void -Track::request_jack_monitors_input (bool m) +Track::request_input_monitoring (bool m) { - _diskstream->request_jack_monitors_input (m); + _diskstream->request_input_monitoring (m); } void -Track::ensure_jack_monitors_input (bool m) +Track::ensure_input_monitoring (bool m) { - _diskstream->ensure_jack_monitors_input (m); + _diskstream->ensure_input_monitoring (m); } bool @@ -542,10 +598,10 @@ Track::set_capture_offset () _diskstream->set_capture_offset (); } -list > -Track::steal_write_sources() +std::string +Track::steal_write_source_name() { - return _diskstream->steal_write_sources (); + return _diskstream->steal_write_source_name (); } void @@ -617,7 +673,14 @@ Track::non_realtime_input_change () void Track::non_realtime_locate (framepos_t p) { - _diskstream->non_realtime_locate (p); + Route::non_realtime_locate (p); + + if (!hidden()) { + /* don't waste i/o cycles and butler calls + for hidden (secret) tracks + */ + _diskstream->non_realtime_locate (p); + } } void @@ -675,9 +738,9 @@ Track::speed () const } void -Track::prepare_to_stop (framepos_t p) +Track::prepare_to_stop (framepos_t t, framepos_t a) { - _diskstream->prepare_to_stop (p); + _diskstream->prepare_to_stop (t, a); } void @@ -803,15 +866,23 @@ Track::adjust_capture_buffering () } } +#ifdef USE_TRACKS_CODE_FEATURES + +/* This is the Tracks version of Track::monitoring_state(). + * + * Ardour developers: try to flag or fix issues if parts of the libardour API + * change in ways that invalidate this + */ + MonitorState Track::monitoring_state () const { /* Explicit requests */ - + if (_monitoring & MonitorInput) { return MonitoringInput; } - + if (_monitoring & MonitorDisk) { return MonitoringDisk; } @@ -820,12 +891,89 @@ Track::monitoring_state () const I don't think it's ever going to be too pretty too look at. */ + // GZ: NOT USED IN TRACKS + //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 const roll = _session.transport_rolling (); + bool const track_rec = _diskstream->record_enabled (); + bool session_rec = _session.actively_recording (); + + if (track_rec) { + + if (!session_rec && roll) { + return MonitoringDisk; + } else { + return MonitoringInput; + } + + } else { + + if (roll) { + return MonitoringDisk; + } + } + + return MonitoringSilence; +} + +#else + +/* This is the Ardour/Mixbus version of Track::monitoring_state(). + * + * Tracks developers: do NOT modify this method under any circumstances. + */ + +MonitorState +Track::monitoring_state () const +{ + /* Explicit requests */ + MonitorChoice m (_monitoring_control->monitoring_choice()); + + if (m & MonitorInput) { + return MonitoringInput; + } + + if (m & MonitorDisk) { + return MonitoringDisk; + } + + switch (_session.config.get_session_monitoring ()) { + case MonitorDisk: + return MonitoringDisk; + break; + case MonitorInput: + return MonitoringInput; + break; + default: + break; + } + + /* 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 session_rec = _session.get_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. + * + * rg: I suspect this is not the case: monitoring may differ + */ + + if (_session.config.get_punch_in() || _session.config.get_punch_out() || _session.preroll_record_punch_enabled ()) { + session_rec = _session.actively_recording (); + } else { + session_rec = _session.get_record_enabled(); + } if (track_rec) { @@ -848,14 +996,16 @@ Track::monitoring_state () const } else { return MonitoringDisk; } - + } } - /* NOTREACHED */ + abort(); /* NOTREACHED */ return MonitoringSilence; } +#endif + void Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick) { @@ -865,7 +1015,7 @@ Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick) ditto if we are monitoring inputs. */ - if (_have_internal_generator || monitoring_choice() == MonitorInput) { + if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) { return; } @@ -898,7 +1048,7 @@ Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame) to reflect that we just wrote _roll_delay frames of silence. */ - Glib::RWLock::ReaderLock lm (_processor_lock); + Glib::Threads::RWLock::ReaderLock lm (_processor_lock); for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { boost::shared_ptr iop = boost::dynamic_pointer_cast (*i); if (iop) { @@ -911,41 +1061,27 @@ Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame) } - return nframes; + return nframes; } void -Track::set_monitoring (MonitorChoice mc) +Track::monitoring_changed (bool, Controllable::GroupControlDisposition) { - if (mc != _monitoring) { - _monitoring = mc; - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->monitoring_changed (); - } - - MonitoringChanged (); /* EMIT SIGNAL */ + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + (*i)->monitoring_changed (); } } -void -Track::parameter_changed (string p) -{ - if (p != "do-not-record-plugins") { - return; - } - - if (record_enabled ()) { - if (Config->get_do_not_record_plugins ()) { - deactivate_visible_processors (); - } else { - activate_deactivated_processors (); - } - } -} - MeterState Track::metering_state () const { - return _diskstream->record_enabled() ? MeteringInput : MeteringRoute; + bool rv; + if (_session.transport_rolling ()) { + // audio_track.cc || midi_track.cc roll() runs meter IFF: + rv = _meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled()); + } else { + // track no_roll() always metering if + rv = _meter_point == MeterInput; + } + return rv ? MeteringInput : MeteringRoute; }