fixes for latency computation and compilation
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 16 Feb 2011 03:25:23 +0000 (03:25 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 16 Feb 2011 03:25:23 +0000 (03:25 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8868 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/port.h
libs/ardour/ardour/route.h
libs/ardour/audioengine.cc
libs/ardour/port.cc
libs/ardour/route.cc
libs/ardour/session.cc

index 21d26397b3be66535124810d181eae2de25b447b..3a45d010c7f2a6bea08c5e75e27bce2878420a86 100644 (file)
@@ -100,8 +100,8 @@ public:
        void set_latency (framecnt_t);
         
 #ifdef HAVE_JACK_NEW_LATENCY
-        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;
+        void get_connected_latency_range (jack_latency_range_t& range, bool playback) const;
+        void set_latency_range (jack_latency_range_t& range, bool playback) const;
 #endif
 
        virtual void reset ();
index 1eb91e29019d12625317669d5f931ed66840270d..e17dc775d1396381175e1a567c2a7500b7fd8c65 100644 (file)
@@ -248,7 +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;
+        void set_latency_ranges (bool playback) const;
        virtual framecnt_t update_total_latency();
        void set_latency_delay (framecnt_t);
        void set_user_latency (framecnt_t);
@@ -507,7 +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;
+        void update_port_latencies (const PortSet& ports, const PortSet& feeders, bool playback, framecnt_t) const;
 };
 
 } // namespace ARDOUR
index 5ac4e2140e5ae329f9808e175f128e460941518e..cc6e3b443acd59080a4b700af02d275886c52074 100644 (file)
@@ -621,11 +621,8 @@ AudioEngine::jack_sample_rate_callback (pframes_t nframes)
 void
 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
 {
-        cerr << "JACK LATENCY CALLBACK\n";
         if (_session) {
                 _session->update_latency (mode == JackPlaybackLatency);
-        } else {
-                cerr << "NO SESSION\n";
         }
 }
 
@@ -1452,10 +1449,8 @@ AudioEngine::request_buffer_size (pframes_t nframes)
 void
 AudioEngine::update_total_latencies ()
 {
-#ifdef HAVE_JACK_RECOMPUTE_LATENCIES
        GET_PRIVATE_JACK_POINTER (_jack);
        jack_recompute_total_latencies (_priv_jack);
-#endif
 }
 
 string
index 607c0294324611187846f72a52dc78d7b75eb167..bc9a0656fff1390ebdb40860730688dd45fd899c 100644 (file)
 #include "libardour-config.h"
 #endif
 
+#include <stdexcept>
+
 #include <jack/weakjack.h> // so that we can test for new functions at runtime
 
+#include "pbd/error.h"
+#include "pbd/compose.h"
+
+#include "ardour/debug.h"
 #include "ardour/port.h"
 #include "ardour/audioengine.h"
 #include "pbd/failed_constructor.h"
-#include "pbd/error.h"
-#include "pbd/compose.h"
-#include <stdexcept>
 
 #include "i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
+using namespace PBD;
 
 AudioEngine* Port::_engine = 0;
 pframes_t Port::_buffer_size = 0;
@@ -235,19 +239,19 @@ Port::recompute_total_latency () const
 }
 
 void
-Port::set_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const
+Port::set_latency_range (jack_latency_range_t& range, bool playback) const
 {
 #ifdef HAVE_JACK_NEW_LATENCY
         if (!jack_port_set_latency_range) {
                 return;
         }
 
-        jack_port_set_latency_range (_jack_port, mode, &range);
+        jack_port_set_latency_range (_jack_port, (playback ? JackPlaybackLatency : JackCaptureLatency), &range);
 #endif
 }
 
 void
-Port::get_connected_latency_range (jack_latency_range_t& range, jack_latency_callback_mode_t mode) const
+Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) const
 {
 #ifdef HAVE_JACK_NEW_LATENCY
         if (!jack_port_get_latency_range) {
@@ -275,10 +279,13 @@ Port::get_connected_latency_range (jack_latency_range_t& range, jack_latency_cal
                         jack_port_t* remote_port = jack_port_by_name (_engine->jack(), (*c).c_str());
                         jack_latency_range_t lr;
 
+                        DEBUG_TRACE (DEBUG::Latency, string_compose ("\t%1 connected to %2\n", name(), *c));
+
                         if (remote_port) {
-                                jack_port_get_latency_range (remote_port, mode, &lr);
+                                jack_port_get_latency_range (remote_port, (playback ? JackPlaybackLatency : JackCaptureLatency), &lr);
+                                DEBUG_TRACE (DEBUG::Latency, string_compose ("\t\tremote has latency range %1 .. %2\n", lr.min, lr.max));
                                 range.min = min (range.min, lr.min);
-                                range.min = max (range.max, lr.max);
+                                range.max = max (range.max, lr.max);
                         }
                 }
 
index e96275871b39b796ecc646b330f22d0bf28eaf5f..2fe9eb7fd1ed0bd8fa8aaac17c66b6d3e1f3a859 100644 (file)
 
 */
 
+#ifdef WAF_BUILD
+#include "libardour-config.h"
+#endif
+
 #include <cmath>
 #include <fstream>
 #include <cassert>
@@ -3630,37 +3634,68 @@ Route::unknown_processors () const
 }
 
 void
-Route::set_latency_ranges (jack_latency_callback_mode_t mode) const
+Route::set_latency_ranges (bool playback) const
 {
-        if (mode == JackPlaybackLatency) {
-                update_port_latencies (_input->ports (), mode, _input->effective_latency());
+       framecnt_t own_latency = 0;
+
+        /* Processor list not protected by lock: MUST BE CALLED FROM PROCESS THREAD OR
+           LATENCY CALLBACK
+        */
+
+       for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+               if ((*i)->active ()) {
+                       own_latency += (*i)->signal_latency ();
+               }
+       }
+
+        if (playback) {
+                update_port_latencies (_input->ports (), _output->ports (), true, own_latency);
         } else {
-                update_port_latencies (_output->ports (), mode, _output->effective_latency());
+                update_port_latencies (_output->ports (), _input->ports (), false, own_latency);
         }
-
 }
 
 void
-Route::update_port_latencies (const PortSet& ports, jack_latency_callback_mode_t mode, framecnt_t our_latency) const
+Route::update_port_latencies (const PortSet& operands, const PortSet& feeders, bool playback, framecnt_t our_latency) const
 {
 #ifdef HAVE_JACK_NEW_LATENCY
-        /* iterate over all connected ports and get the latency range
-           they represent
-        */
-
-        for (PortSet::const_iterator p = ports.begin(); p != ports.end(); ++p) {
 
+        /* we assume that all our input ports feed all our output ports. its not
+           universally true, but the alternative is way too corner-case to worry about.
+        */
+        
+        jack_latency_range_t all_connections;
+        
+        all_connections.min = ~((jack_nframes_t) 0);
+        all_connections.max = 0;
+        
+        /* iterate over all feeder ports and determine their relevant latency, taking
+           the maximum and minimum across all of them.
+        */
+        
+        for (PortSet::const_iterator p = feeders.begin(); p != feeders.end(); ++p) {
+                
                 jack_latency_range_t range;
+                
+                p->get_connected_latency_range (range, playback);
+                
+                all_connections.min = min (all_connections.min, range.min);
+                all_connections.max = max (all_connections.max, range.max);
+        }
+        
+        all_connections.min += our_latency;
+        all_connections.max += our_latency;
 
-                p->get_connected_latency_range (range, mode);
-
-                /* add the latency created within this route
-                 */
-
-                range.min += our_latency;
-                range.max += our_latency;
+        for (PortSet::const_iterator p = operands.begin(); p != operands.end(); ++p) {
+                
+                p->set_latency_range (all_connections, playback);
                 
-                p->set_latency_range (range, mode);
+                DEBUG_TRACE (DEBUG::Latency, string_compose ("Port %1 %5 latency range %2 .. %3 + %4\n",
+                                                             p->name(),
+                                                             all_connections.min,
+                                                             all_connections.max,
+                                                             our_latency,
+                                                             (playback ? "PLAYBACK" : "CAPTURE")));
         }
 #endif
 }
index 28822ef6f9a830821f868dcb539022aba5cf5e78..9b461d8c69c51494c9cefa1a2eaa86355130ed1d 100644 (file)
@@ -660,6 +660,7 @@ Session::when_engine_running ()
        BootMessage (_("Connect to engine"));
 
        _engine.set_session (this);
+        _engine.update_total_latencies ();
 }
 
 void
@@ -4239,5 +4240,18 @@ void
 Session::update_latency (bool playback)
 {
         DEBUG_TRACE (DEBUG::Latency, "JACK latency callback\n");
+
+       boost::shared_ptr<RouteList> r = routes.reader ();
+
+        if (playback) {
+                /* reverse the list so that we work backwards from the last route to run to the first */
+                reverse (r->begin(), r->end());
+        }
+
+       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+                DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Working on latency for %1\n", (*i)->name()));
+                (*i)->set_latency_ranges (playback);
+                DEBUG_TRACE (DEBUG::Latency, string_compose ("------------- Done working on latency for %1\n\n", (*i)->name()));
+        }
 }
 #endif