Krotos Modules 3
Loading...
Searching...
No Matches
KwidgetProcessorGraph.cpp
Go to the documentation of this file.
1namespace krotos
2{
3 KwidgetProcessorGraph::KwidgetProcessorGraph(int numVoices, int inputChannels, int outputChannels)
4 : m_numVoices(numVoices), m_numInputChannels(inputChannels), m_numOutputChannels(outputChannels)
5 {
6 // Every voice has an AudioProcessorGraph created for it here
7 for (int i = 0; i < m_numVoices; i++)
8 {
9 // Create the AudioProcessorGraph
10 auto& graph = *m_graphs.add(new AudioProcessorGraph());
11
12 // ... and add one of each type of in/out node to every AudioProcessorGraph
13 // and keep pointers to those nodes in m_audioInputNodes, m_audioOutputNodes etc...
14 m_audioInputNodes.add(graph.addNode(std::make_unique<IOProcessor>(IOProcessor::audioInputNode)));
15 m_audioOutputNodes.add(graph.addNode(std::make_unique<IOProcessor>(IOProcessor::audioOutputNode)));
16 m_midiInputNodes.add(graph.addNode(std::make_unique<IOProcessor>(IOProcessor::midiInputNode)));
17 m_midiOutputNodes.add(graph.addNode(std::make_unique<IOProcessor>(IOProcessor::midiOutputNode)));
18
19 graph.setPlayConfigDetails(m_numInputChannels, m_numOutputChannels, 44100.0, 1024);
20 graph.prepareToPlay(44100.0, 1024);
21 }
22 }
23
24 void KwidgetProcessorGraph::addKwidget(std::unique_ptr<Kwidget> kwidgetToAdd)
25 {
26 auto kwidget = kwidgetToAdd.release();
27 auto node = m_graphs[0]->addNode(kwidget->createVoice());
28
29 // If you are here, then AudioProcessorGraph did not like the processor you gave it.
30 jassert(node != nullptr);
31
32 auto id = node->nodeID;
33 for (int i = 1; i < getNumVoices(); i++)
34 node = m_graphs[i]->addNode(kwidget->createVoice(), id);
35
36 m_nodeIDs[kwidget] = node->nodeID;
37 m_kwidgets.add(kwidget);
38 }
39
41 {
42 auto id = getNodeID(kwidget);
43 for (auto g : m_graphs)
44 g->removeNode(id);
45
46 m_kwidgets.removeObject(kwidget);
47 m_nodeIDs.erase(kwidget);
48 }
49
51 {
52 return canConnect(getNodeID(src), getNodeID(dest));
53 }
54
55 void KwidgetProcessorGraph::addConnection(Kwidget* src, Kwidget* dest, int baseChannel, int numConnections)
56 {
57 addMultipleConnections(getNodeID(src), getNodeID(dest), baseChannel, numConnections);
58 }
59
64
65 void KwidgetProcessorGraph::connectToInputNode(Kwidget* dest, int baseChannel, int numConnections)
66 {
67 addMultipleConnections(m_audioInputNodes[0]->nodeID, getNodeID(dest), baseChannel, numConnections);
68 }
69
70 void KwidgetProcessorGraph::connectToOutputNode(Kwidget* src, int baseChannel, int numChannels)
71 {
72 addMultipleConnectionsToOutputNode(getNodeID(src), baseChannel, numChannels);
73 }
74
76 {
77 auto connections = m_graphs[0]->getConnections();
78
79 for (auto& c : connections)
80 for (auto g : m_graphs)
81 g->removeConnection(c);
82 }
83
85 {
86 std::vector<Kwidget*> currentKwidgets;
87
88 for (auto& kwidget : m_kwidgets)
89 currentKwidgets.push_back(kwidget);
90
91 for (auto& kwidget : currentKwidgets)
92 removeKwidget(kwidget);
93 }
94
95 void KwidgetProcessorGraph::prepareToPlay(double sampleRate, int samplesPerBlock)
96 {
97 m_sampleRate = sampleRate;
98 m_blockSize = samplesPerBlock;
99
100 for (int i = 0; i < getNumVoices(); i++)
101 {
102 auto& g = *m_graphs[i];
103 g.setPlayConfigDetails(m_numInputChannels, m_numOutputChannels, sampleRate, samplesPerBlock);
104 g.prepareToPlay(sampleRate, samplesPerBlock);
105 }
106 }
107
108 void KwidgetProcessorGraph::noteOn(int voiceIdx, int midiNote, float velocity)
109 {
110 jassert(isPositiveAndBelow(voiceIdx, getNumVoices()));
111
112 for (auto k : m_kwidgets)
113 {
114 if (!k->isAChildKwidget()) // We ignore child kwidgets
115 {
116 k->noteOn(voiceIdx, midiNote, velocity);
117 }
118 }
119 }
120
121 void KwidgetProcessorGraph::noteOff(int voiceIdx, float velocity)
122 {
123 jassert(isPositiveAndBelow(voiceIdx, getNumVoices()));
124
125 for (auto k : m_kwidgets)
126 {
127 if (!k->isAChildKwidget()) // We ignore child kwidgets
128 {
129 k->noteOff(voiceIdx, velocity);
130 }
131 }
132 }
133
135 {
136 jassert(isPositiveAndBelow(voiceIdx, getNumVoices()));
137
138 // Clears every processor including child kwidget processors
139 for (auto k : m_kwidgets)
140 {
141 k->noteCleared(voiceIdx);
142 }
143 }
144
146 {
147 jassert(isPositiveAndBelow(voiceIdx, getNumVoices()));
148
149 for (auto k : m_kwidgets)
150 {
151 if (!k->isAChildKwidget()) // We don't poll child kwidgets - parents must do that
152 {
153 if (k->isActive(voiceIdx))
154 {
155 return true;
156 }
157 }
158 }
159
160 return false;
161 }
162
163 void KwidgetProcessorGraph::processVoice(int voiceIdx, AudioBuffer<float>& buffer)
164 {
165 jassert(isPositiveAndBelow(voiceIdx, getNumVoices()));
166
167 MidiBuffer m;
168 m_graphs[voiceIdx]->processBlock(buffer, m);
169 }
170
172 {
173 auto connections = m_graphs[0]->getConnections();
174
175 for (auto& c : connections)
176 {
177 auto src = m_graphs[0]->getNodeForId(c.source.nodeID)->getProcessor();
178 auto dest = m_graphs[0]->getNodeForId(c.destination.nodeID)->getProcessor();
179
180 String srcID = "";
181 if (auto kp = dynamic_cast<KwidgetProcessor*>(src))
182 srcID = kp->getKwidgetID();
183
184 String destID = "";
185 if (auto kp = dynamic_cast<KwidgetProcessor*>(dest))
186 destID = kp->getKwidgetID();
187
188 DBG("Connection\nChannel: " << c.source.channelIndex << "\nSource: " << srcID
189 << "\nDest: " << destID + "\n");
190 }
191 }
192
193 AudioProcessorGraph::NodeID KwidgetProcessorGraph::getNodeID(Kwidget* k)
194 {
195 jassert(m_nodeIDs.count(k) == 1);
196 return m_nodeIDs.at(k);
197 }
198
200 {
201 auto g = m_graphs.getUnchecked(0);
202
203 if (g->isAnInputTo(*g->getNodeForId(dest), *g->getNodeForId(src)))
204 return false;
205
206 // TODO During the big refactor, replace this commented out code with something which doesn't always return true
207 // if (g->isConnected(src, dest))
208 // return false;
209 /*
210 for (int i = 0; i < m_numOutputChannels; i++)
211 if (g->canConnect({ { src, i }, { dest, i } }) == false)
212 return false;
213 */
214 return true;
215 }
216
217 void KwidgetProcessorGraph::addMultipleConnections(NodeID src, NodeID dest, int baseChannel, int numConnections)
218 {
219 jassert(baseChannel <= m_numOutputChannels - numConnections);
220 for (auto g : m_graphs)
221 for (int channel = 0; channel < numConnections; channel++)
222 if (g->addConnection({{src, channel}, {dest, channel + baseChannel}}) == false)
223 jassertfalse;
224 }
225
226 void KwidgetProcessorGraph::addMultipleConnectionsToOutputNode(NodeID src, int baseChannel, int numConnections)
227 {
228 jassert(baseChannel <= m_numOutputChannels - numConnections);
229
230 for (int graphIndex = 0; graphIndex < m_graphs.size(); graphIndex++)
231 {
232 auto g = m_graphs[graphIndex];
233 auto outputNodeID = m_audioOutputNodes[graphIndex]->nodeID;
234 for (int channel = 0; channel < numConnections; channel++)
235 {
236 if (g->addConnection({{src, channel}, {outputNodeID, channel + baseChannel}}) == false)
237 {
238 jassertfalse;
239 }
240 }
241 }
242 }
243
244 void KwidgetProcessorGraph::removeConnection(NodeID src, NodeID dest)
245 {
246 for (auto g : m_graphs)
247 for (int i = 0; i < m_numOutputChannels; i++)
248 g->removeConnection({{src, i}, {dest, i}});
249 }
250} // namespace krotos
Definition Kwidget.h:8
double m_sampleRate
Definition KwidgetProcessorGraph.h:121
void clearConnections()
Definition KwidgetProcessorGraph.cpp:75
void addKwidget(std::unique_ptr< Kwidget > kwidgetToAdd)
Definition KwidgetProcessorGraph.cpp:24
Array< Node::Ptr > m_midiInputNodes
Definition KwidgetProcessorGraph.h:128
int m_blockSize
Definition KwidgetProcessorGraph.h:122
Array< Node::Ptr > m_audioInputNodes
Definition KwidgetProcessorGraph.h:126
void addMultipleConnections(NodeID src, NodeID dest, int baseChannel, int numConnections)
Definition KwidgetProcessorGraph.cpp:217
int m_numOutputChannels
Definition KwidgetProcessorGraph.h:124
OwnedArray< Kwidget > m_kwidgets
Definition KwidgetProcessorGraph.h:116
void connectToInputNode(Kwidget *dest, int baseChannel, int numConnections)
Definition KwidgetProcessorGraph.cpp:65
AudioProcessorGraph::NodeID NodeID
Definition KwidgetProcessorGraph.h:21
void addMultipleConnectionsToOutputNode(NodeID src, int baseChannel, int numConnections)
Definition KwidgetProcessorGraph.cpp:226
std::map< Kwidget *, NodeID > m_nodeIDs
Definition KwidgetProcessorGraph.h:117
void prepareToPlay(double sampleRate, int samplesPerBlock)
Definition KwidgetProcessorGraph.cpp:95
void addConnection(Kwidget *src, Kwidget *dest, int baseChannel, int numConnections)
Definition KwidgetProcessorGraph.cpp:55
void removeKwidget(Kwidget *kwidget)
Definition KwidgetProcessorGraph.cpp:40
void removeConnection(Kwidget *src, Kwidget *dest)
Definition KwidgetProcessorGraph.cpp:60
void clearKwidgets()
Definition KwidgetProcessorGraph.cpp:84
void noteOn(int voiceIdx, int midiNote, float velocity)
Definition KwidgetProcessorGraph.cpp:108
bool isActive(int voiceIdx)
Definition KwidgetProcessorGraph.cpp:145
NodeID getNodeID(Kwidget *k)
Definition KwidgetProcessorGraph.cpp:193
KwidgetProcessorGraph(int numVoices, int inputChannels, int outputChannels)
Definition KwidgetProcessorGraph.cpp:3
void noteCleared(int voiceIdx)
Definition KwidgetProcessorGraph.cpp:134
int m_numInputChannels
Definition KwidgetProcessorGraph.h:123
void debugConnections() const
Definition KwidgetProcessorGraph.cpp:171
void processVoice(int voiceIdx, AudioBuffer< float > &buffer)
Definition KwidgetProcessorGraph.cpp:163
Array< Node::Ptr > m_audioOutputNodes
Definition KwidgetProcessorGraph.h:127
OwnedArray< AudioProcessorGraph > m_graphs
Definition KwidgetProcessorGraph.h:119
void noteOff(int voiceIdx, float velocity)
Definition KwidgetProcessorGraph.cpp:121
int getNumVoices() const
Definition KwidgetProcessorGraph.h:35
const int m_numVoices
Definition KwidgetProcessorGraph.h:114
bool canConnect(Kwidget *src, Kwidget *dest)
Definition KwidgetProcessorGraph.cpp:50
void connectToOutputNode(Kwidget *src, int baseChannel, int numChannels)
Definition KwidgetProcessorGraph.cpp:70
Array< Node::Ptr > m_midiOutputNodes
Definition KwidgetProcessorGraph.h:129
An interface for an audio processor designed for modular use.
Definition KwidgetProcessor.h:8
Definition AirAbsorptionFilter.cpp:2