From 01c253b61b3130d13f9e30f17683e0f8a93b4696 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 15 Feb 2011 18:47:10 +0000 Subject: [PATCH] part one of several parts: implement support for new (and correct) JACK latency API git-svn-id: svn://localhost/ardour2/branches/3.0@8863 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/port.h | 3 ++ libs/ardour/ardour/route.h | 3 ++ libs/ardour/port.cc | 66 ++++++++++++++++++++++++++++++++ libs/ardour/route.cc | 34 ++++++++++++++++ libs/ardour/session_transport.cc | 15 ++++---- libs/ardour/wscript | 8 +++- 6 files changed, 121 insertions(+), 8 deletions(-) diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index ffdc1d4721..45256a61fe 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -98,6 +98,9 @@ public: int reconnect (); void request_monitor_input (bool); void set_latency (framecnt_t); + + void get_connected_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const; + void set_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const; virtual void reset (); diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index e44eb5c061..1eb91e2901 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -55,6 +55,7 @@ class Delivery; class IOProcessor; class Panner; class PannerShell; +class PortSet; class Processor; class RouteGroup; class Send; @@ -247,6 +248,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, void all_processors_flip(); void all_processors_active (Placement, bool state); + void set_latency_ranges (jack_latency_callback_mode_t mode) const; virtual framecnt_t update_total_latency(); void set_latency_delay (framecnt_t); void set_user_latency (framecnt_t); @@ -505,6 +507,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember, void set_mute_master_solo (); void set_processor_positions (); + void update_port_latencies (const PortSet& ports, jack_latency_callback_mode_t mode, framecnt_t) const; }; } // namespace ARDOUR diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 2a89560b77..7d6abbdb04 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -21,6 +21,8 @@ #include "libardour-config.h" #endif +#include // so that we can test for new functions at runtime + #include "ardour/port.h" #include "ardour/audioengine.h" #include "pbd/failed_constructor.h" @@ -219,6 +221,7 @@ Port::reset () void Port::recompute_total_latency () const { +#if !HAVE_JACK_NEW_LATENCY #ifdef HAVE_JACK_RECOMPUTE_LATENCY jack_client_t* jack = _engine->jack(); @@ -228,11 +231,69 @@ Port::recompute_total_latency () const jack_recompute_total_latency (jack, _jack_port); #endif +#endif +} + +void +Port::set_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const +{ +#if HAVE_JACK_NEW_LATENCY + if (!jack_port_set_latency_range) { + return; + } + + jack_port_set_latency_range (_jack_port, mode, &range); +#endif +} + +void +Port::get_connected_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const +{ +#if HAVE_JACK_NEW_LATENCY + if (!jack_port_get_latency_range) { + return; + } + + vector connections; + jack_client_t* jack = _engine->jack(); + + if (!jack) { + range.min = 0; + range.max = 0; + PBD::warning << _("get_connected_latency_range() called while disconnected from JACK") << endmsg; + return; + } + + get_connections (connections); + + if (!connections.empty()) { + + range.min = ~((jack_nframes_t) 0); + range.max = 0; + + for (vector::iterator c = connections.begin(); c != connections.end(); ++c) { + 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, mode, &lr); + range.min = min (range.min, lr.min); + range.min = max (range.max, lr.max); + } + } + + } else { + + range.min = 0; + range.max = 0; + } +#endif /* HAVE_JACK_NEW_LATENCY */ } framecnt_t Port::total_latency () const { +#if !HAVE_JACK_NEW_LATENCY jack_client_t* jack = _engine->jack(); if (!jack) { @@ -240,6 +301,9 @@ Port::total_latency () const } return jack_port_get_total_latency (jack, _jack_port); +#else + return 0; +#endif } int @@ -305,7 +369,9 @@ Port::request_monitor_input (bool yn) void Port::set_latency (framecnt_t n) { +#if !HAVE_JACK_NEW_LATENCY jack_port_set_latency (_jack_port, n); +#endif } bool diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 68a4019cf7..0ef0fc8bba 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -3628,3 +3628,37 @@ Route::unknown_processors () const return p; } + +void +Route::set_latency_ranges (jack_latency_callback_mode_t mode) const +{ + if (mode == JackPlaybackLatency) { + update_port_latencies (_input->ports (), mode, _input->effective_latency()); + } else { + update_port_latencies (_output->ports (), mode, _output->effective_latency()); + } + +} + +void +Route::update_port_latencies (const PortSet& ports, jack_latency_callback_mode_t mode, framecnt_t our_latency) const +{ + /* iterate over all connected ports and get the latency range + they represent + */ + + for (PortSet::const_iterator p = ports.begin(); p != ports.end(); ++p) { + + jack_latency_range_t range; + + p->get_connected_latency_range (range, mode); + + /* add the latency created within this route + */ + + range.min += our_latency; + range.max += our_latency; + + p->set_latency_range (range, mode); + } +} diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 0aab6a7e27..7d58a97e77 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -21,6 +21,10 @@ #include #include +#ifdef WAF_BUILD +#include "libardour-config.h" +#endif + #include "pbd/undo.h" #include "pbd/error.h" @@ -1507,10 +1511,7 @@ Session::update_latency_compensation (bool with_stop, bool abort) _worst_track_latency = 0; ptw = post_transport_work(); -#undef DEBUG_LATENCY -#ifdef DEBUG_LATENCY - cerr << "\n---------------------------------\nUPDATE LATENCY\n"; -#endif + DEBUG_TRACE(DEBUG::Latency, "---------------------------- update latency\n\n") boost::shared_ptr r = routes.reader (); @@ -1524,8 +1525,10 @@ Session::update_latency_compensation (bool with_stop, bool abort) framecnt_t track_latency = (*i)->update_total_latency (); if (old_latency != track_latency) { +#if !HAVE_JACK_NEW_LATENCY (*i)->input()->update_port_total_latencies (); (*i)->output()->update_port_total_latencies (); +#endif update_jack = true; } @@ -1538,9 +1541,7 @@ Session::update_latency_compensation (bool with_stop, bool abort) _engine.update_total_latencies (); } -#ifdef DEBUG_LATENCY - cerr << "\tworst was " << _worst_track_latency << endl; -#endif + DEBUG_TRACE(DEBUG::Latency, string_compose("worst case latency was %1\n", _worst_track_latency)); for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->set_latency_delay (_worst_track_latency); diff --git a/libs/ardour/wscript b/libs/ardour/wscript index fc128a44bf..88983dcc05 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -268,7 +268,13 @@ def configure(conf): linkflags = ['-ljack'], msg = 'Checking for jack_on_info_shutdown', define_name = 'HAVE_JACK_ON_INFO_SHUTDOWN', - okmsg = 'ok') + okmsg = 'present') + + conf.check_cc(fragment = "#include \nint main(int argc, char **argv) { jack_port_t* p; jack_latency_range_t r; jack_port_set_latency_range (p, JackCaptureLatency, &r); return 0; }\n", + linkflags = ['-ljack'], + msg = 'Checking for new JACK latency API', + define_name = 'HAVE_JACK_NEW_LATENCY', + okmsg = 'present') if flac_supported(): conf.define ('HAVE_FLAC', 1) -- 2.30.2