11namespace tracktion {
inline namespace engine
18 : wetInput (
std::move (wetNode)),
20 wetGainFunction (
std::move (wetGainFunc)),
21 dryGainFunction (
std::move (dryGainFunc))
28 lastWetGain = wetGainFunction();
29 lastDryGain = dryGainFunction();
34 return { wetInput.get(), dryInput };
39 auto wetProps = wetInput->getNodeProperties();
42 auto props = wetProps;
43 props.hasAudio =
true;
44 props.numberOfChannels =
std::max (wetProps.numberOfChannels, dryProps.numberOfChannels);
45 props.latencyNumSamples =
std::max (wetProps.latencyNumSamples, dryProps.latencyNumSamples);
46 hash_combine (props.nodeID, dryProps.nodeID);
48 constexpr size_t rackReturnNodeMagicHash =
size_t (0x726b52657475726e);
50 if (props.nodeID != 0)
51 hash_combine (props.nodeID, rackReturnNodeMagicHash);
59 return TransformResult::none;
61 hasTransformed =
true;
62 auto wetProps = wetInput->getNodeProperties();
64 assert (dryProps.latencyNumSamples <= wetProps.latencyNumSamples);
66 if (wetProps.latencyNumSamples > dryProps.latencyNumSamples)
68 const int numLatencySamples = wetProps.latencyNumSamples - dryProps.latencyNumSamples;
69 dryLatencyNode = tracktion::graph::makeNode<tracktion::graph::LatencyNode> (dryInput, numLatencySamples);
70 dryInput = dryLatencyNode.get();
72 return TransformResult::connectionsMade;
75 return TransformResult::none;
80 if (wetInput->numOutputNodes > 1)
83 const auto inputNumChannels = wetInput->getNodeProperties().numberOfChannels;
86 if (inputNumChannels >= desiredNumChannels)
88 canUseWetSourceBuffers =
true;
90 tracktion::graph::AllocateAudioBuffer::no });
96 return wetInput->hasProcessed() && dryInput->
hasProcessed();
101 if (canUseWetSourceBuffers)
107 auto destAudio = pc.buffers.audio;
109 auto wetSource = wetInput->getProcessedOutput();
112 assert (destAudio.getNumFrames() == wetSource.audio.getNumFrames());
113 assert (wetSource.audio.getNumFrames() == drySource.audio.getNumFrames());
115 const float wetGain = wetGainFunction();
116 const float dryGain = dryGainFunction();
120 pc.buffers.midi.copyFrom (wetSource.midi);
124 copyIfNotAliased (destAudio.getFirstChannels (wetSource.audio.getNumChannels()),
127 if (wetGain == lastWetGain)
130 applyGain (destAudio, wetGain);
134 const auto step = (wetGain - lastWetGain) / destAudio.getNumFrames();
135 applyGainPerFrame (destAudio, [start = lastWetGain, step]()
mutable {
return start += step; });
137 lastWetGain = wetGain;
142 auto dryDestView = destAudio.getFirstChannels (drySource.audio.getNumChannels());
144 if (dryGain == lastDryGain)
147 add (dryDestView, drySource.audio);
149 tracktion::graph::add (dryDestView, drySource.audio, dryGain);
153 tracktion::graph::addApplyingGainRamp (dryDestView, drySource.audio, lastDryGain, dryGain);
154 lastDryGain = dryGain;
tracktion::graph::NodeProperties getNodeProperties() override
Should return the properties of the node.
void preProcess(choc::buffer::FrameCount, juce::Range< int64_t >) override
Called when the node is to be processed, just before process.
bool isReadyToProcess() override
Should return true when this node is ready to be processed.
void process(ProcessContext &) override
Called when the node is to be processed.
RackReturnNode(std::unique_ptr< Node > wetNode, std::function< float()> wetGainFunc, Node *dryNode, std::function< float()> dryGainFunc)
Creates a RackInstanceNode that maps an input node channel to an output channel and applies a gain pa...
std::vector< Node * > getDirectInputNodes() override
Should return all the inputs directly feeding in to this node.
void prepareToPlay(const tracktion::graph::PlaybackInitialisationInfo &) override
Called once before playback begins for each node.
TransformResult transform(Node &, const std::vector< Node * > &, TransformCache &) override
Called after construction to give the node a chance to modify its topology.
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...
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.
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.
TransformResult
Enum to signify the result of the transform function.
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...