From c44c0e0e9e6cd007a69eebea3bf85a03f59f0b52 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 21 Jul 2022 13:36:46 +0100 Subject: [PATCH] Graph: Reduce templating in RenderSequenceBuilder --- .../processors/juce_AudioProcessorGraph.cpp | 67 ++++++++++--------- .../processors/juce_AudioProcessorGraph.h | 3 +- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index e06f88cd4e..6b7a33416e 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -308,34 +308,23 @@ private: //============================================================================== //============================================================================== -template -struct RenderSequenceBuilder +class RenderSequenceBuilder { - RenderSequenceBuilder (AudioProcessorGraph& g, RenderSequence& s) - : graph (g), sequence (s), orderedNodes (createOrderedNodeList (graph)) +public: + template + static auto build (AudioProcessorGraph& g) { - audioBuffers.add (AssignedBuffer::createReadOnlyEmpty()); // first buffer is read-only zeros - midiBuffers .add (AssignedBuffer::createReadOnlyEmpty()); - - for (int i = 0; i < orderedNodes.size(); ++i) - { - createRenderingOpsForNode (*orderedNodes.getUnchecked(i), i); - markAnyUnusedBuffersAsFree (audioBuffers, i); - markAnyUnusedBuffersAsFree (midiBuffers, i); - } - - graph.setLatencySamples (totalLatency); - - s.numBuffersNeeded = audioBuffers.size(); - s.numMidiBuffersNeeded = midiBuffers.size(); + auto sequence = std::make_unique(); + const RenderSequenceBuilder builder (g, *sequence); + return sequence; } +private: //============================================================================== using Node = AudioProcessorGraph::Node; using NodeID = AudioProcessorGraph::NodeID; AudioProcessorGraph& graph; - RenderSequence& sequence; const Array orderedNodes; @@ -440,7 +429,8 @@ struct RenderSequenceBuilder return result; } - int findBufferForInputAudioChannel (Node& node, const int inputChan, + template + int findBufferForInputAudioChannel (RenderSequence& sequence, Node& node, const int inputChan, const int ourRenderingIndex, const int maxLatency) { auto& processor = *node.getProcessor(); @@ -572,7 +562,8 @@ struct RenderSequenceBuilder return bufIndex; } - int findBufferForInputMidiChannel (Node& node, int ourRenderingIndex) + template + int findBufferForInputMidiChannel (RenderSequence& sequence, Node& node, int ourRenderingIndex) { auto& processor = *node.getProcessor(); auto sources = getSourcesForChannel (node, AudioProcessorGraph::midiChannelIndex); @@ -663,7 +654,8 @@ struct RenderSequenceBuilder return midiBufferToUse; } - void createRenderingOpsForNode (Node& node, const int ourRenderingIndex) + template + void createRenderingOpsForNode (RenderSequence& sequence, Node& node, const int ourRenderingIndex) { auto& processor = *node.getProcessor(); auto numIns = processor.getTotalNumInputChannels(); @@ -676,7 +668,7 @@ struct RenderSequenceBuilder for (int inputChan = 0; inputChan < numIns; ++inputChan) { // get a list of all the inputs to this node - auto index = findBufferForInputAudioChannel (node, inputChan, ourRenderingIndex, maxLatency); + auto index = findBufferForInputAudioChannel (sequence, node, inputChan, ourRenderingIndex, maxLatency); jassert (index >= 0); audioChannelsToUse.add (index); @@ -694,7 +686,7 @@ struct RenderSequenceBuilder audioBuffers.getReference (index).channel = { node.nodeID, outputChan }; } - auto midiBufferToUse = findBufferForInputMidiChannel (node, ourRenderingIndex); + auto midiBufferToUse = findBufferForInputMidiChannel (sequence, node, ourRenderingIndex); if (processor.producesMidi()) midiBuffers.getReference (midiBufferToUse).channel = { node.nodeID, AudioProcessorGraph::midiChannelIndex }; @@ -781,7 +773,25 @@ struct RenderSequenceBuilder return false; } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RenderSequenceBuilder) + template + RenderSequenceBuilder (AudioProcessorGraph& g, RenderSequence& sequence) + : graph (g), orderedNodes (createOrderedNodeList (graph)) + { + audioBuffers.add (AssignedBuffer::createReadOnlyEmpty()); // first buffer is read-only zeros + midiBuffers .add (AssignedBuffer::createReadOnlyEmpty()); + + for (int i = 0; i < orderedNodes.size(); ++i) + { + createRenderingOpsForNode (sequence, *orderedNodes.getUnchecked(i), i); + markAnyUnusedBuffersAsFree (audioBuffers, i); + markAnyUnusedBuffersAsFree (midiBuffers, i); + } + + graph.setLatencySamples (totalLatency); + + sequence.numBuffersNeeded = audioBuffers.size(); + sequence.numMidiBuffersNeeded = midiBuffers.size(); + } }; //============================================================================== @@ -1233,11 +1243,8 @@ bool AudioProcessorGraph::anyNodesNeedPreparing() const noexcept void AudioProcessorGraph::handleAsyncUpdate() { - auto newSequenceF = std::make_unique(); - auto newSequenceD = std::make_unique(); - - RenderSequenceBuilder builderF (*this, *newSequenceF); - RenderSequenceBuilder builderD (*this, *newSequenceD); + auto newSequenceF = RenderSequenceBuilder::build (*this); + auto newSequenceD = RenderSequenceBuilder::build (*this); const ScopedLock sl (getCallbackLock()); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 50f1dca56f..f5f3851346 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -133,8 +133,7 @@ public: friend class AudioProcessorGraph; template friend struct GraphRenderSequence; - template - friend struct RenderSequenceBuilder; + friend class RenderSequenceBuilder; struct Connection {