MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BufferManager.cpp
Go to the documentation of this file.
1#include "BufferManager.hpp"
2
4
9
14
15namespace MayaFlux::Buffers {
16
18 uint32_t default_out_channels,
19 uint32_t default_in_channels,
20 uint32_t default_buffer_size,
21 ProcessingToken default_audio_token,
22 ProcessingToken default_graphics_token)
23 : m_unit_manager(std::make_unique<TokenUnitManager>(default_audio_token, default_graphics_token))
24 , m_access_control(std::make_unique<BufferAccessControl>(*m_unit_manager))
25 , m_processor_control(std::make_unique<BufferProcessingControl>(*m_unit_manager, *m_access_control))
26 , m_input_control(std::make_unique<BufferInputControl>())
27 , m_supply_mixing(std::make_unique<BufferSupplyMixing>(*m_unit_manager, *m_access_control))
28 , m_global_processing_chain(std::make_shared<BufferProcessingChain>())
29{
30 validate_num_channels(default_audio_token, default_out_channels, default_buffer_size);
31
32 if (default_in_channels) {
33 m_input_control->setup_audio_input_buffers(default_in_channels, default_buffer_size);
34 }
35
36 auto& a_unit = m_unit_manager->get_or_create_audio_unit(default_audio_token);
37 if (a_unit.channel_count > 0) {
38 auto limiter = std::make_shared<FinalLimiterProcessor>();
39 m_processor_control->set_audio_final_processor(limiter, default_audio_token);
40 }
41
42 auto& g_unit = m_unit_manager->get_or_create_graphics_unit(default_graphics_token);
43 auto present_processor = std::make_shared<PresentProcessor>();
44 m_processor_control->set_graphics_final_processor(present_processor, default_graphics_token);
45}
46
48
49// ============================================================================
50// Processing and Token Management
51// ============================================================================
52
63
65{
66 for (const auto& token : m_unit_manager->get_active_audio_tokens()) {
67 process_token(token, m_unit_manager->get_audio_buffer_size(token));
68 }
69}
70
73 uint32_t channel,
74 uint32_t /*processing_units*/,
75 const std::vector<double>& node_output_data)
76{
77 if (!m_unit_manager->has_audio_unit(token)) {
78 return;
79 }
80
81 auto& unit = m_unit_manager->get_audio_unit_mutable(token);
82 if (channel >= unit.channel_count) {
83 return;
84 }
85
86 auto root_buffer = unit.get_buffer(channel);
87
88 if (!node_output_data.empty()) {
89 root_buffer->set_node_output(node_output_data);
90 }
91
92 for (auto& child : root_buffer->get_child_buffers()) {
93 if (child->needs_default_processing()) {
94 child->process_default();
95 }
96
97 if (auto processing_chain = child->get_processing_chain()) {
98 if (child->has_data_for_cycle()) {
99 processing_chain->process(child);
100 }
101 }
102 }
103
104 root_buffer->process_default();
105
106 unit.get_chain(channel)->process(root_buffer);
107
108 m_global_processing_chain->process(root_buffer);
109
110 if (auto chain = root_buffer->get_processing_chain()) {
111 chain->process_final(root_buffer);
112 }
113}
114
115std::vector<ProcessingToken> BufferManager::get_active_tokens() const
116{
117 std::vector<ProcessingToken> active_tokens;
118 for (const auto& token : m_unit_manager->get_active_audio_tokens()) {
119 active_tokens.push_back(token);
120 }
121 for (const auto& token : m_unit_manager->get_active_graphics_tokens()) {
122 active_tokens.push_back(token);
123 }
124 return active_tokens;
125}
126
128{
129 auto& unit = m_unit_manager->get_or_create_audio_unit(token);
130 unit.custom_processor = std::move(processor);
131}
132
134{
135 return m_unit_manager->get_default_audio_token();
136}
137
138// ============================================================================
139// Buffer Access (Token-Generic)
140// ============================================================================
141
142std::shared_ptr<RootAudioBuffer> BufferManager::get_root_audio_buffer(ProcessingToken token, uint32_t channel)
143{
144 return m_access_control->get_root_audio_buffer(token, channel);
145}
146
148{
149 return m_access_control->get_root_graphics_buffer(token);
150}
151
152std::vector<double>& BufferManager::get_buffer_data(ProcessingToken token, uint32_t channel)
153{
154 return m_access_control->get_audio_buffer_data(token, channel);
155}
156
157const std::vector<double>& BufferManager::get_buffer_data(ProcessingToken token, uint32_t channel) const
158{
159 return m_access_control->get_audio_buffer_data(token, channel);
160}
161
163{
164 return m_access_control->get_num_audio_out_channels(token);
165}
166
168{
169 return m_access_control->get_audio_buffer_size(token);
170}
171
173{
175 return;
176 }
177 m_access_control->resize_audio_buffers(token, buffer_size);
178}
179
181{
182 m_access_control->ensure_audio_channels(token, channel_count);
183}
184
185std::shared_ptr<BufferProcessingChain> BufferManager::get_processing_chain(ProcessingToken token, uint32_t channel)
186{
187 return m_access_control->get_audio_processing_chain(token, channel);
188}
189
190std::shared_ptr<BufferProcessingChain> BufferManager::get_global_processing_chain()
191{
193}
194
195// ============================================================================
196// Buffer Management (Token-Generic via Dynamic Dispatch)
197// ============================================================================
198
200 const std::shared_ptr<Buffer>& buffer,
202 uint32_t channel)
203{
204 m_access_control->add_buffer(buffer, token, channel);
205}
206
208 const std::shared_ptr<Buffer>& buffer,
210 uint32_t channel)
211{
212 m_access_control->remove_buffer(buffer, token, channel);
213}
214
215const std::vector<std::shared_ptr<AudioBuffer>>& BufferManager::get_buffers(ProcessingToken token, uint32_t channel) const
216{
217 return m_access_control->get_audio_buffers(token, channel);
218}
219
220const std::vector<std::shared_ptr<VKBuffer>>& BufferManager::get_graphics_buffers(ProcessingToken token) const
221{
222 return m_access_control->get_graphics_buffers(token);
223}
224
225std::vector<std::shared_ptr<VKBuffer>> BufferManager::get_buffers_by_usage(
226 VKBuffer::Usage usage,
228{
229 return m_access_control->get_graphics_buffers_by_usage(usage, token);
230}
231
232// ============================================================================
233// Processor Management (Token-Generic)
234// ============================================================================
235
237 const std::shared_ptr<BufferProcessor>& processor,
238 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
239{
240 m_processor_control->add_processor(processor, buffer, token);
241}
242
244 const std::shared_ptr<BufferProcessor>& processor,
246 uint32_t channel)
247{
248 m_processor_control->add_processor(processor, token, channel);
249}
250
252 const std::shared_ptr<BufferProcessor>& processor,
254{
255 m_processor_control->add_processor(processor, token);
256}
257
259 const std::shared_ptr<BufferProcessor>& processor,
260 const std::shared_ptr<Buffer>& buffer)
261{
262 m_processor_control->remove_processor(processor, buffer);
263}
264
266 const std::shared_ptr<BufferProcessor>& processor,
268 uint32_t channel)
269{
270 m_processor_control->remove_processor_from_token(processor, token, channel);
271}
272
274 const std::shared_ptr<BufferProcessor>& processor,
276{
277 m_processor_control->remove_processor_from_token(processor, token, 0);
278}
279
281 const std::shared_ptr<BufferProcessor>& processor,
283{
284 m_processor_control->set_final_processor(processor, token);
285}
286
287// ============================================================================
288// Quick Processing (Audio-Specific)
289// ============================================================================
290
291std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
292 BufferProcessingFunction processor,
293 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
294{
295 return m_processor_control->attach_quick_process(std::move(processor), buffer, token);
296}
297
298std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
299 BufferProcessingFunction processor,
301 uint32_t channel)
302{
303 return m_processor_control->attach_quick_process(std::move(processor), token, channel);
304}
305
306std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
307 BufferProcessingFunction processor,
309{
310 return m_processor_control->attach_quick_process(std::move(processor), token);
311}
312
313// ============================================================================
314// Node Connection (Audio-Specific)
315// ============================================================================
316
318 const std::shared_ptr<Nodes::Node>& node,
320 uint32_t channel,
321 float mix,
322 bool clear_before)
323{
324 m_processor_control->connect_node_to_audio_channel(node, token, channel, mix, clear_before);
325}
326
328 const std::shared_ptr<Nodes::Node>& node,
329 const std::shared_ptr<AudioBuffer>& buffer,
330 float mix,
331 bool clear_before)
332{
333 m_processor_control->connect_node_to_audio_buffer(node, buffer, mix, clear_before);
334}
335
336// ============================================================================
337// Data I/O (Audio-Specific)
338// ============================================================================
339
341 const double* interleaved_data,
342 uint32_t num_frames,
344 uint32_t num_channels)
345{
346 m_supply_mixing->fill_audio_from_interleaved(interleaved_data, num_frames, token, num_channels);
347}
348
350 double* interleaved_data,
351 uint32_t num_frames,
353 uint32_t num_channels) const
354{
355 m_supply_mixing->fill_audio_interleaved(interleaved_data, num_frames, token, num_channels);
356}
357
358std::vector<std::shared_ptr<AudioBuffer>> BufferManager::clone_buffer_for_channels(
359 const std::shared_ptr<AudioBuffer>& buffer,
360 const std::vector<uint32_t>& channels,
362{
363 return m_supply_mixing->clone_audio_buffer_for_channels(buffer, channels, token);
364}
365
366// ============================================================================
367// Input Handling (Audio-Specific)
368// ============================================================================
369
370void BufferManager::process_input(double* input_data, uint32_t num_channels, uint32_t num_frames)
371{
372 m_input_control->process_audio_input(input_data, num_channels, num_frames);
373}
374
375void BufferManager::register_input_listener(const std::shared_ptr<AudioBuffer>& buffer, uint32_t channel)
376{
377 m_input_control->register_audio_input_listener(buffer, channel);
378}
379
380void BufferManager::unregister_input_listener(const std::shared_ptr<AudioBuffer>& buffer, uint32_t channel)
381{
382 m_input_control->unregister_audio_input_listener(buffer, channel);
383}
384
385// ============================================================================
386// Buffer Supply/Mixing (Audio-Specific)
387// ============================================================================
388
390 const std::shared_ptr<AudioBuffer>& buffer,
392 uint32_t channel,
393 double mix)
394{
395 return m_supply_mixing->supply_audio_buffer_to(buffer, token, channel, mix);
396}
397
399 const std::shared_ptr<AudioBuffer>& buffer,
401 uint32_t channel)
402{
403 return m_supply_mixing->remove_supplied_audio_buffer(buffer, token, channel);
404}
405
406// ============================================================================
407// Utility
408// ============================================================================
409
411{
412 m_access_control->initialize_buffer_service();
413}
414
416{
417 m_access_control->terminate_active_buffers();
418}
419
420// ============================================================================
421// Private
422// ============================================================================
423
425{
426 if (!m_unit_manager->has_audio_unit(token)) {
427 return;
428 }
429
430 auto& unit = m_unit_manager->get_audio_unit_mutable(token);
431
432 if (unit.custom_processor) {
433 unit.custom_processor(unit.root_buffers, processing_units);
434 return;
435 }
436
437 for (uint32_t channel = 0; channel < unit.channel_count; ++channel) {
438 process_channel(token, channel, processing_units);
439 }
440}
441
443{
444 if (!m_unit_manager->has_graphics_unit(token)) {
445 return;
446 }
447
448 auto& unit = m_unit_manager->get_graphics_unit_mutable(token);
449
450 if (unit.custom_processor) {
451 unit.custom_processor(unit.root_buffer, processing_units);
452 return;
453 }
454
455 auto root_buffer = m_access_control->get_root_graphics_buffer(token);
456
457 // if (!node_output_data.empty()) {
458 // root_buffer->set_node_output(node_output_data);
459 // }
460
461 root_buffer->process_default();
462
463 unit.get_chain()->process(root_buffer);
464
465 m_global_processing_chain->process(root_buffer);
466
467 if (auto chain = root_buffer->get_processing_chain()) {
468 chain->process_final(root_buffer);
469 }
470}
471
472} // namespace MayaFlux::Buffers
static MayaFlux::Nodes::ProcessingToken token
Definition Timers.cpp:8
Token-aware buffer and unit access patterns.
Audio input buffer management and listener coordination.
void ensure_channels(ProcessingToken token, uint32_t channel_count)
Ensures minimum number of channels exist for an audio token.
std::vector< double > & get_buffer_data(ProcessingToken token, uint32_t channel)
Gets data from a specific token and channel (audio-specific)
void remove_processor(const std::shared_ptr< BufferProcessor > &processor, const std::shared_ptr< Buffer > &buffer)
Removes a processor from a buffer.
std::shared_ptr< RootAudioBuffer > get_root_audio_buffer(ProcessingToken token, uint32_t channel=0)
Gets a root buffer for a specific token and channel (audio-specific due to channels)
std::vector< std::shared_ptr< VKBuffer > > get_buffers_by_usage(VKBuffer::Usage usage, ProcessingToken token) const
Gets graphics buffers filtered by usage.
std::shared_ptr< BufferProcessingChain > m_global_processing_chain
Global processing chain applied to all tokens.
const std::vector< std::shared_ptr< AudioBuffer > > & get_buffers(ProcessingToken token, uint32_t channel) const
Gets buffers for a token (audio-specific due to channels)
void set_final_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Sets a final processor for a token (audio-specific)
void process_audio_token_default(ProcessingToken token, uint32_t processing_units)
void terminate_active_buffers()
Terminates all active buffers, clearing their data.
void add_processor(const std::shared_ptr< BufferProcessor > &processor, const std::shared_ptr< Buffer > &buffer, ProcessingToken token=ProcessingToken::AUDIO_BACKEND)
Adds a processor to a buffer.
uint32_t get_buffer_size(ProcessingToken token) const
Gets the buffer size for a token.
void remove_processor_from_token(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Removes a processor from all channels in a token (audio-specific)
void register_input_listener(const std::shared_ptr< AudioBuffer > &buffer, uint32_t channel)
void process_graphics_token_default(ProcessingToken token, uint32_t processing_units)
std::unique_ptr< TokenUnitManager > m_unit_manager
Token/unit storage and lifecycle.
void fill_interleaved(double *interleaved_data, uint32_t num_frames, ProcessingToken token, uint32_t num_channels) const
BufferManager(uint32_t default_out_channels=2, uint32_t default_in_channels=0, uint32_t default_buffer_size=512, ProcessingToken default_audio_token=ProcessingToken::AUDIO_BACKEND, ProcessingToken default_graphics_token=ProcessingToken::GRAPHICS_BACKEND)
Creates a new multimodal buffer manager.
std::shared_ptr< BufferProcessor > attach_quick_process(BufferProcessingFunction processor, const std::shared_ptr< Buffer > &buffer, ProcessingToken token=ProcessingToken::AUDIO_BACKEND)
uint32_t get_num_channels(ProcessingToken token) const
Gets the number of channels for a token (audio-specific)
bool supply_buffer_to(const std::shared_ptr< AudioBuffer > &buffer, ProcessingToken token, uint32_t channel, double mix=1.0)
std::vector< std::shared_ptr< AudioBuffer > > clone_buffer_for_channels(const std::shared_ptr< AudioBuffer > &buffer, const std::vector< uint32_t > &channels, ProcessingToken token)
std::shared_ptr< RootGraphicsBuffer > get_root_graphics_buffer(ProcessingToken token)
Gets a root graphics buffer for a specific token.
std::unique_ptr< BufferInputControl > m_input_control
Audio input management.
void connect_node_to_buffer(const std::shared_ptr< Nodes::Node > &node, const std::shared_ptr< AudioBuffer > &buffer, float mix=0.5F, bool clear_before=true)
void process_input(double *input_data, uint32_t num_channels, uint32_t num_frames)
const std::vector< std::shared_ptr< VKBuffer > > & get_graphics_buffers(ProcessingToken token) const
Gets graphics buffers for a token.
std::shared_ptr< BufferProcessingChain > get_global_processing_chain()
Gets the global processing chain (applied to all tokens)
void process_channel(ProcessingToken token, uint32_t channel, uint32_t processing_units, const std::vector< double > &node_output_data={})
Processes a specific channel within a token domain.
void resize_buffers(ProcessingToken token, uint32_t buffer_size)
Resizes buffers for a token.
std::shared_ptr< BufferProcessingChain > get_processing_chain(ProcessingToken token, uint32_t channel)
Gets the processing chain for a token and channel (audio-specific)
std::unique_ptr< BufferProcessingControl > m_processor_control
Processor attachment/removal operations.
void fill_from_interleaved(const double *interleaved_data, uint32_t num_frames, ProcessingToken token, uint32_t num_channels)
void remove_processor_from_channel(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token, uint32_t channel)
Removes a processor from a token and channel (audio-specific)
void remove_buffer(const std::shared_ptr< Buffer > &buffer, ProcessingToken token, uint32_t channel=0)
Removes a buffer from a token.
void validate_num_channels(ProcessingToken token, uint32_t num_channels, uint32_t buffer_size)
Validates the number of channels and resizes buffers if necessary (audio-specific)
ProcessingToken get_default_audio_token() const
Gets the default processing token used by the manager.
void connect_node_to_channel(const std::shared_ptr< Nodes::Node > &node, ProcessingToken token, uint32_t channel, float mix=0.5F, bool clear_before=false)
void process_token(ProcessingToken token, uint32_t processing_units)
Processes all buffers for a specific token.
void unregister_input_listener(const std::shared_ptr< AudioBuffer > &buffer, uint32_t channel)
bool remove_supplied_buffer(const std::shared_ptr< AudioBuffer > &buffer, ProcessingToken token, uint32_t channel)
void register_audio_token_processor(ProcessingToken token, RootAudioProcessingFunction processor)
Registers a custom processor for an audio token domain.
std::unique_ptr< BufferSupplyMixing > m_supply_mixing
Buffer supply and mixing operations.
std::unique_ptr< BufferAccessControl > m_access_control
Buffer and unit access operations.
void add_buffer(const std::shared_ptr< Buffer > &buffer, ProcessingToken token, uint32_t channel=0)
Adds a buffer to a token and channel.
std::vector< ProcessingToken > get_active_tokens() const
Gets all currently active processing tokens.
void process_all_tokens()
Processes all active tokens with their configured processing units.
Advanced pipeline manager for multi-stage buffer transformations with backend optimization.
Processor attachment, removal, and processing chain management.
External buffer supply, mixing, and interleaved data I/O.
Token-scoped unit storage and lifecycle management.
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.
@ AUDIO_PARALLEL
High-performance audio processing with GPU acceleration.
std::variant< AudioProcessingFunction, GraphicsProcessingFunction > BufferProcessingFunction
std::function< void(std::vector< std::shared_ptr< RootAudioBuffer > > &, uint32_t)> RootAudioProcessingFunction
std::vector< double > mix(const std::vector< std::vector< double > > &streams)
Mix multiple data streams with equal weighting.
Definition Yantra.cpp:1019