From 1e4c1388c32d76c99f111b58b0820b8d1ecd6fbe Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 14 Mar 2011 20:33:47 +0000 Subject: more fun and games with latency compensation, and so forth ... not done yet git-svn-id: svn://localhost/ardour2/branches/3.0@9149 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/session.h | 34 +++-- libs/ardour/audio_diskstream.cc | 13 +- libs/ardour/port.cc | 33 +++-- libs/ardour/route.cc | 14 +- libs/ardour/session.cc | 269 +++++++++++++++++++++++++++++---------- libs/ardour/session_state.cc | 4 +- libs/ardour/session_transport.cc | 70 +--------- 7 files changed, 279 insertions(+), 158 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index f5b6db4448..c67e3d10fe 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -820,7 +820,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi protected: friend class Route; void schedule_curve_reallocation (); - void update_latency_compensation (bool, bool, bool force=false); + void update_latency_compensation (bool force = false); private: int create (const std::string& mix_template, BusProfile*); @@ -880,9 +880,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool _was_seamless; void set_worst_io_latencies (); + void set_worst_playback_latency (); + void set_worst_capture_latency (); void set_worst_io_latencies_x (IOChange, void *) { set_worst_io_latencies (); } + void post_capture_latency (); + void post_playback_latency (); void update_latency_compensation_proxy (void* ignored); @@ -1208,7 +1212,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi SerializedRCUManager routes; - void add_routes (RouteList&, bool save); + void add_routes (RouteList&, bool auto_connect, bool save); uint32_t destructive_index; boost::shared_ptr XMLRouteFactory (const XMLNode&, int); @@ -1218,14 +1222,24 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool find_route_name (std::string const &, uint32_t& id, char* name, size_t name_len, bool); void count_existing_route_channels (ChanCount& in, ChanCount& out); - void auto_connect_route ( - Route* route, - ChanCount& existing_inputs, - ChanCount& existing_outputs, - bool connect_inputs = true, - ChanCount input_start = ChanCount (), - ChanCount output_start = ChanCount () - ); + void auto_connect_route (Route*, + ChanCount& existing_inputs, + ChanCount& existing_outputs, + bool with_lock, + bool connect_inputs = true, + ChanCount input_start = ChanCount (), + ChanCount output_start = ChanCount ()); + + void auto_connect_route (boost::shared_ptr route, + ChanCount& existing_inputs, + ChanCount& existing_outputs, + bool with_lock, + bool connect_inputs = true, + ChanCount input_start = ChanCount (), + ChanCount output_start = ChanCount ()) { + auto_connect_route (route.get(), existing_inputs, existing_outputs, with_lock, connect_inputs, input_start, output_start); + } + /* mixer stuff */ diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 5eba4cb822..d7d0b8513a 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -174,11 +174,11 @@ AudioDiskstream::non_realtime_input_change () remove_channel_from (c, _n_channels.n_audio() - _io->n_ports().n_audio()); } } - + get_input_sources (); set_capture_offset (); set_align_style_from_io (); - + input_change_pending = IOChange::NoChange; /* implicit unlock */ @@ -223,8 +223,11 @@ AudioDiskstream::get_input_sources () connections.clear (); + cerr << "Getting Nth connection from io " << n << " = " << _io->nth(n) << endl; + if (_io->nth (n)->get_connections (connections) == 0) { + cerr << "\tThere were NO connections, apparently ...\n"; if ((*chan)->source) { // _source->disable_metering (); } @@ -232,6 +235,7 @@ AudioDiskstream::get_input_sources () (*chan)->source = 0; } else { + cerr << "\tThere were some connections, apparently ... to " << connections[0] << endl; (*chan)->source = dynamic_cast(_session.engine().get_port_by_name (connections[0]) ); } } @@ -2012,12 +2016,17 @@ AudioDiskstream::set_align_style_from_io () boost::shared_ptr c = channels.reader(); + cerr << "Checking " << c->size() << " for physical connections\n"; + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + cerr << "Channel connected via " << (*chan)->source << endl; if ((*chan)->source && (*chan)->source->flags() & JackPortIsPhysical) { + cerr << "\tchannel has physical connection to " << (*chan)->source->name() << endl; have_physical = true; break; } } + cerr << "\tphysical? " << have_physical << endl; if (have_physical) { set_align_style (ExistingMaterial); diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index da3e5f037d..a2fe3ab06d 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -51,6 +51,10 @@ Port::Port (std::string const & n, DataType t, Flags f) , _flags (f) , _last_monitor (false) { + _private_playback_latency.min = 0; + _private_playback_latency.max = 0; + _private_capture_latency.min = 0; + _private_capture_latency.max = 0; /* Unfortunately we have to pass the DataType into this constructor so that we can create the right kind of JACK port; aside from this we'll use the virtual function type () @@ -242,8 +246,8 @@ Port::set_public_latency_range (jack_latency_range_t& range, bool playback) cons if (!jack_port_set_latency_range) { return; } - - DEBUG_TRACE (DEBUG::Latency, string_compose ("PORT %1 %4 latency now [%2 - %3]\n", name(), + + DEBUG_TRACE (DEBUG::Latency, string_compose ("SET PORT %1 %4 PUBLIC latency now [%2 - %3]\n", name(), range.min, range.max, (playback ? "PLAYBACK" : "CAPTURE")));; @@ -256,14 +260,14 @@ Port::set_private_latency_range (jack_latency_range_t& range, bool playback) { if (playback) { _private_playback_latency = range; - DEBUG_TRACE (DEBUG::Latency, string_compose ("PORT %1 playback latency now [%2 - %3]\n", name(), + DEBUG_TRACE (DEBUG::Latency, string_compose ("SET PORT %1 playback PRIVATE latency now [%2 - %3]\n", name(), _private_playback_latency.min, _private_playback_latency.max)); } else { _private_capture_latency = range; - DEBUG_TRACE (DEBUG::Latency, string_compose ("PORT %1 capture latency now [%2 - %3]\n", name(), - _private_playback_latency.min, - _private_playback_latency.max)); + DEBUG_TRACE (DEBUG::Latency, string_compose ("SET PORT %1 capture PRIVATE latency now [%2 - %3]\n", name(), + _private_capture_latency.min, + _private_capture_latency.max)); } /* push to public (JACK) location so that everyone else can see it */ @@ -275,8 +279,14 @@ const jack_latency_range_t& Port::private_latency_range (bool playback) const { if (playback) { - return _private_playback_latency; + DEBUG_TRACE (DEBUG::Latency, string_compose ("GET PORT %1 playback PRIVATE latency now [%2 - %3]\n", name(), + _private_playback_latency.min, + _private_playback_latency.max)); + return _private_playback_latency; } else { + DEBUG_TRACE (DEBUG::Latency, string_compose ("GET PORT %1 capture PRIVATE latency now [%2 - %3]\n", name(), + _private_playback_latency.min, + _private_playback_latency.max)); return _private_capture_latency; } } @@ -289,7 +299,7 @@ Port::public_latency_range (bool playback) const jack_port_get_latency_range (_jack_port, sends_output() ? JackPlaybackLatency : JackCaptureLatency, &r); - DEBUG_TRACE (DEBUG::Latency, string_compose ("PORT %1: %4 public latency range %2 .. %3\n", + DEBUG_TRACE (DEBUG::Latency, string_compose ("GET PORT %1: %4 PUBLIC latency range %2 .. %3\n", name(), r.min, r.max, sends_output() ? "PLAYBACK" : "CAPTURE")); return r; @@ -320,14 +330,19 @@ Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) c range.max = 0; for (vector::iterator c = connections.begin(); c != connections.end(); ++c) { + + cerr << "Connection between " << name() << " and " << *c << endl; + jack_port_t* remote_port = jack_port_by_name (_engine->jack(), (*c).c_str()); jack_latency_range_t lr; if (remote_port) { jack_port_get_latency_range (remote_port, (playback ? JackPlaybackLatency : JackCaptureLatency), &lr); - DEBUG_TRACE (DEBUG::Latency, string_compose ("\t\%1 has latency range %2 .. %3\n", *c, lr.min, lr.max)); + DEBUG_TRACE (DEBUG::Latency, string_compose ("\t%1 <-> %2 : latter has latency range %3 .. %4\n", name(), *c, lr.min, lr.max)); range.min = min (range.min, lr.min); range.max = max (range.max, lr.max); + } else { + cerr << "\t NO PORT BY NAME!\n"; } } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index d1adac366c..c8c023c0b5 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -920,7 +920,7 @@ Route::add_processor (boost::shared_ptr processor, ProcessorList::ite processor->activate (); } - processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false, false)); + processor->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); _output->set_user_latency (0); } @@ -1057,7 +1057,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr } } - (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false, false)); + (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); } for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { @@ -2422,7 +2422,7 @@ Route::set_processor_state (const XMLNode& node) for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false, false)); + (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); boost::shared_ptr pi; @@ -2752,7 +2752,9 @@ Route::output_change_handler (IOChange change, void * /*src*/) and we are master (as an auto-connect in this situation would cause a feedback loop) */ + AutoConnectOption ac = Config->get_output_auto_connect (); + if (ac == AutoConnectPhysical || (ac == AutoConnectMaster && !is_master ())) { ChanCount start = change.before; @@ -2769,8 +2771,8 @@ Route::output_change_handler (IOChange change, void * /*src*/) already there */ start.set (*i, start.get (*i) + 1); - - _session.auto_connect_route (this, dummy, dummy, false, ChanCount(), change.before); + + _session.auto_connect_route (this, dummy, dummy, false, false, ChanCount(), change.before); } } } @@ -3076,7 +3078,7 @@ void Route::set_user_latency (framecnt_t nframes) { _output->set_user_latency (nframes); - _session.update_latency_compensation (false, false); + _session.update_latency_compensation (); } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 57017f0035..a56627648d 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -325,31 +325,6 @@ Session::destroy () #endif } -void -Session::set_worst_io_latencies () -{ - if (_state_of_the_state & InitialConnecting) { - return; - } - - _worst_output_latency = 0; - _worst_input_latency = 0; - - if (!_engine.connected()) { - return; - } - - boost::shared_ptr r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency()); - _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency()); - } - - DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1 Worst input latency: %2\n", - _worst_output_latency, _worst_input_latency)); -} - void Session::when_engine_running () { @@ -656,7 +631,7 @@ Session::when_engine_running () BootMessage (_("Connect to engine")); _engine.set_session (this); - update_latency_compensation (false, false, true); + update_latency_compensation (true); } void @@ -1431,7 +1406,9 @@ Session::count_existing_route_channels (ChanCount& in, ChanCount& out) { in = ChanCount::ZERO; out = ChanCount::ZERO; + boost::shared_ptr r = routes.reader (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (!(*i)->is_hidden()) { in += (*i)->n_inputs(); @@ -1448,15 +1425,11 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m { char track_name[32]; uint32_t track_id = 0; - ChanCount existing_inputs; - ChanCount existing_outputs; string port; RouteList new_routes; list > ret; uint32_t control_id; - count_existing_route_channels (existing_inputs, existing_outputs); - control_id = ntracks() + nbusses(); bool const use_number = (how_many != 1); @@ -1494,8 +1467,6 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m } } - auto_connect_route (track.get(), existing_inputs, existing_outputs); - track->non_realtime_input_change(); if (route_group) { @@ -1525,23 +1496,31 @@ Session::new_midi_track (TrackMode mode, RouteGroup* route_group, uint32_t how_m failed: if (!new_routes.empty()) { - add_routes (new_routes, false); + add_routes (new_routes, true, false); save_state (_current_snapshot_name); } return ret; } -/** Caller must hold process lock. - * @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs. +/** @param connect_inputs true to connect inputs as well as outputs, false to connect just outputs. * @param input_start Where to start from when auto-connecting inputs; e.g. if this is 0, auto-connect starting from input 0. * @param output_start As \a input_start, but for outputs. */ void -Session::auto_connect_route ( - Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs, ChanCount input_start, ChanCount output_start - ) +Session::auto_connect_route (Route* route, ChanCount& existing_inputs, ChanCount& existing_outputs, + bool with_lock, bool connect_inputs, ChanCount input_start, ChanCount output_start) { + if (!IO::connecting_legal) { + return; + } + + Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock (), Glib::NOT_LOCK); + + if (with_lock) { + lm.acquire (); + } + /* If both inputs and outputs are auto-connected to physical ports, use the max of input and output offsets to ensure auto-connected port numbers always match up (e.g. the first audio input and the @@ -1550,14 +1529,14 @@ Session::auto_connect_route ( offset possible. */ + cerr << "ACR: existing in = " << existing_inputs << " out = " << existing_outputs << endl; + const bool in_out_physical = (Config->get_input_auto_connect() & AutoConnectPhysical) && (Config->get_output_auto_connect() & AutoConnectPhysical) && connect_inputs; - const ChanCount in_offset = in_out_physical - ? ChanCount::max(existing_inputs, existing_outputs) - : existing_inputs; + const ChanCount in_offset = existing_inputs; const ChanCount out_offset = in_out_physical ? ChanCount::max(existing_inputs, existing_outputs) @@ -1572,13 +1551,21 @@ Session::auto_connect_route ( if (!physinputs.empty() && connect_inputs) { uint32_t nphysical_in = physinputs.size(); + + cerr << "There are " << nphysical_in << " physical inputs of type " << *t << endl; + for (uint32_t i = input_start.get(*t); i < route->n_inputs().get(*t) && i < nphysical_in; ++i) { string port; if (Config->get_input_auto_connect() & AutoConnectPhysical) { + cerr << "Get index " << in_offset.get(*t) << " + " << i << " % " << nphysical_in << " = " + << (in_offset.get(*t) + i) % nphysical_in + << endl; port = physinputs[(in_offset.get(*t) + i) % nphysical_in]; } + cerr << "Connect route " << route->name() << " IN to " << port << endl; + if (!port.empty() && route->input()->connect ( route->input()->ports().port(*t, i), port, this)) { break; @@ -1600,6 +1587,8 @@ Session::auto_connect_route ( } } + cerr << "Connect route " << route->name() << " OUT to " << port << endl; + if (!port.empty() && route->output()->connect ( route->output()->ports().port(*t, i), port, this)) { break; @@ -1607,9 +1596,6 @@ Session::auto_connect_route ( } } } - - existing_inputs += route->n_inputs(); - existing_outputs += route->n_outputs(); } /** Caller must not hold process lock @@ -1622,15 +1608,11 @@ Session::new_audio_track ( { char track_name[32]; uint32_t track_id = 0; - ChanCount existing_inputs; - ChanCount existing_outputs; string port; RouteList new_routes; list > ret; uint32_t control_id; - count_existing_route_channels (existing_inputs, existing_outputs); - control_id = ntracks() + nbusses() + 1; bool const use_number = (how_many != 1); @@ -1673,8 +1655,6 @@ Session::new_audio_track ( << endmsg; goto failed; } - - auto_connect_route (track.get(), existing_inputs, existing_outputs); } if (route_group) { @@ -1707,7 +1687,7 @@ Session::new_audio_track ( failed: if (!new_routes.empty()) { - add_routes (new_routes, true); + add_routes (new_routes, true, true); } return ret; @@ -1748,14 +1728,10 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r { char bus_name[32]; uint32_t bus_id = 0; - ChanCount existing_inputs; - ChanCount existing_outputs; string port; RouteList ret; uint32_t control_id; - count_existing_route_channels (existing_inputs, existing_outputs); - control_id = ntracks() + nbusses() + 1; bool const use_number = (how_many != 1); @@ -1792,8 +1768,6 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r << endmsg; goto failure; } - - auto_connect_route (bus.get(), existing_inputs, existing_outputs, false); } if (route_group) { @@ -1824,7 +1798,7 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r failure: if (!ret.empty()) { - add_routes (ret, true); + add_routes (ret, true, true); } return ret; @@ -1914,14 +1888,14 @@ Session::new_route_from_template (uint32_t how_many, const std::string& template out: if (!ret.empty()) { - add_routes (ret, true); + add_routes (ret, true, true); } return ret; } void -Session::add_routes (RouteList& new_routes, bool save) +Session::add_routes (RouteList& new_routes, bool auto_connect, bool save) { { RCUWriter writer (routes); @@ -1972,7 +1946,17 @@ Session::add_routes (RouteList& new_routes, bool save) mt->StepEditStatusChange.connect_same_thread (*this, boost::bind (&Session::step_edit_status_change, this, _1)); } } - } + + if (auto_connect) { + + ChanCount existing_inputs; + ChanCount existing_outputs; + + count_existing_route_channels (existing_inputs, existing_outputs); + + auto_connect_route (r, existing_inputs, existing_outputs, true); + } + } if (_monitor_out && IO::connecting_legal) { @@ -2141,7 +2125,7 @@ Session::remove_route (boost::shared_ptr route) } } - update_latency_compensation (false, false); + update_latency_compensation (); set_dirty(); /* Re-sort routes to remove the graph's current references to the one that is @@ -4156,6 +4140,10 @@ Session::update_latency (bool playback) { DEBUG_TRACE (DEBUG::Latency, string_compose ("JACK latency callback: %1\n", (playback ? "PLAYBACK" : "CAPTURE"))); + if (_state_of_the_state & (InitialConnecting|Deletion)) { + return; + } + boost::shared_ptr r = routes.reader (); framecnt_t max_latency = 0; @@ -4164,15 +4152,166 @@ Session::update_latency (bool playback) reverse (r->begin(), r->end()); } + /* compute actual latency values for the given direction and store them all in per-port + structures. this will also publish the same values (to JACK) so that computation of latency + for routes can consistently use public latency values. + */ + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { max_latency = max (max_latency, (*i)->set_private_port_latencies (playback)); } - DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency)); + if (playback) { - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_public_port_latencies (max_latency, playback); + post_playback_latency (); + + /* because we latency compensate playback, our published playback latencies should + be the same for all output ports - all material played back by ardour has + the same latency, whether its caused by plugins or by latency compensation. since + these may differ from the values computed above, reset all playback port latencies + to the same value. + */ + + DEBUG_TRACE (DEBUG::Latency, string_compose ("Set public port latencies to %1\n", max_latency)); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + (*i)->set_public_port_latencies (max_latency, playback); + } + + + + } else { + + post_capture_latency (); } DEBUG_TRACE (DEBUG::Latency, "JACK latency callback: DONE\n"); } + +void +Session::post_playback_latency () +{ + set_worst_playback_latency (); + + boost::shared_ptr r = routes.reader (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (!(*i)->is_hidden() && ((*i)->active())) { + _worst_track_latency = max (_worst_track_latency, (*i)->update_signal_latency ()); + } + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + (*i)->set_latency_compensation (_worst_track_latency); + } + } +} + +void +Session::post_capture_latency () +{ + set_worst_capture_latency (); + + /* reflect any changes in capture latencies into capture offsets + */ + + boost::shared_ptr rl = routes.reader(); + for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { + boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); + if (tr) { + tr->set_capture_offset (); + } + } +} + +void +Session::set_worst_io_latencies () +{ + set_worst_playback_latency (); + set_worst_capture_latency (); +} + +void +Session::set_worst_playback_latency () +{ + if (_state_of_the_state & (InitialConnecting|Deletion)) { + return; + } + + _worst_output_latency = 0; + + if (!_engine.connected()) { + return; + } + + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + _worst_output_latency = max (_worst_output_latency, (*i)->output()->latency()); + } + + DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst output latency: %1\n", _worst_output_latency)); +} + +void +Session::set_worst_capture_latency () +{ + if (_state_of_the_state & (InitialConnecting|Deletion)) { + return; + } + + _worst_input_latency = 0; + + if (!_engine.connected()) { + return; + } + + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + _worst_input_latency = max (_worst_input_latency, (*i)->input()->latency()); + } + + DEBUG_TRACE (DEBUG::Latency, string_compose ("Worst input latency: %1\n", _worst_input_latency)); +} + +void +Session::update_latency_compensation (bool force_whole_graph) +{ + bool update_jack = false; + + if (_state_of_the_state & Deletion) { + return; + } + + DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n"); + + _worst_track_latency = 0; + + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (!(*i)->is_hidden() && ((*i)->active())) { + framecnt_t tl; + if ((*i)->signal_latency () != (tl = (*i)->update_signal_latency ())) { + update_jack = true; + } + _worst_track_latency = max (tl, _worst_track_latency); + } + } + + DEBUG_TRACE (DEBUG::Latency, string_compose ("worst signal processing latency: %1 (changed ? %2)\n", _worst_track_latency, + (update_jack ? "yes" : "no"))); + + if (force_whole_graph || update_jack) { + /* trigger a full recompute of latency numbers for the graph. + everything else that we need to do will be done in the latency + callback. + */ + _engine.update_total_latencies (); + return; // everything else will be done in the latency callback + } + + + + DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n") +} + diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index cdf6408e8f..b5b713cbd4 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -606,7 +606,7 @@ Session::create (const string& mix_template, BusProfile* bus_profile) } if (!rl.empty()) { - add_routes (rl, false); + add_routes (rl, false, false); } /* this allows the user to override settings with an environment variable. @@ -1439,7 +1439,7 @@ Session::load_routes (const XMLNode& node, int version) new_routes.push_back (route); } - add_routes (new_routes, false); + add_routes (new_routes, false, false); return 0; } diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 26a4592f0e..252262efcd 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -490,7 +490,11 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) } if (_engine.running()) { - update_latency_compensation (true, abort); + PostTransportWork ptw = post_transport_work (); + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush)); + } + update_latency_compensation (); } bool const auto_return_enabled = @@ -1461,72 +1465,10 @@ Session::route_processors_changed (RouteProcessorChange c) return; } - update_latency_compensation (false, false); + update_latency_compensation (); resort_routes (); } -void -Session::update_latency_compensation (bool with_stop, bool abort, bool force_whole_graph) -{ - bool update_jack = false; - PostTransportWork ptw; - - if (_state_of_the_state & Deletion) { - return; - } - - _worst_track_latency = 0; - ptw = post_transport_work(); - - DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency compensation\n\n") - - boost::shared_ptr r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - if (with_stop) { - (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush)); - } - - framecnt_t old_latency = (*i)->signal_latency (); - framecnt_t new_latency = (*i)->update_signal_latency (); - - if (old_latency != new_latency) { - update_jack = true; - } - - if (!(*i)->is_hidden() && ((*i)->active())) { - _worst_track_latency = max (_worst_track_latency, new_latency); - } - } - - if (force_whole_graph || update_jack) { - /* trigger a full recompute of latency numbers for the graph - */ - _engine.update_total_latencies (); - } - - DEBUG_TRACE(DEBUG::Latency, string_compose("worst case route internal latency was %1\n", _worst_track_latency)); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_latency_compensation (_worst_track_latency); - } - - set_worst_io_latencies (); - - /* reflect any changes in latencies into capture offsets - */ - - boost::shared_ptr rl = routes.reader(); - for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { - boost::shared_ptr tr = boost::dynamic_pointer_cast (*i); - if (tr) { - tr->set_capture_offset (); - } - } - DEBUG_TRACE(DEBUG::Latency, "---------------------------- DONE update latency compensation\n\n") -} - void Session::allow_auto_play (bool yn) { -- cgit v1.2.3