tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_LatencyNode.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11#pragma once
12
13namespace tracktion { inline namespace graph
14{
15
16//==============================================================================
17//==============================================================================
18class LatencyNode final : public Node
19{
20public:
21 LatencyNode (std::unique_ptr<Node> inputNode, int numSamplesToDelay)
22 : LatencyNode (inputNode.get(), numSamplesToDelay)
23 {
24 ownedInput = std::move (inputNode);
25
26 setOptimisations ({ tracktion::graph::ClearBuffers::no,
27 tracktion::graph::AllocateAudioBuffer::yes });
28 }
29
30 LatencyNode (std::shared_ptr<Node> inputNode, int numSamplesToDelay)
31 : LatencyNode (inputNode.get(), numSamplesToDelay)
32 {
33 sharedInput = std::move (inputNode);
34
35 setOptimisations ({ tracktion::graph::ClearBuffers::no,
36 tracktion::graph::AllocateAudioBuffer::yes });
37 }
38
39 LatencyNode (Node* inputNode, int numSamplesToDelay)
40 : input (inputNode)
41 {
42 latencyProcessor->setLatencyNumSamples (numSamplesToDelay);
43
44 setOptimisations ({ tracktion::graph::ClearBuffers::no,
45 tracktion::graph::AllocateAudioBuffer::yes });
46 }
47
49 {
50 auto props = input->getNodeProperties();
51 props.latencyNumSamples += latencyProcessor->getLatencyNumSamples();
52
53 constexpr size_t latencyNodeMagicHash = size_t (0x95ab5e9dcc);
54
55 if (props.nodeID != 0)
56 hash_combine (props.nodeID, latencyNodeMagicHash);
57
58 return props;
59 }
60
62 {
63 return { input };
64 }
65
66 bool isReadyToProcess() override
67 {
68 return input->hasProcessed();
69 }
70
71 void prepareToPlay (const PlaybackInitialisationInfo& info) override
72 {
73 latencyProcessor->prepareToPlay (info.sampleRate, info.blockSize, getNodeProperties().numberOfChannels);
74 replaceLatencyProcessorIfPossible (info.nodeGraphToReplace);
75 }
76
77 void process (ProcessContext& pc) override
78 {
79 auto inputBuffer = input->getProcessedOutput().audio;
80 auto& inputMidi = input->getProcessedOutput().midi;
81 auto numSamples = (int) pc.referenceSampleRange.getLength();
82 jassert (pc.buffers.audio.getNumChannels() == 0 || numSamples == (int) pc.buffers.audio.getNumFrames());
83
84 latencyProcessor->writeAudio (inputBuffer);
85 latencyProcessor->writeMIDI (inputMidi);
86
87 pc.buffers.midi.clear();
88 latencyProcessor->readAudioOverwriting (pc.buffers.audio);
89 latencyProcessor->readMIDI (pc.buffers.midi, numSamples);
90 }
91
92private:
93 std::unique_ptr<Node> ownedInput;
94 std::shared_ptr<Node> sharedInput;
95 Node* input = nullptr;
97
98 void replaceLatencyProcessorIfPossible (NodeGraph* nodeGraphToReplace)
99 {
100 if (nodeGraphToReplace == nullptr)
101 return;
102
103 const auto nodeIDToLookFor = getNodeProperties().nodeID;
104
105 if (nodeIDToLookFor == 0)
106 return;
107
108 if (auto oldNode = findNodeWithID<LatencyNode> (*nodeGraphToReplace, nodeIDToLookFor))
109 if (latencyProcessor->hasSameConfigurationAs (*oldNode->latencyProcessor))
110 latencyProcessor = oldNode->latencyProcessor;
111 }
112};
113
114}}
constexpr ValueType getLength() const noexcept
void prepareToPlay(const PlaybackInitialisationInfo &info) override
Called once before playback begins for each node.
NodeProperties getNodeProperties() override
Should return the properties of the node.
std::vector< Node * > getDirectInputNodes() override
Should return all the inputs directly feeding in to this node.
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.
Main graph Node processor class.
virtual NodeProperties getNodeProperties()=0
Should return the properties of the node.
void setOptimisations(NodeOptimisations)
This can be called to provide some hints about allocating or playing back a Node to improve efficienc...
bool hasProcessed() const
Returns true if this node has processed and its outputs can be retrieved.
AudioAndMidiBuffer getProcessedOutput()
Returns the processed audio and MIDI output.
Struct to describe a single iteration of a process call.
T get(T... args)
T is_pointer_v
#define jassert(expression)
typedef int
Holds a graph in an order ready for processing and a sorted map for quick lookups.
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...
typedef size_t