Parallel execution of cycle-start/end
authorRobin Gareus <robin@gareus.org>
Mon, 30 Oct 2017 14:58:36 +0000 (15:58 +0100)
committerRobin Gareus <robin@gareus.org>
Mon, 30 Oct 2017 15:31:38 +0000 (16:31 +0100)
libs/ardour/ardour/port_manager.h
libs/ardour/ardour/session.h
libs/ardour/audioengine.cc
libs/ardour/port_manager.cc
libs/ardour/session.cc

index bfbf98c328cd1dfed3cb132f736681688dbf1fb9..743c006fbd2871d5ea705c94574e3d6e8c3631f9 100644 (file)
@@ -189,14 +189,14 @@ class LIBARDOUR_API PortManager
         * This MUST be called before any reading/writing for this cycle.
         * Realtime safe.
         */
-       void cycle_start (pframes_t nframes);
+       void cycle_start (pframes_t nframes, Session* s = 0);
 
        /** Signal the end of an audio cycle.
         * This signifies that the cycle began with @ref cycle_start has ended.
         * This MUST be called at the end of each cycle.
         * Realtime safe.
         */
-       void cycle_end (pframes_t nframes);
+       void cycle_end (pframes_t nframes, Session* s = 0);
 
        typedef std::map<std::string,MidiPortInformation> MidiPortInfo;
 
index b0e133f4c699c6def90a08430ac45e1b48706342..4ef5fe66359960e59a1e67e36e10966ef316425d 100644 (file)
@@ -141,6 +141,7 @@ class Region;
 class Return;
 class Route;
 class RouteGroup;
+class RTTaskList;
 class SMFSource;
 class Send;
 class SceneChanger;
@@ -288,6 +289,8 @@ public:
                return routes.reader ();
        }
 
+       boost::shared_ptr<RTTaskList> rt_tasklist () { return _rt_tasklist; }
+
        CoreSelection& selection () { return *_selection; }
 
        /* because the set of Stripables consists of objects managed
@@ -2079,6 +2082,8 @@ private:
        boost::shared_ptr<IO>   _ltc_input;
        boost::shared_ptr<IO>   _ltc_output;
 
+       boost::shared_ptr<RTTaskList> _rt_tasklist;
+
        /* Scene Changing */
        SceneChanger* _scene_changer;
 
index da512cc51dc9748784a3921041063a98dfbbfca9..1c0fcbf1388d23398361bbbb643283b599fab6d5 100644 (file)
@@ -372,7 +372,7 @@ AudioEngine::process_callback (pframes_t nframes)
 
        /* tell all Ports that we're starting a new cycle */
 
-       PortManager::cycle_start (nframes);
+       PortManager::cycle_start (nframes, _session);
 
        /* test if we are freewheeling and there are freewheel signals connected.
         * ardour should act normally even when freewheeling unless /it/ is
@@ -398,7 +398,7 @@ AudioEngine::process_callback (pframes_t nframes)
        }
 
        if (_freewheeling) {
-               PortManager::cycle_end (nframes);
+               PortManager::cycle_end (nframes, _session);
                return 0;
        }
 
@@ -451,7 +451,7 @@ AudioEngine::process_callback (pframes_t nframes)
                session_removal_gain -= (nframes * session_removal_gain_step);
        }
 
-       PortManager::cycle_end (nframes);
+       PortManager::cycle_end (nframes, _session);
 
        _processed_samples = next_processed_samples;
 
index 1ef7ca1d8b7d10e34fcd000b4c9ff2501bea5b7c..eae165454323a4a39af5824beb0b0d73e6bba89a 100644 (file)
@@ -38,6 +38,7 @@
 #include "ardour/midiport_manager.h"
 #include "ardour/port_manager.h"
 #include "ardour/profile.h"
+#include "ardour/rt_tasklist.h"
 #include "ardour/session.h"
 #include "ardour/types_convert.h"
 
@@ -745,24 +746,39 @@ PortManager::graph_order_callback ()
 }
 
 void
-PortManager::cycle_start (pframes_t nframes)
+PortManager::cycle_start (pframes_t nframes, Session* s)
 {
        Port::set_global_port_buffer_offset (0);
        Port::set_cycle_samplecnt (nframes);
 
        _cycle_ports = ports.reader ();
 
-       // TODO parallelize
-       for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
-               p->second->cycle_start (nframes);
+       if (s && s->rt_tasklist ()) {
+               RTTaskList::TaskList tl;
+               for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
+                       tl.push_back (boost::bind (&Port::cycle_start, p->second, nframes));
+               }
+               s->rt_tasklist()->process (tl);
+       } else {
+               for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
+                       p->second->cycle_start (nframes);
+               }
        }
 }
 
 void
-PortManager::cycle_end (pframes_t nframes)
+PortManager::cycle_end (pframes_t nframes, Session* s)
 {
-       for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
-               p->second->cycle_end (nframes);
+       if (s && s->rt_tasklist ()) {
+               RTTaskList::TaskList tl;
+               for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
+                       tl.push_back (boost::bind (&Port::cycle_end, p->second, nframes));
+               }
+               s->rt_tasklist()->process (tl);
+       } else {
+               for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
+                       p->second->cycle_end (nframes);
+               }
        }
 
        for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
index 0bfc5d97ca51a91e78517b8eea1318dbb4281f60..ef08eb0bf2c8dff73f3fa3c56de1c03803c5c34c 100644 (file)
@@ -93,6 +93,7 @@
 #include "ardour/revision.h"
 #include "ardour/route_graph.h"
 #include "ardour/route_group.h"
+#include "ardour/rt_tasklist.h"
 #include "ardour/send.h"
 #include "ardour/selection.h"
 #include "ardour/session.h"
@@ -600,6 +601,8 @@ Session::immediately_post_engine ()
         * session or set state for an existing one.
         */
 
+       _rt_tasklist.reset (new RTTaskList ());
+
        if (how_many_dsp_threads () > 1) {
                /* For now, only create the graph if we are using >1 DSP threads, as
                   it is a bit slower than the old code with 1 thread.