X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Froute.cc;h=8193d4ed77ae38929c502dd5f710e254e3ebe301;hb=f2aa62385872367b5402f13a0e02527c54589cd4;hp=d8ecabb1c077f292ada7fc808d03aecded539e45;hpb=05bcdd1d4c583c68ed977164913ff47e94df7adb;p=ardour.git diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index d8ecabb1c0..8193d4ed77 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -53,21 +53,21 @@ using namespace ARDOUR; using namespace PBD; uint32_t Route::order_key_cnt = 0; - +sigc::signal Route::SyncOrderKeys; Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type) : IO (sess, name, input_min, input_max, output_min, output_max, default_type), _flags (flg), - _solo_control (X_("solo"), *this, ToggleControllable::SoloControl), - _mute_control (X_("mute"), *this, ToggleControllable::MuteControl) + _solo_control (new ToggleControllable (X_("solo"), *this, ToggleControllable::SoloControl)), + _mute_control (new ToggleControllable (X_("mute"), *this, ToggleControllable::MuteControl)) { init (); } Route::Route (Session& sess, const XMLNode& node, DataType default_type) : IO (sess, *node.child ("IO"), default_type), - _solo_control (X_("solo"), *this, ToggleControllable::SoloControl), - _mute_control (X_("mute"), *this, ToggleControllable::MuteControl) + _solo_control (new ToggleControllable (X_("solo"), *this, ToggleControllable::SoloControl)), + _mute_control (new ToggleControllable (X_("mute"), *this, ToggleControllable::MuteControl)) { init (); _set_state (node, false); @@ -89,6 +89,7 @@ Route::init () _initial_delay = 0; _roll_delay = 0; _own_latency = 0; + _user_latency = 0; _have_internal_generator = false; _declickable = false; _pending_declick = true; @@ -160,9 +161,34 @@ void Route::set_order_key (const char* name, long n) { order_keys[strdup(name)] = n; + + if (Config->get_sync_all_route_ordering()) { + for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) { + x->second = n; + } + } + _session.set_dirty (); } +void +Route::sync_order_keys () +{ + uint32_t key; + + if (order_keys.empty()) { + return; + } + + OrderKeys::iterator x = order_keys.begin(); + key = x->second; + ++x; + + for (; x != order_keys.end(); ++x) { + x->second = key; + } +} + void Route::inc_gain (gain_t fraction, void *src) { @@ -176,33 +202,33 @@ Route::set_gain (gain_t val, void *src) if (_mix_group->is_relative()) { - - gain_t usable_gain = gain(); + gain_t usable_gain = gain(); if (usable_gain < 0.000001f) { - usable_gain=0.000001f; + usable_gain = 0.000001f; } gain_t delta = val; if (delta < 0.000001f) { - delta=0.000001f; + delta = 0.000001f; } delta -= usable_gain; - if (delta == 0.0f) return; + if (delta == 0.0f) + return; gain_t factor = delta / usable_gain; if (factor > 0.0f) { factor = _mix_group->get_max_factor(factor); if (factor == 0.0f) { - gain_changed (src); + _gain_control->Changed(); /* EMIT SIGNAL */ return; } } else { factor = _mix_group->get_min_factor(factor); if (factor == 0.0f) { - gain_changed (src); + _gain_control->Changed(); /* EMIT SIGNAL */ return; } } @@ -294,17 +320,17 @@ Route::process_output_buffers (BufferSet& bufs, -------------------------------------------------------------------------------------------------- */ if (declick > 0) { - Amp::run (bufs, nframes, 0.0, 1.0, false); + Amp::run_in_place (bufs, nframes, 0.0, 1.0, false); _pending_declick = 0; } else if (declick < 0) { - Amp::run (bufs, nframes, 1.0, 0.0, false); + Amp::run_in_place (bufs, nframes, 1.0, 0.0, false); _pending_declick = 0; } else { /* no global declick */ if (solo_gain != dsg) { - Amp::run (bufs, nframes, solo_gain, dsg, false); + Amp::run_in_place (bufs, nframes, solo_gain, dsg, false); solo_gain = dsg; } } @@ -315,11 +341,11 @@ Route::process_output_buffers (BufferSet& bufs, -------------------------------------------------------------------------------------------------- */ if (meter && (_meter_point == MeterInput)) { - _meter->run(bufs, start_frame, end_frame, nframes, offset); + _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); } if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) { - Amp::run (bufs, nframes, mute_gain, dmg, false); + Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -380,7 +406,7 @@ Route::process_output_buffers (BufferSet& bufs, for (i = _processors.begin(); i != _processors.end(); ++i) { switch ((*i)->placement()) { case PreFader: - (*i)->run (bufs, start_frame, end_frame, nframes, offset); + (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset); break; case PostFader: post_fader_work = true; @@ -406,7 +432,7 @@ Route::process_output_buffers (BufferSet& bufs, bufs.set_count(pre_fader_streams()); if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) { - Amp::run (bufs, nframes, mute_gain, dmg, false); + Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -416,7 +442,7 @@ Route::process_output_buffers (BufferSet& bufs, -------------------------------------------------------------------------------------------------- */ if (meter && (_meter_point == MeterPreFader)) { - _meter->run(bufs, start_frame, end_frame, nframes, offset); + _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); } @@ -459,13 +485,9 @@ Route::process_output_buffers (BufferSet& bufs, // OR recording - // h/w monitoring not in use - - (!Config->get_monitoring_model() == HardwareMonitoring && - // AND software monitoring required - Config->get_monitoring_model() == SoftwareMonitoring)) { + Config->get_monitoring_model() == SoftwareMonitoring) { if (apply_gain_automation) { @@ -497,7 +519,7 @@ Route::process_output_buffers (BufferSet& bufs, if (_gain != dg) { - Amp::run (bufs, nframes, _gain, dg, _phase_invert); + Amp::run_in_place (bufs, nframes, _gain, dg, _phase_invert); _gain = dg; } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) { @@ -550,7 +572,7 @@ Route::process_output_buffers (BufferSet& bufs, case PreFader: break; case PostFader: - (*i)->run (bufs, start_frame, end_frame, nframes, offset); + (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset); break; } } @@ -569,7 +591,7 @@ Route::process_output_buffers (BufferSet& bufs, } if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) { - Amp::run (bufs, nframes, mute_gain, dmg, false); + Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -614,7 +636,7 @@ Route::process_output_buffers (BufferSet& bufs, ----------------------------------------------------------------------*/ if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) { - Amp::run (bufs, nframes, mute_gain, dmg, false); + Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); mute_gain = dmg; mute_declick_applied = true; } @@ -676,7 +698,7 @@ Route::process_output_buffers (BufferSet& bufs, if ((_gain == 0 && !apply_gain_automation) || dmg == 0) { _meter->reset(); } else { - _meter->run(output_buffers(), start_frame, end_frame, nframes, offset); + _meter->run_in_place(output_buffers(), start_frame, end_frame, nframes, offset); } } } @@ -697,7 +719,7 @@ Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, collect_input (bufs, nframes, offset); if (meter_first) { - _meter->run(bufs, start_frame, end_frame, nframes, offset); + _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); meter_first = false; } @@ -725,7 +747,7 @@ Route::set_solo (bool yn, void *src) if (_soloed != yn) { _soloed = yn; solo_changed (src); /* EMIT SIGNAL */ - _solo_control.Changed (); /* EMIT SIGNAL */ + _solo_control->Changed (); /* EMIT SIGNAL */ } } @@ -762,7 +784,7 @@ Route::set_mute (bool yn, void *src) _muted = yn; mute_changed (src); /* EMIT SIGNAL */ - _mute_control.Changed (); /* EMIT SIGNAL */ + _mute_control->Changed (); /* EMIT SIGNAL */ Glib::Mutex::Lock lm (declick_lock); desired_mute_gain = (yn?0.0f:1.0f); @@ -812,6 +834,8 @@ Route::add_processor (boost::shared_ptr processor, ProcessorStreams* processor->activate (); processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false)); + + _user_latency = 0; } if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) { @@ -867,6 +891,8 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err) (*i)->activate (); (*i)->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false)); } + + _user_latency = 0; } if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) { @@ -1098,6 +1124,8 @@ Route::remove_processor (boost::shared_ptr processor, ProcessorStream removed = true; break; } + + _user_latency = 0; } if (!removed) { @@ -1214,6 +1242,8 @@ Route::apply_some_plugin_counts (list& iclist) for (i = iclist.begin(); i != iclist.end(); ++i) { + cerr << "now applying for " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl; + if ((*i).processor->configure_io ((*i).in, (*i).out)) { return -1; } @@ -1242,6 +1272,9 @@ Route::check_some_plugin_counts (list& iclist, ChanCount require for (i = iclist.begin(); i != iclist.end(); ++i) { + + cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n"; + if ((*i).processor->can_support_input_configuration (required_inputs) < 0) { if (err) { err->index = index; @@ -1253,6 +1286,8 @@ Route::check_some_plugin_counts (list& iclist, ChanCount require (*i).in = required_inputs; (*i).out = (*i).processor->output_for_input_configuration (required_inputs); + cerr << "config looks like " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl; + required_inputs = (*i).out; ++index; @@ -1337,6 +1372,7 @@ Route::copy_processors (const Route& other, Placement placement, ProcessorStream /* SUCCESSFUL COPY ATTEMPT: delete the processors we removed pre-copy */ to_be_deleted.clear (); + _user_latency = 0; } } @@ -1437,7 +1473,7 @@ XMLNode& Route::state(bool full_state) { XMLNode *node = new XMLNode("Route"); - ProcessorList:: iterator i; + ProcessorList::iterator i; char buf[32]; if (_flags) { @@ -1483,8 +1519,8 @@ Route::state(bool full_state) node->add_property ("order-keys", order_string); node->add_child_nocopy (IO::state (full_state)); - node->add_child_nocopy (_solo_control.get_state ()); - node->add_child_nocopy (_mute_control.get_state ()); + node->add_child_nocopy (_solo_control->get_state ()); + node->add_child_nocopy (_mute_control->get_state ()); XMLNode* remote_control_node = new XMLNode (X_("remote_control")); snprintf (buf, sizeof (buf), "%d", _remote_control_id); @@ -1845,12 +1881,12 @@ Route::_set_state (const XMLNode& node, bool call_base) } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) { if (prop->value() == "solo") { - _solo_control.set_state (*child); - _session.add_controllable (&_solo_control); + _solo_control->set_state (*child); + _session.add_controllable (_solo_control); } else if (prop->value() == "mute") { - _mute_control.set_state (*child); - _session.add_controllable (&_mute_control); + _mute_control->set_state (*child); + _session.add_controllable (_mute_control); } } else if (child->name() == X_("remote_control")) { @@ -2030,7 +2066,7 @@ Route::set_control_outs (const vector& ports) _control_outs = 0; } - if (control() || master()) { + if (is_control() || is_master()) { /* no control outs for these two special busses */ return 0; } @@ -2059,7 +2095,7 @@ Route::set_control_outs (const vector& ports) /* now connect to the named ports */ for (size_t n = 0; n < limit; ++n) { - if (_control_outs->connect_output (_control_outs->output (n), ports[n], this)) { + if (_control_outs->connect_output (_control_outs->output (n), ports[n % ports.size()], this)) { error << string_compose (_("could not connect %1 to %2"), _control_outs->output(n)->name(), ports[n]) << endmsg; return -1; } @@ -2300,7 +2336,7 @@ Route::pans_required () const return 0; } - return max (n_inputs ().n_audio(), static_cast(processor_max_outs.n_audio())); + return max (n_inputs ().n_audio(), processor_max_outs.n_audio()); } int @@ -2385,10 +2421,9 @@ Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nfra if (am.locked() && _session.transport_rolling()) { - ARDOUR::AutomationList& gain_auto = gain_automation(); - - if (gain_auto.automation_playback()) { - apply_gain_automation = gain_auto.curve().rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes); + if (_gain_control->list()->automation_playback()) { + apply_gain_automation = _gain_control->list()->curve().rt_safe_get_vector ( + start_frame, end_frame, _session.gain_automation_buffer(), nframes); } } } @@ -2470,32 +2505,62 @@ Route::set_meter_point (MeterPoint p, void *src) nframes_t Route::update_total_latency () { - _own_latency = 0; + nframes_t old = _own_latency; - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->active ()) { - _own_latency += (*i)->latency (); + if (_user_latency) { + _own_latency = _user_latency; + } else { + _own_latency = 0; + + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + if ((*i)->active ()) { + _own_latency += (*i)->signal_latency (); + } } } set_port_latency (_own_latency); + + if (!_user_latency) { + /* this (virtual) function is used for pure Routes, + not derived classes like AudioTrack. this means + that the data processed here comes from an input + port, not prerecorded material, and therefore we + have to take into account any input latency. + */ - /* this (virtual) function is used for pure Routes, - not derived classes like AudioTrack. this means - that the data processed here comes from an input - port, not prerecorded material, and therefore we - have to take into account any input latency. - */ - _own_latency += input_latency (); + _own_latency += input_latency (); + } + if (old != _own_latency) { + signal_latency_changed (); /* EMIT SIGNAL */ + } + return _own_latency; } +void +Route::set_user_latency (nframes_t nframes) +{ + Latent::set_user_latency (nframes); + _session.update_latency_compensation (false, false); +} + void Route::set_latency_delay (nframes_t longest_session_latency) { - _initial_delay = longest_session_latency - _own_latency; + nframes_t old = _initial_delay; + + if (_own_latency < longest_session_latency) { + _initial_delay = longest_session_latency - _own_latency; + } else { + _initial_delay = 0; + } + + if (_initial_delay != old) { + initial_delay_changed (); /* EMIT SIGNAL */ + } if (_session.transport_stopped()) { _roll_delay = _initial_delay;