14 #pragma warning (push)
15 #pragma warning (disable: 4127)
22namespace tracktion {
inline namespace graph
37 template<
typename Type>
41 LockFreeFifo (
int capacity)
42 : fifo (
std::make_unique<rigtorp::MPMCQueue<Type>> (
static_cast<size_t> (capacity)))
46 bool try_enqueue (Type&& item) {
return fifo->try_push (std::move (item)); }
47 bool try_dequeue (Type& item) {
return fifo->try_pop (item); }
55 PlaybackNode (
Node& n)
56 : node (n), numInputs (node.getDirectInputNodes().size())
60 const size_t numInputs;
108 virtual void signal (
int numToSignal) = 0;
125 threadsShouldExit =
true;
132 threadsShouldExit =
false;
149 return player.numNodesQueued == 0;
155 assert (currentPreparedNode);
157 if (! currentPreparedNode.
load()->graph)
160 return currentPreparedNode.
load()->graph->rootNode->hasProcessed();
169 if (
auto cpn = currentPreparedNode.
load())
170 return player.processNextFreeNode (*cpn);
178 currentPreparedNode = nodeInUse;
219 void prepareToPlay (
double sampleRateToUse,
int blockSizeToUse);
258 void enableNodeMemorySharing (
bool shouldBeEnabled);
264 choc::buffer::FrameCount numSamplesToProcess = 0;
270 LockFreeObject<PreparedNode> preparedNodeObject;
271 Node* rootNode =
nullptr;
272 NodeGraph* lastGraphPosted =
nullptr;
273 AudioBufferPool* lastAudioBufferPoolPosted =
nullptr;
280 bool nodeMemorySharingEnabled =
false;
285 double sampleRateToUse,
int blockSizeToUse,
286 bool useCurrentAudioBufferPool);
290 void createThreads();
297 static void buildNodesOutputLists (PreparedNode&);
298 void resetProcessQueue (PreparedNode&);
299 Node* updateProcessQueueForNode (PreparedNode&, Node&);
300 void processNode (PreparedNode&, Node&);
303 bool processNextFreeNode (PreparedNode&);
Plays back a node with mutiple threads.
void clearNode()
Clears the current Node.
void setNode(std::unique_ptr< Node >)
Sets the Node to process.
void enablePooledMemoryAllocations(bool)
Enables or disables the use on an AudioBufferPool to reduce memory consumption.
int getBlockSize() const
Returns the current block size.
~LockFreeMultiThreadedNodePlayer()
Destructor.
double getSampleRate() const
Returns the current sample rate.
int process(const Node::ProcessContext &)
Process a block of the Node.
void setNumThreads(size_t)
Sets the number of threads to use for rendering.
void prepareToPlay(double sampleRateToUse, int blockSizeToUse)
Prepares the current Node to be played.
Node * getNode()
Returns the current Node.
LockFreeMultiThreadedNodePlayer()
Creates an empty LockFreeMultiThreadedNodePlayer.
Main graph Node processor class.
Struct to describe a single iteration of a process call.
T hardware_concurrency(T... args)
Base class for thread pools which can be customised to determine how cooperative threads should behav...
virtual ~ThreadPool()=default
Destructor.
virtual void createThreads(size_t numThreads, juce::AudioWorkgroup)=0
Subclasses should implement this to create the given number of threads.
bool shouldWait()
Returns true if there are no free Nodes to be processed and the calling thread should wait until ther...
virtual void signal(int numToSignal)=0
Called by the player when more than one Node becomes available to process.
virtual void clearThreads()=0
Subclasses should implement this to clear all the threads.
void signalShouldExit()
Signals the pool that all the threads should exit.
virtual void signalOne()=0
Called by the player when a Node becomes available to process.
void setCurrentNode(LockFreeMultiThreadedNodePlayer::PreparedNode *nodeInUse)
Sets the current PreparedNode in use.
bool isFinalNodeReady()
Returns true if all the Nodes have been processed.
bool process()
Process the next chain of Nodes.
void resetExitSignal()
Signals the pool that all the threads should continue to run and not exit.
ThreadPool(LockFreeMultiThreadedNodePlayer &p)
Constructs a ThreadPool for a given LockFreeMultiThreadedNodePlayer.
virtual void waitForFinalNode()=0
Called by the player when the audio thread has no free Nodes to process.
bool shouldExit() const
Returns true if all the threads should exit.
virtual void signalAll()=0
Called by the player when more than one Node becomes available to process.