X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftrack.cc;h=57239cb841a35201f9d9438bdee416e984978e3f;hb=97a537cd2138dea1c64d01c5a0fa0f9335893c19;hp=452a0843e28f06d6189f2f7e9d9e487163d29e0d;hpb=0532e2063b73ec32d4dd108b58e90a0f20ae91b3;p=ardour.git diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 452a0843e2..57239cb841 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -46,8 +46,6 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data { _freeze_record.state = NoFreeze; _declickable = true; - - Config->ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1)); } Track::~Track () @@ -100,19 +98,6 @@ Track::state (bool full) 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 (_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; } @@ -152,18 +137,6 @@ Track::set_state (const XMLNode& node, int version) _rec_enable_control->set_state (*child, version); } } - - 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); - } - } - } } const XMLProperty* prop; @@ -250,35 +223,8 @@ 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) +Track::prep_record_enabled (bool yn, void *src) { if (!_session.writable()) { return; @@ -289,7 +235,7 @@ Track::set_record_enabled (bool yn, void *src) } if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) { - _route_group->apply (&Track::set_record_enabled, yn, _route_group); + _route_group->apply (&Track::prep_record_enabled, yn, _route_group); return; } @@ -298,28 +244,46 @@ 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); +void +Track::set_record_enabled (bool yn, void *src) +{ + if (!_session.writable()) { + return; + } - if (_diskstream->record_enabled()) { - if (_meter_point != MeterCustom) { - set_meter_point (MeterInput); - } - } else { - set_meter_point (_saved_meter_point); + if (_freeze_record.state == Frozen) { + return; } + 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; + } + + _diskstream->set_record_enabled (yn); + _rec_enable_control->Changed (); } - bool Track::set_name (const string& str) { @@ -365,19 +329,27 @@ 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 (); + /* no outputs? nothing to do ... what happens if we have sends etc. ? */ + if (n_outputs().n_total() == 0) { return 0; } + /* not active ... do the minimum possible by just outputting silence */ + if (!_active) { silence (nframes); + if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) { + _meter->reset(); + } return 0; } @@ -406,33 +378,88 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, into the route. */ 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); - } - - if (!_have_internal_generator && metering_state() == MeteringInput) { - _input->process_input (_meter, start_frame, end_frame, nframes); + switch (s) { + case MonitoringSilence: + /* if there is an instrument, be_silent should always + be false + */ + be_silent = (the_instrument_unlocked() == 0); + break; + case MonitoringDisk: + be_silent = true; + break; + case MonitoringInput: + be_silent = false; + break; + default: + be_silent = false; + break; + } } - _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, 0, 0, nframes, true); + _input->process_input (boost::shared_ptr(), start_frame, end_frame, nframes); + } else { + _input->process_input (_meter, start_frame, end_frame, 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()); + + fill_buffers_with_input (bufs, _input, nframes); + + if (_meter_point == MeterInput) { + _meter->run (bufs, start_frame, end_frame, nframes, true); + } - passthru (start_frame, end_frame, nframes, false); + passthru (bufs, start_frame, end_frame, nframes, false); } for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { @@ -448,8 +475,12 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, 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; } @@ -468,7 +499,10 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /* silence (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; } @@ -516,15 +550,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 @@ -832,10 +866,22 @@ Track::monitoring_state () const 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. + */ + + 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) { @@ -908,7 +954,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) { @@ -938,24 +984,17 @@ Track::set_monitoring (MonitorChoice mc) } } -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 & MonitorInput || _diskstream->record_enabled()); + } else { + // track no_roll() always metering if + rv = _meter_point == MeterInput; + } + return rv ? MeteringInput : MeteringRoute; } +