Parallel execution of cycle-start/end

This commit is contained in:
Robin Gareus 2017-10-30 15:58:36 +01:00
parent fba0fce441
commit 471644c59d
5 changed files with 36 additions and 12 deletions

View 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;

View 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;

View 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;

View 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) {

View 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.