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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_LiveMidiInjectingNode.cpp
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
11namespace tracktion { inline namespace engine
12{
13
14//==============================================================================
15//==============================================================================
16LiveMidiInjectingNode::LiveMidiInjectingNode (AudioTrack& at, std::unique_ptr<tracktion::graph::Node> inputNode)
17 : track (at), input (std::move (inputNode))
18{
19 setOptimisations ({ tracktion::graph::ClearBuffers::no,
20 tracktion::graph::AllocateAudioBuffer::no });
21
22 track->addListener (this);
23}
24
25LiveMidiInjectingNode::~LiveMidiInjectingNode()
26{
27 track->removeListener (this);
28}
29
30//==============================================================================
31tracktion::graph::NodeProperties LiveMidiInjectingNode::getNodeProperties()
32{
33 auto props = input->getNodeProperties();
34 props.hasMidi = true;
35 hash_combine (props.nodeID, track->itemID.getRawID());
36
37 return props;
38}
39
40std::vector<tracktion::graph::Node*> LiveMidiInjectingNode::getDirectInputNodes()
41{
42 return { input.get() };
43}
44
45void LiveMidiInjectingNode::prepareToPlay (const tracktion::graph::PlaybackInitialisationInfo& info)
46{
47 if (auto oldNode = findNodeWithIDIfNonZero<LiveMidiInjectingNode> (info.nodeGraphToReplace, getNodeProperties().nodeID))
48 {
49 if (oldNode->track == track)
50 {
51 const juce::ScopedLock sl2 (oldNode->liveMidiLock);
52 liveMidiMessages.swapWith (oldNode->liveMidiMessages);
53 midiSourceID = oldNode->midiSourceID;
54 }
55 }
56}
57
58bool LiveMidiInjectingNode::isReadyToProcess()
59{
60 return input->hasProcessed();
61}
62
63void LiveMidiInjectingNode::process (ProcessContext& pc)
64{
65 auto sourceBuffers = input->getProcessedOutput();
66 auto& destMidiBlock = pc.buffers.midi;
67 jassert (sourceBuffers.audio.getSize() == pc.buffers.audio.getSize());
68
69 destMidiBlock.copyFrom (sourceBuffers.midi);
70 setAudioOutput (input.get(), sourceBuffers.audio);
71
72 const juce::ScopedLock sl (liveMidiLock);
73
74 if (liveMidiMessages.isEmpty())
75 return;
76
77 destMidiBlock.mergeFromAndClear (liveMidiMessages);
78}
79
80//==============================================================================
81void LiveMidiInjectingNode::injectMessage (MidiMessageArray::MidiMessageWithSource mm)
82{
83 mm.setTimeStamp (0.0);
84
85 const juce::ScopedLock sl (liveMidiLock);
86 liveMidiMessages.add (std::move (mm));
87}
88
89//==============================================================================
90void LiveMidiInjectingNode::injectLiveMidiMessage (AudioTrack& at, const MidiMessageArray::MidiMessageWithSource& mm, bool& wasUsed)
91{
92 if (&at != track.get())
93 return;
94
95 injectMessage (mm);
96 wasUsed = true;
97}
98
99}} // namespace tracktion { inline namespace engine
void setTimeStamp(double newTimestamp) noexcept
Struct to describe a single iteration of a process call.
#define jassert(expression)
T move(T... args)
Holds some really basic properties of a node.
Passed into Nodes when they are being initialised, to give them useful contextual information that th...