11namespace tracktion {
inline namespace engine
21 : input (std::move (inputNode)),
22 meterPlugin (levelMeterPlugin)
28 if (isInitialised && ! meterPlugin.baseClassNeedsInitialising())
29 meterPlugin.baseClassDeinitialise();
34 return input->getNodeProperties();
39 return { input.
get() };
44 return input->hasProcessed();
51 const auto inputProps = input->getNodeProperties();
54 if (info.enableNodeMemorySharing && input->numOutputNodes == 1)
56 const auto inputNumChannels = inputProps.numberOfChannels;
57 const auto desiredNumChannels = nodeProps.numberOfChannels;
59 if (inputNumChannels >= desiredNumChannels)
61 canUseSourceBuffers =
true;
63 tracktion::graph::AllocateAudioBuffer::no });
67 const int latencyAtRoot = info.nodeGraph.rootNode->getNodeProperties().latencyNumSamples;
68 const int latencyAtInput = inputProps.latencyNumSamples;
70 const int numSamplesLatencyToIntroduce = latencyAtRoot - latencyAtInput;
72 if (numSamplesLatencyToIntroduce <= 0)
76 latencyProcessor->setLatencyNumSamples (numSamplesLatencyToIntroduce);
77 latencyProcessor->prepareToPlay (info.sampleRate, info.blockSize, nodeProps.numberOfChannels);
79 tempAudioBuffer.resize ({ (choc::buffer::ChannelCount) nodeProps.numberOfChannels,
80 (choc::buffer::FrameCount) info.blockSize });
85 if (canUseSourceBuffers)
92 auto sourceBuffers = input->getProcessedOutput();
93 jassert (sourceBuffers.audio.getNumChannels() == pc.buffers.audio.getNumChannels());
96 if (input->numOutputNodes == 1)
98 pc.buffers.midi.swapWith (sourceBuffers.midi);
103 pc.buffers.midi.copyFrom (sourceBuffers.midi);
104 copyIfNotAliased (pc.buffers.audio, sourceBuffers.audio);
108 if (! latencyProcessor)
110 processLevelMeasurer (meterPlugin.measurer, sourceBuffers.audio, pc.buffers.midi);
115 const auto numFrames = sourceBuffers.audio.getNumFrames();
117 latencyProcessor->writeAudio (sourceBuffers.audio);
118 latencyProcessor->writeMIDI (sourceBuffers.midi);
120 tempMidiBuffer.clear();
122 auto tempBlock = tempAudioBuffer.getStart (numFrames);
123 latencyProcessor->readAudioOverwriting (tempBlock);
124 latencyProcessor->readMIDI (tempMidiBuffer, (
int) numFrames);
126 processLevelMeasurer (meterPlugin.measurer, tempBlock, tempMidiBuffer);
133 bool isInitialised =
false, canUseSourceBuffers =
false;
137 choc::buffer::ChannelArrayBuffer<float> tempAudioBuffer;
141 void initialisePlugin()
144 meterPlugin.baseClassInitialise ({ 0_tp, 0.0, 0 });
145 isInitialised =
true;
148 void processLevelMeasurer (LevelMeasurer& measurer, choc::buffer::ChannelArrayView<float> block, MidiMessageArray& midi)
150 auto buffer = tracktion::graph::toAudioBuffer (block);
151 measurer.processBuffer (buffer, 0, buffer.getNumSamples());
153 measurer.setShowMidi (meterPlugin.showMidiActivity);
154 measurer.processMidi (midi,
nullptr);
A Node that introduces latency to balance the latency at the root Node and its position in the graph.
void process(ProcessContext &pc) override
Called when the node is to be processed.
bool isReadyToProcess() override
Should return true when this node is ready to be processed.
void preProcess(choc::buffer::FrameCount, juce::Range< int64_t >) override
Called when the node is to be processed, just before process.
void prepareToPlay(const tracktion::graph::PlaybackInitialisationInfo &info) override
Called once before playback begins for each node.
tracktion::graph::NodeProperties getNodeProperties() override
Should return the properties of the node.
std::vector< tracktion::graph::Node * > getDirectInputNodes() override
Should return all the inputs directly feeding in to this node.
Main graph Node processor class.
void setAudioOutput(Node *sourceNode, const choc::buffer::ChannelArrayView< float > &)
This can be called during your process function to set a view to the output.
void setOptimisations(NodeOptimisations)
This can be called to provide some hints about allocating or playing back a Node to improve efficienc...
void setBufferViewToUse(Node *sourceNode, const choc::buffer::ChannelArrayView< float > &)
This can be called during prepareToPlay to set a BufferView to use which can improve efficiency.
Struct to describe a single iteration of a process call.
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...