part one of several parts: implement support for new (and correct) JACK latency API
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 15 Feb 2011 18:47:10 +0000 (18:47 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 15 Feb 2011 18:47:10 +0000 (18:47 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8863 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/port.h
libs/ardour/ardour/route.h
libs/ardour/port.cc
libs/ardour/route.cc
libs/ardour/session_transport.cc
libs/ardour/wscript

index ffdc1d47217db070d733d4468d8f93e053fbf925..45256a61fec0791d2aed6f33ea6754617ca4ea61 100644 (file)
@@ -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 ();
 
index e44eb5c0617fecfc0fdbe9e50950a9aa0bc1d09d..1eb91e29019d12625317669d5f931ed66840270d 100644 (file)
@@ -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
index 2a89560b77d7c3d9563eefa3563f4b2923d7e763..7d6abbdb043a052004860a3bc43963490d603a2e 100644 (file)
@@ -21,6 +21,8 @@
 #include "libardour-config.h"
 #endif
 
+#include <jack/weakjack.h> // 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<string> 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<string>::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
index 68a4019cf75dc7b94a13ac9595779590b688080d..0ef0fc8bba0132cabff1db94f021b73b020c4f79 100644 (file)
@@ -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);
+        }
+}
index 0aab6a7e27820f2ee6bfa177a80a6c359da87044..7d58a97e777ca1bae35577ff1c66ac8e4cfa3976 100644 (file)
 #include <cerrno>
 #include <unistd.h>
 
+#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<RouteList> 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);
index fc128a44bf2c63aa33b5457997e73f0e4355e20c..88983dcc059a94ce73be1136fdba8576949996c8 100644 (file)
@@ -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 <jack/jack.h>\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)