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

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_LiveMidiOutputNode.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//==============================================================================
16LiveMidiOutputNode::LiveMidiOutputNode (AudioTrack& at, std::unique_ptr<tracktion::graph::Node> inputNode)
17 : track (&at), trackPtr (at), input (std::move (inputNode))
18{
19 jassert (input);
20
21 setOptimisations ({ tracktion::graph::ClearBuffers::no,
22 tracktion::graph::AllocateAudioBuffer::no });
23
24 pendingMessages.reserve (50);
25 dispatchingMessages.reserve (50);
26}
27
28LiveMidiOutputNode::LiveMidiOutputNode (Clip& c, std::unique_ptr<tracktion::graph::Node> inputNode)
29 : clipPtr (c), input (std::move (inputNode))
30{
31 jassert (input);
32
33 setOptimisations ({ tracktion::graph::ClearBuffers::no,
34 tracktion::graph::AllocateAudioBuffer::no });
35
36 pendingMessages.reserve (50);
37 dispatchingMessages.reserve (50);
38}
39
40//==============================================================================
41tracktion::graph::NodeProperties LiveMidiOutputNode::getNodeProperties()
42{
43 auto props = input->getNodeProperties();
44 props.nodeID = 0;
45
46 return props;
47}
48
49std::vector<tracktion::graph::Node*> LiveMidiOutputNode::getDirectInputNodes()
50{
51 return { input.get() };
52}
53
54void LiveMidiOutputNode::prepareToPlay (const tracktion::graph::PlaybackInitialisationInfo&)
55{
56}
57
58bool LiveMidiOutputNode::isReadyToProcess()
59{
60 return input->hasProcessed();
61}
62
63void LiveMidiOutputNode::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 // If the source only outputs to this node, we can steal its data
70 if (input->numOutputNodes == 1)
71 destMidiBlock.swapWith (sourceBuffers.midi);
72 else
73 destMidiBlock.copyFrom (sourceBuffers.midi);
74
75 setAudioOutput (input.get(), sourceBuffers.audio);
76
77 bool needToUpdate = false;
78
79 if (sourceBuffers.midi.isNotEmpty())
80 {
81 const std::scoped_lock sl (mutex);
82
83 for (auto& m : sourceBuffers.midi)
84 pendingMessages.add (m);
85
86 needToUpdate = ! pendingMessages.isEmpty();
87 }
88
89 if (needToUpdate)
90 triggerAsyncUpdate();
91}
92
93//==============================================================================
94void LiveMidiOutputNode::handleAsyncUpdate()
95{
96 {
97 const std::scoped_lock sl (mutex);
98 pendingMessages.swapWith (dispatchingMessages);
99 }
100
101 if (track != nullptr)
102 for (auto& m : dispatchingMessages)
103 track->getListeners().call (&AudioTrack::Listener::recordedMidiMessageSentToPlugins, *track, m);
104
105 if (clipPtr != nullptr)
106 for (auto& m : dispatchingMessages)
107 clipPtr->getListeners().call (&Clip::Listener::midiMessageGenerated, *clipPtr, m);
108
109 dispatchingMessages.clear();
110}
111
112}} // namespace tracktion { inline namespace engine
A clip in an edit.
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...