14namespace tracktion {
inline namespace engine
19 double sampleRateToUse,
int blockSizeToUse,
22 : input (
std::move (inputNode)),
23 modifier (
std::move (modifierToProcess)),
24 trackMuteState (trackMuteStateToUse),
25 playHeadState (&playHeadStateToUse),
26 isRendering (rendering)
30 initialiseModifier (sampleRateToUse, blockSizeToUse);
35 double sampleRateToUse,
int blockSizeToUse,
37 : input (
std::move (inputNode)),
38 modifier (
std::move (modifierToProcess)),
39 audioRenderContextProvider (
std::move (contextProvider))
43 initialiseModifier (sampleRateToUse, blockSizeToUse);
48 if (isInitialised && ! modifier->baseClassNeedsInitialising())
49 modifier->baseClassDeinitialise();
55 auto props = input->getNodeProperties();
57 props.numberOfChannels =
juce::jmax (props.numberOfChannels, modifier->getAudioInputNames().size());
58 props.hasAudio = props.hasAudio || modifier->getAudioInputNames().size() > 0;
59 props.hasMidi = props.hasMidi || modifier->getMidiInputNames().size() > 0;
60 props.nodeID = (
size_t) modifier->itemID.getRawID();
68 jassert (sampleRate == info.sampleRate);
72 if (props.latencyNumSamples > 0)
73 automationAdjustmentTime = TimeDuration::fromSamples (-props.latencyNumSamples, sampleRate);
78 auto inputBuffers = input->getProcessedOutput();
79 auto& inputAudioBlock = inputBuffers.audio;
81 auto& outputBuffers = pc.buffers;
82 auto& outputAudioBlock = outputBuffers.audio;
86 if (
auto numInputChannelsToCopy =
std::min (inputAudioBlock.getNumChannels(),
87 outputAudioBlock.getNumChannels()))
89 jassert (inputAudioBlock.getNumFrames() == outputAudioBlock.getNumFrames());
90 copy (outputAudioBlock.getFirstChannels (numInputChannelsToCopy),
91 inputAudioBlock.getFirstChannels (numInputChannelsToCopy));
95 auto outputAudioBuffer = tracktion::graph::toAudioBuffer (outputAudioBlock);
98 midiMessageArray.copyFrom (inputBuffers.midi);
102 midiMessageArray.isAllNotesOff =
true;
104 if (trackMuteState !=
nullptr)
111 midiMessageArray.isAllNotesOff =
true;
117 modifier->baseClassApplyToBuffer (getPluginRenderContext (pc.referenceSampleRange, outputAudioBuffer));
120 outputBuffers.midi.copyFrom (midiMessageArray);
124void ModifierNode::initialiseModifier (
double sampleRateToUse,
int blockSizeToUse)
126 sampleRate = sampleRateToUse;
127 modifier->baseClassInitialise (sampleRate, blockSizeToUse);
128 isInitialised =
true;
133 if (audioRenderContextProvider !=
nullptr)
136 rc.destBuffer = &destBuffer;
137 rc.bufferStartSample = 0;
139 rc.bufferForMidiMessages = &midiMessageArray;
140 rc.midiBufferOffset = 0.0;
145 jassert (playHeadState !=
nullptr);
146 auto& playHead = playHeadState->playHead;
148 const auto timelineRange = referenceSampleRangeToSplitTimelineRange (playHead, referenceSampleRange);
149 jassert (! timelineRange.isSplit);
151 return { &destBuffer,
154 &midiMessageArray, 0.0,
155 timeRangeFromSamples (timelineRange.timelineRange1, sampleRate) + automationAdjustmentTime,
156 playHead.isPlaying(), playHead.isUserDragging(), isRendering,
false };
int getNumChannels() const noexcept
int getNumSamples() const noexcept
static AudioChannelSet JUCE_CALLTYPE canonicalChannelSet(int numChannels)
void prepareToPlay(const tracktion::graph::PlaybackInitialisationInfo &) override
Called once before playback begins for each node.
void process(ProcessContext &) override
Called when the node is to be processed.
ModifierNode(std::unique_ptr< Node > input, tracktion::engine::Modifier::Ptr, double sampleRateToUse, int blockSizeToUse, const TrackMuteState *, tracktion::graph::PlayHeadState &, bool rendering)
Creates a ModifierNode to process a Modifier.
tracktion::graph::NodeProperties getNodeProperties() override
Should return the properties of the node.
~ModifierNode() override
Destructor.
Holds the state of a Track and if its contents/plugins should be played or not.
bool shouldTrackBeAudible() const
Returns true if the track's mix bus should be audible.
bool shouldTrackContentsBeProcessed() const
Returns true if the track's contents should be processed e.g.
bool wasJustMuted() const
Returns true if the last block was audible but this one isn't.
Struct to describe a single iteration of a process call.
Determines how this block releates to other previous render blocks and if the play head has jumped in...
bool didPlayheadJump() noexcept
Returns true if the play head jumped.
constexpr Type jmax(Type a, Type b)
void ignoreUnused(Types &&...) noexcept
bool getBoolParamValue(const AutomatableParameter &ap)
Returns a bool version of an AutomatableParameter.
The context passed to plugin render methods to provide it with buffers to fill.
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...