MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Graph.cpp
Go to the documentation of this file.
1#include "Graph.hpp"
2
3#include "Core.hpp"
4
5#include "Chronie.hpp"
6
14
16
17namespace MayaFlux {
18
19namespace internal {
20 std::shared_ptr<Buffers::BufferProcessor> attach_quick_process_audio(Buffers::AudioProcessingFunction processor, const std::shared_ptr<Buffers::AudioBuffer>& buffer)
21 {
22 return get_buffer_manager()->attach_quick_process(std::move(processor), buffer, Buffers::ProcessingToken::AUDIO_BACKEND);
23 }
24
25 std::shared_ptr<Buffers::BufferProcessor> attach_quick_process_graphics(Buffers::GraphicsProcessingFunction processor, const std::shared_ptr<Buffers::VKBuffer>& buffer)
26 {
27 return get_buffer_manager()->attach_quick_process(std::move(processor), buffer, Buffers::ProcessingToken::GRAPHICS_BACKEND);
28 }
29}
30
31//-------------------------------------------------------------------------
32// Node Graph Management
33//-------------------------------------------------------------------------
34
35std::shared_ptr<Nodes::NodeGraphManager> get_node_graph_manager()
36{
38}
39
40void register_audio_node(const std::shared_ptr<Nodes::Node>& node, uint32_t channel)
41{
42 auto manager = get_node_graph_manager();
43 if (!manager) {
45 "Node graph manager not initialized - cannot register audio node");
46 return;
47 }
48 if (channel >= manager->get_channel_count(Nodes::ProcessingToken::AUDIO_RATE)) {
49 MF_ERROR(Journal::Component::API, Journal::Context::NodeProcessing, "Channel index {} out of range for audio node registration", channel);
50 }
51 manager->add_to_root(node, Nodes::ProcessingToken::AUDIO_RATE, channel);
52}
53
54void register_audio_node(const std::shared_ptr<Nodes::Node>& node, const std::vector<uint32_t>& channels)
55{
56 for (const auto& channel : channels) {
57 register_audio_node(node, channel);
58 }
59}
60
61void unregister_audio_node(const std::shared_ptr<Nodes::Node>& node, uint32_t channel)
62{
63 auto manager = get_node_graph_manager();
64 if (!manager) {
66 "Node graph manager not initialized - cannot unregister audio node");
67 return;
68 }
69
70 if (channel >= manager->get_channel_count(Nodes::ProcessingToken::AUDIO_RATE)) {
72 "Channel index out of range for audio node registration");
73 }
74 manager->remove_from_root(node, Nodes::ProcessingToken::AUDIO_RATE, channel);
75}
76
77void unregister_audio_node(const std::shared_ptr<Nodes::Node>& node, const std::vector<uint32_t>& channels)
78{
79 for (const auto& channel : channels) {
80 unregister_audio_node(node, channel);
81 }
82}
83
84void unregister_node(const std::shared_ptr<Nodes::Node>& node, const Nodes::ProcessingToken& token, uint32_t channel)
85{
86 auto manager = get_node_graph_manager();
87 if (!manager) {
89 "Node graph manager not initialized - cannot register node");
90 return;
91 }
92
93 if (channel >= manager->get_channel_count(token)) {
95 "Channel index out of range for audio node registration");
96 }
97 manager->remove_from_root(node, token, channel);
98}
99
101 const std::shared_ptr<Nodes::Node>& node,
102 const std::vector<uint32_t>& channels,
103 uint32_t num_samples,
104 const Nodes::ProcessingToken& token)
105{
106 get_node_graph_manager()->route_node_to_channels(node, channels, num_samples, token);
107}
108
110 const std::shared_ptr<Nodes::Node>& node,
111 const std::vector<uint32_t>& channels,
112 double seconds_to_fade,
113 const Nodes::ProcessingToken& token)
114{
115 get_node_graph_manager()->route_node_to_channels(node, channels, seconds_to_samples(seconds_to_fade), token);
116}
117
119{
120 return *get_context().get_node_graph_manager()->get_all_root_nodes(Nodes::ProcessingToken::AUDIO_RATE)[channel];
121}
122
123void register_node(const std::shared_ptr<Nodes::Node>& node, const Nodes::ProcessingToken& token, uint32_t channel)
124{
125 get_context().get_node_graph_manager()->add_to_root(node, token, channel);
126}
127
128//-------------------------------------------------------------------------
129// Buffer Management
130//-------------------------------------------------------------------------
131
132std::shared_ptr<Buffers::BufferManager> get_buffer_manager()
133{
135}
136
137void add_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, const std::shared_ptr<Buffers::Buffer>& buffer, Buffers::ProcessingToken token)
138{
139 get_buffer_manager()->add_processor(processor, buffer, token);
140}
141
142void add_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, Buffers::ProcessingToken token, uint32_t channel)
143{
144 get_buffer_manager()->add_processor(processor, token, channel);
145}
146
147void add_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, Buffers::ProcessingToken token)
148{
149 get_buffer_manager()->add_processor(processor, token);
150}
151
152void remove_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, const std::shared_ptr<Buffers::Buffer>& buffer)
153{
154 get_buffer_manager()->remove_processor(processor, buffer);
155}
156
157void remove_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, uint32_t channel, Buffers::ProcessingToken token)
158{
159 get_buffer_manager()->remove_processor_from_channel(processor, token, channel);
160}
161
162void remove_processor(const std::shared_ptr<Buffers::BufferProcessor>& processor, Buffers::ProcessingToken token)
163{
164 get_buffer_manager()->remove_processor_from_token(processor, token);
165}
166
167std::shared_ptr<Buffers::BufferProcessingChain> create_processing_chain()
168{
169 return std::make_shared<Buffers::BufferProcessingChain>();
170}
171
173{
174 return *get_buffer_manager()->get_root_audio_buffer(Buffers::ProcessingToken::AUDIO_BACKEND, channel);
175}
176
177void connect_node_to_channel(const std::shared_ptr<Nodes::Node>& node, uint32_t channel_index, float mix, bool clear_before)
178{
179 auto token = get_buffer_manager()->get_default_audio_token();
180 get_buffer_manager()->connect_node_to_channel(node, token, channel_index, mix, clear_before);
181}
182
183void connect_node_to_buffer(const std::shared_ptr<Nodes::Node>& node, const std::shared_ptr<Buffers::AudioBuffer>& buffer, float mix, bool clear_before)
184{
185 get_buffer_manager()->connect_node_to_buffer(node, buffer, mix, clear_before);
186}
187
188//-------------------------------------------------------------------------
189// Node Network Management
190//-------------------------------------------------------------------------
191
192void register_node_network(const std::shared_ptr<Nodes::Network::NodeNetwork>& network, const Nodes::ProcessingToken& token)
193{
194 get_context().get_node_graph_manager()->add_network(network, token);
195}
196
197void unregister_node_network(const std::shared_ptr<Nodes::Network::NodeNetwork>& network, const Nodes::ProcessingToken& token)
198{
199 get_context().get_node_graph_manager()->remove_network(network, token);
200}
201
203 const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
204 const std::vector<uint32_t>& channels,
205 uint32_t num_samples,
206 const Nodes::ProcessingToken& token)
207{
208 get_node_graph_manager()->route_network_to_channels(network, channels, num_samples, token);
209}
210
212 const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
213 const std::vector<uint32_t>& channels,
214 double seconds_to_fade,
215 const Nodes::ProcessingToken& token)
216{
217 get_node_graph_manager()->route_network_to_channels(network, channels, seconds_to_samples(seconds_to_fade), token);
218}
219
220//-------------------------------------------------------------------------
221// Audio Processing
222//-------------------------------------------------------------------------
223
224std::shared_ptr<Buffers::BufferProcessor> attach_quick_process(Buffers::AudioProcessingFunction processor, unsigned int channel_id)
225{
226 return get_buffer_manager()->attach_quick_process(std::move(processor), Buffers::ProcessingToken::AUDIO_BACKEND, channel_id);
227}
228
229void register_audio_buffer(const std::shared_ptr<Buffers::AudioBuffer>& buffer, uint32_t channel)
230{
231 get_buffer_manager()->add_buffer(buffer, Buffers::ProcessingToken::AUDIO_BACKEND, channel);
232}
233
234void unregister_audio_buffer(const std::shared_ptr<Buffers::AudioBuffer>& buffer, uint32_t channel)
235{
236 get_buffer_manager()->remove_buffer(buffer, Buffers::ProcessingToken::AUDIO_BACKEND, channel);
237}
238
239void register_graphics_buffer(const std::shared_ptr<Buffers::VKBuffer>& buffer, Buffers::ProcessingToken token)
240{
241 get_buffer_manager()->add_buffer(buffer, token);
242}
243
244void unregister_graphics_buffer(const std::shared_ptr<Buffers::VKBuffer>& buffer)
245{
247}
248
249void read_from_audio_input(const std::shared_ptr<Buffers::AudioBuffer>& buffer, uint32_t channel)
250{
251 get_buffer_manager()->register_input_listener(buffer, channel);
252}
253
254void detach_from_audio_input(const std::shared_ptr<Buffers::AudioBuffer>& buffer, uint32_t channel)
255{
256 get_buffer_manager()->unregister_input_listener(buffer, channel);
257}
258
259std::shared_ptr<Buffers::AudioBuffer> create_input_listener_buffer(uint32_t channel, bool add_to_output)
260{
261 std::shared_ptr<Buffers::AudioBuffer> buffer = std::make_shared<Buffers::AudioBuffer>(channel);
262
263 if (add_to_output) {
264 register_audio_buffer(buffer, channel);
265 }
266 read_from_audio_input(buffer, channel);
267
268 return buffer;
269}
270
271std::vector<std::shared_ptr<Buffers::AudioBuffer>> clone_buffer_to_channels(const std::shared_ptr<Buffers::AudioBuffer>& buffer,
272 const std::vector<uint32_t>& channels)
273{
274 return get_buffer_manager()->clone_buffer_for_channels(buffer, channels, Buffers::ProcessingToken::AUDIO_BACKEND);
275}
276
277std::vector<std::shared_ptr<Buffers::AudioBuffer>> clone_buffer_to_channels(const std::shared_ptr<Buffers::AudioBuffer>& buffer, const std::vector<uint32_t>& channels, const Buffers::ProcessingToken& token)
278{
279 return get_buffer_manager()->clone_buffer_for_channels(buffer, channels, token);
280}
281
282void supply_buffer_to_channel(const std::shared_ptr<Buffers::AudioBuffer>& buffer,
283 uint32_t channel, double mix)
284{
285 auto manager = get_buffer_manager();
286 if (!manager) {
288 "Buffer manager not initialized - cannot perform supply_buffer_to_channel");
289 return;
290 }
291 if (channel < manager->get_num_channels(Buffers::ProcessingToken::AUDIO_BACKEND)) {
292 manager->supply_buffer_to(buffer, Buffers::ProcessingToken::AUDIO_BACKEND, channel, mix);
293 }
294}
295
296void supply_buffer_to_channels(const std::shared_ptr<Buffers::AudioBuffer>& buffer,
297 const std::vector<uint32_t>& channels,
298 double mix)
299{
300 for (const auto& channel : channels) {
301 supply_buffer_to_channel(buffer, channel, mix);
302 }
303}
304
305void remove_supplied_buffer_from_channel(const std::shared_ptr<Buffers::AudioBuffer>& buffer,
306 const uint32_t channel)
307{
308 auto manager = get_buffer_manager();
309
310 if (channel < manager->get_num_channels(Buffers::ProcessingToken::AUDIO_BACKEND)) {
311 manager->remove_supplied_buffer(buffer, Buffers::ProcessingToken::AUDIO_BACKEND, channel);
312 }
313}
314
315void remove_supplied_buffer_from_channels(const std::shared_ptr<Buffers::AudioBuffer>& buffer,
316 const std::vector<uint32_t>& channels)
317{
318 for (const auto& channel : channels) {
320 }
321}
322
324 const std::shared_ptr<Buffers::AudioBuffer>& buffer,
325 uint32_t target_channel,
326 double seconds_to_fade,
327 const Buffers::ProcessingToken& token)
328{
329 get_buffer_manager()->route_buffer_to_channel(
330 buffer, target_channel, seconds_to_blocks(seconds_to_fade), token);
331}
332
334 const std::shared_ptr<Buffers::AudioBuffer>& buffer,
335 uint32_t target_channel,
336 uint32_t num_blocks,
337 const Buffers::ProcessingToken& token)
338{
339 get_buffer_manager()->route_buffer_to_channel(buffer, target_channel, num_blocks, token);
340}
341
342std::shared_ptr<Nodes::Node> operator>>(const std::shared_ptr<Nodes::Node>& lhs, const std::shared_ptr<Nodes::Node>& rhs)
343{
344 auto manager = get_node_graph_manager();
345
346 auto lhs_chain = std::dynamic_pointer_cast<Nodes::ChainNode>(lhs);
347 auto rhs_chain = std::dynamic_pointer_cast<Nodes::ChainNode>(rhs);
348
349 if (lhs_chain) {
350 if (rhs_chain) {
351 lhs_chain->append_chain(rhs_chain);
352 } else {
353 lhs_chain->append(rhs);
354 }
355 lhs_chain->initialize();
356 return lhs_chain;
357 }
358
359 std::shared_ptr<Nodes::ChainNode> chain;
360 if (rhs_chain) {
361 std::vector<std::shared_ptr<Nodes::Node>> nodes;
362 nodes.reserve(1 + rhs_chain->size());
363 nodes.push_back(lhs);
364 for (auto& node : rhs_chain->nodes()) {
365 nodes.push_back(node);
366 }
367 chain = std::make_shared<Nodes::ChainNode>(std::move(nodes), *manager);
368 } else {
369 chain = std::make_shared<Nodes::ChainNode>(lhs, rhs, *manager);
370 }
371
372 chain->initialize();
373 return chain;
374}
375
376std::shared_ptr<Nodes::Node> operator+(const std::shared_ptr<Nodes::Node>& lhs, const std::shared_ptr<Nodes::Node>& rhs)
377{
378 auto manager = get_node_graph_manager();
379 auto result = std::make_shared<Nodes::BinaryOpNode>(
380 lhs, rhs, [](double a, double b) { return a + b; }, *manager);
381 result->initialize();
382 return result;
383}
384
385std::shared_ptr<Nodes::Node> operator*(const std::shared_ptr<Nodes::Node>& lhs, const std::shared_ptr<Nodes::Node>& rhs)
386{
387 auto manager = get_node_graph_manager();
388 auto result = std::make_shared<Nodes::BinaryOpNode>(
389 lhs, rhs, [](double a, double b) { return a * b; }, *manager);
390 result->initialize();
391 return result;
392}
393
394}
#define MF_ERROR(comp, ctx,...)
Core::GlobalNetworkConfig network
Definition Config.cpp:37
Core engine lifecycle and configuration API.
size_t a
size_t b
Top-level aggregation buffer for computational data streams.
std::shared_ptr< Nodes::NodeGraphManager > get_node_graph_manager()
Gets the node graph manager.
Definition Engine.hpp:267
std::shared_ptr< Buffers::BufferManager > get_buffer_manager()
Gets the buffer manager.
Definition Engine.hpp:285
Container for top-level nodes in a processing channel with multi-modal support.
Definition RootNode.hpp:29
std::function< void(const std::shared_ptr< AudioBuffer > &)> AudioProcessingFunction
Audio processing function - receives correctly-typed AudioBuffer.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
std::function< void(const std::shared_ptr< VKBuffer > &)> GraphicsProcessingFunction
Graphics processing function - receives correctly-typed VKBuffer.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ API
MayaFlux/API Wrapper and convenience functions.
ProcessingToken
Enumerates the different processing domains for nodes.
@ AUDIO_RATE
Nodes that process at the audio sample rate.
std::shared_ptr< Buffers::BufferProcessor > attach_quick_process_graphics(Buffers::GraphicsProcessingFunction processor, const std::shared_ptr< Buffers::VKBuffer > &buffer)
Definition Graph.cpp:25
std::shared_ptr< Buffers::BufferProcessor > attach_quick_process_audio(Buffers::AudioProcessingFunction processor, const std::shared_ptr< Buffers::AudioBuffer > &buffer)
Definition Graph.cpp:20
void connect_node_to_buffer(const std::shared_ptr< Nodes::Node > &node, const std::shared_ptr< Buffers::AudioBuffer > &buffer, float mix, bool clear_before)
Connects a node to a specific buffer.
Definition Graph.cpp:183
std::shared_ptr< Nodes::Node > operator*(const std::shared_ptr< Nodes::Node > &lhs, const std::shared_ptr< Nodes::Node > &rhs)
Combines two nodes in parallel (multiplication)
Definition Graph.cpp:385
std::shared_ptr< Buffers::AudioBuffer > create_input_listener_buffer(uint32_t channel, bool add_to_output)
Creates a new AudioBuffer for input listening.
Definition Graph.cpp:259
void register_node(const std::shared_ptr< Nodes::Node > &node, const Nodes::ProcessingToken &token, uint32_t channel)
Definition Graph.cpp:123
std::shared_ptr< Buffers::BufferProcessingChain > create_processing_chain()
Creates a new processing chain for the default engine.
Definition Graph.cpp:167
void unregister_node(const std::shared_ptr< Nodes::Node > &node, const Nodes::ProcessingToken &token, uint32_t channel)
Removes a node from the root node of specified channels.
Definition Graph.cpp:84
void remove_processor(const std::shared_ptr< Buffers::BufferProcessor > &processor, const std::shared_ptr< Buffers::Buffer > &buffer)
Removes a processor from a specific buffer.
Definition Graph.cpp:152
void unregister_graphics_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer)
Unregisters a VKBuffer from the default engine's buffer manager.
Definition Graph.cpp:244
void add_processor(const std::shared_ptr< Buffers::BufferProcessor > &processor, const std::shared_ptr< Buffers::Buffer > &buffer, Buffers::ProcessingToken token)
Adds a processor to a specific buffer.
Definition Graph.cpp:137
void route_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const std::vector< uint32_t > &channels, uint32_t num_samples, const Nodes::ProcessingToken &token)
@breif Moves the node from its current channel(s) to the specified channel(s) with an optional fade t...
Definition Graph.cpp:202
std::shared_ptr< Nodes::NodeGraphManager > get_node_graph_manager()
Gets the node graph manager from the default engine.
Definition Graph.cpp:35
std::shared_ptr< Buffers::BufferProcessor > attach_quick_process(Buffers::AudioProcessingFunction processor, unsigned int channel_id)
Attaches a processing function to a specific channel.
Definition Graph.cpp:224
uint64_t seconds_to_samples(double seconds)
Converts a time duration in seconds to the equivalent number of audio samples.
Definition Chronie.cpp:271
std::shared_ptr< Nodes::Node > operator>>(const std::shared_ptr< Nodes::Node > &lhs, const std::shared_ptr< Nodes::Node > &rhs)
Connects two nodes in series (pipeline operator)
Definition Graph.cpp:342
Buffers::RootAudioBuffer & get_root_audio_buffer(uint32_t channel)
Gets the audio buffer for a specific channel.
Definition Graph.cpp:172
void route_node(const std::shared_ptr< Nodes::Node > &node, const std::vector< uint32_t > &channels, uint32_t num_samples, const Nodes::ProcessingToken &token)
@breif Moves the node from its current channel(s) to the specified channel(s) with an optional fade t...
Definition Graph.cpp:100
void register_node_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::ProcessingToken &token)
Registers a node network with the default engine's node graph manager.
Definition Graph.cpp:192
std::shared_ptr< Nodes::Node > operator+(const std::shared_ptr< Nodes::Node > &lhs, const std::shared_ptr< Nodes::Node > &rhs)
Combines two nodes in parallel (addition)
Definition Graph.cpp:376
void remove_supplied_buffer_from_channels(const std::shared_ptr< Buffers::AudioBuffer > &buffer, const std::vector< uint32_t > &channels)
Removes a supplied buffer from multiple channels.
Definition Graph.cpp:315
std::vector< std::shared_ptr< Buffers::AudioBuffer > > clone_buffer_to_channels(const std::shared_ptr< Buffers::AudioBuffer > &buffer, const std::vector< uint32_t > &channels)
Clones a buffer to multiple channels.
Definition Graph.cpp:271
void unregister_audio_buffer(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t channel)
Unregisters an AudioBuffer from the default engine's buffer manager.
Definition Graph.cpp:234
void supply_buffer_to_channels(const std::shared_ptr< Buffers::AudioBuffer > &buffer, const std::vector< uint32_t > &channels, double mix)
Supplies a buffer to multiple channels with mixing.
Definition Graph.cpp:296
void supply_buffer_to_channel(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t channel, double mix)
Supplies a buffer to a single channel with mixing.
Definition Graph.cpp:282
void route_buffer(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t target_channel, double seconds_to_fade, const Buffers::ProcessingToken &token)
Routes a buffer from its current channel to a target channel with fade.
Definition Graph.cpp:323
void register_audio_buffer(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t channel)
Registers an AudioBuffer with the default engine's buffer manager.
Definition Graph.cpp:229
uint64_t seconds_to_blocks(double seconds)
Converts a time duration in seconds to the equivalent number of processing blocks.
Definition Chronie.cpp:280
void detach_from_audio_input(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t channel)
Stops reading audio data from the default input source.
Definition Graph.cpp:254
void register_audio_node(const std::shared_ptr< Nodes::Node > &node, uint32_t channel)
Adds a node to the root node of a specific channel.
Definition Graph.cpp:40
void unregister_node_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const Nodes::ProcessingToken &token)
Unregisters a node network from the default engine's node graph manager.
Definition Graph.cpp:197
void unregister_audio_node(const std::shared_ptr< Nodes::Node > &node, uint32_t channel)
Removes a node from the root node of a specific channel.
Definition Graph.cpp:61
std::shared_ptr< Buffers::BufferManager > get_buffer_manager()
Gets the buffer manager from the default engine.
Definition Graph.cpp:132
void register_graphics_buffer(const std::shared_ptr< Buffers::VKBuffer > &buffer, Buffers::ProcessingToken token)
Registers a VKBuffer with the default engine's buffer manager.
Definition Graph.cpp:239
Core::Engine & get_context()
Gets the default engine instance.
Definition Core.cpp:68
Nodes::RootNode & get_audio_channel_root(uint32_t channel)
Gets the root node for a specific channel.
Definition Graph.cpp:118
std::vector< double > mix(const std::vector< std::vector< double > > &streams)
Mix multiple data streams with equal weighting.
Definition Yantra.cpp:945
void read_from_audio_input(const std::shared_ptr< Buffers::AudioBuffer > &buffer, uint32_t channel)
Reads audio data from the default input source into a buffer.
Definition Graph.cpp:249
void connect_node_to_channel(const std::shared_ptr< Nodes::Node > &node, uint32_t channel_index, float mix, bool clear_before)
Connects a node to a specific output channel.
Definition Graph.cpp:177
void remove_supplied_buffer_from_channel(const std::shared_ptr< Buffers::AudioBuffer > &buffer, const uint32_t channel)
Removes a supplied buffer from multiple channels.
Definition Graph.cpp:305
Main namespace for the Maya Flux audio engine.
Definition Runtime.cpp:12