MayaFlux 0.5.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 uint64_t default_sample_rate,
21 uint32_t default_buffer_size,
22 uint32_t default_frame_rate,
23 ProcessingToken default_audio_token,
24 ProcessingToken default_graphics_token)
25 : m_unit_manager(std::make_unique<TokenUnitManager>(default_audio_token, default_graphics_token, default_buffer_size))
26 , m_access_control(std::make_unique<BufferAccessControl>(*m_unit_manager))
27 , m_processor_control(std::make_unique<BufferProcessingControl>(*m_unit_manager, *m_access_control))
28 , m_input_control(std::make_unique<BufferInputControl>())
29 , m_supply_mixing(std::make_unique<BufferSupplyMixing>(*m_unit_manager, *m_access_control))
30 , m_global_processing_chain(std::make_shared<BufferProcessingChain>())
31{
32 s_registered_sample_rate = default_sample_rate;
33 s_preferred_buffer_size = default_buffer_size;
34 s_preferred_frame_rate = default_frame_rate;
35 validate_num_channels(default_audio_token, default_out_channels, default_buffer_size);
36
37 if (default_in_channels) {
38 m_input_control->setup_audio_input_buffers(default_in_channels, default_buffer_size);
39 }
40
41 auto& a_unit = m_unit_manager->get_or_create_audio_unit(default_audio_token);
42 if (a_unit.channel_count > 0) {
43 auto limiter = std::make_shared<FinalLimiterProcessor>();
44 m_processor_control->set_audio_final_processor(limiter, default_audio_token);
45 }
46
47 auto& g_unit = m_unit_manager->get_or_create_graphics_unit(default_graphics_token);
48 auto present_processor = std::make_shared<PresentProcessor>();
49 m_processor_control->set_graphics_final_processor(present_processor, default_graphics_token);
50}
51
53
54// ============================================================================
55// Processing and Token Management
56// ============================================================================
57
58void BufferManager::process_token(ProcessingToken token, uint32_t processing_units)
59{
61 process_audio_token_default(token, processing_units);
62 }
63
65 process_graphics_token_default(token, processing_units);
66 }
67}
68
70{
71 for (const auto& token : m_unit_manager->get_active_audio_tokens()) {
72 process_token(token, m_unit_manager->get_audio_buffer_size(token));
73 }
74}
75
77 ProcessingToken token,
78 uint32_t channel,
79 uint32_t /*processing_units*/,
80 const std::vector<double>& node_output_data)
81{
82 if (!m_unit_manager->has_audio_unit(token)) {
83 return;
84 }
85
86 auto& unit = m_unit_manager->get_audio_unit_mutable(token);
87 if (channel >= unit.channel_count) {
88 return;
89 }
90
91 auto root_buffer = unit.get_buffer(channel);
92
93 if (!node_output_data.empty()) {
94 root_buffer->set_node_output(node_output_data);
95 }
96
97 for (auto& child : root_buffer->get_child_buffers()) {
98 if (child->needs_default_processing()) {
99 child->process_default();
100 }
101
102 if (auto processing_chain = child->get_processing_chain()) {
103 if (child->has_data_for_cycle()) {
104 processing_chain->process_complete(child);
105 }
106 }
107 unit.get_chain(channel)->process_complete(child);
108 }
109
110 root_buffer->process_default();
111
112 unit.get_chain(channel)->process(root_buffer);
113
114 m_global_processing_chain->process(root_buffer);
115
116 if (auto chain = root_buffer->get_processing_chain()) {
117 chain->process_final(root_buffer);
118 }
119}
120
121std::vector<ProcessingToken> BufferManager::get_active_tokens() const
122{
123 std::vector<ProcessingToken> active_tokens;
124 for (const auto& token : m_unit_manager->get_active_audio_tokens()) {
125 active_tokens.push_back(token);
126 }
127 for (const auto& token : m_unit_manager->get_active_graphics_tokens()) {
128 active_tokens.push_back(token);
129 }
130 return active_tokens;
131}
132
134{
135 auto& unit = m_unit_manager->get_or_create_audio_unit(token);
136 unit.custom_processor = std::move(processor);
137}
138
140{
141 return m_unit_manager->get_default_audio_token();
142}
143
144// ============================================================================
145// Buffer Access (Token-Generic)
146// ============================================================================
147
148std::shared_ptr<RootAudioBuffer> BufferManager::get_root_audio_buffer(ProcessingToken token, uint32_t channel)
149{
150 return m_access_control->get_root_audio_buffer(token, channel);
151}
152
153std::shared_ptr<RootGraphicsBuffer> BufferManager::get_root_graphics_buffer(ProcessingToken token)
154{
155 return m_access_control->get_root_graphics_buffer(token);
156}
157
158std::vector<double>& BufferManager::get_buffer_data(ProcessingToken token, uint32_t channel)
159{
160 return m_access_control->get_audio_buffer_data(token, channel);
161}
162
163const std::vector<double>& BufferManager::get_buffer_data(ProcessingToken token, uint32_t channel) const
164{
165 return m_access_control->get_audio_buffer_data(token, channel);
166}
167
169{
170 return m_access_control->get_num_audio_out_channels(token);
171}
172
174{
175 return m_access_control->get_audio_buffer_size(token);
176}
177
178void BufferManager::resize_buffers(ProcessingToken token, uint32_t buffer_size)
179{
181 return;
182 }
183 m_access_control->resize_audio_buffers(token, buffer_size);
184}
185
186void BufferManager::ensure_channels(ProcessingToken token, uint32_t channel_count)
187{
188 m_access_control->ensure_audio_channels(token, channel_count);
189}
190
191std::shared_ptr<BufferProcessingChain> BufferManager::get_processing_chain(ProcessingToken token, uint32_t channel)
192{
193 return m_access_control->get_audio_processing_chain(token, channel);
194}
195
196std::shared_ptr<BufferProcessingChain> BufferManager::get_global_processing_chain()
197{
199}
200
201// ============================================================================
202// Buffer Management (Token-Generic via Dynamic Dispatch)
203// ============================================================================
204
206 const std::shared_ptr<Buffer>& buffer,
207 ProcessingToken token,
208 uint32_t channel)
209{
210 m_access_control->add_buffer(buffer, token, channel);
211}
212
214 const std::shared_ptr<Buffer>& buffer,
215 ProcessingToken token,
216 uint32_t channel)
217{
218 m_access_control->remove_buffer(buffer, token, channel);
219}
220
221const std::vector<std::shared_ptr<AudioBuffer>>& BufferManager::get_buffers(ProcessingToken token, uint32_t channel) const
222{
223 return m_access_control->get_audio_buffers(token, channel);
224}
225
226const std::vector<std::shared_ptr<VKBuffer>>& BufferManager::get_graphics_buffers(ProcessingToken token) const
227{
228 return m_access_control->get_graphics_buffers(token);
229}
230
231std::vector<std::shared_ptr<VKBuffer>> BufferManager::get_buffers_by_usage(
232 VKBuffer::Usage usage,
233 ProcessingToken token) const
234{
235 return m_access_control->get_graphics_buffers_by_usage(usage, token);
236}
237
238// ============================================================================
239// Processor Management (Token-Generic)
240// ============================================================================
241
243 const std::shared_ptr<BufferProcessor>& processor,
244 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
245{
246 m_processor_control->add_processor(processor, buffer, token);
247}
248
250 const std::shared_ptr<BufferProcessor>& processor,
251 ProcessingToken token,
252 uint32_t channel)
253{
254 m_processor_control->add_processor(processor, token, channel);
255}
256
258 const std::shared_ptr<BufferProcessor>& processor,
259 ProcessingToken token)
260{
261 m_processor_control->add_processor(processor, token);
262}
263
265 const std::shared_ptr<BufferProcessor>& processor,
266 const std::shared_ptr<Buffer>& buffer)
267{
268 m_processor_control->remove_processor(processor, buffer);
269}
270
272 const std::shared_ptr<BufferProcessor>& processor,
273 ProcessingToken token,
274 uint32_t channel)
275{
276 m_processor_control->remove_processor_from_token(processor, token, channel);
277}
278
280 const std::shared_ptr<BufferProcessor>& processor,
281 ProcessingToken token)
282{
283 m_processor_control->remove_processor_from_token(processor, token, 0);
284}
285
287 const std::shared_ptr<BufferProcessor>& processor,
288 ProcessingToken token)
289{
290 m_processor_control->set_final_processor(processor, token);
291}
292
293// ============================================================================
294// Quick Processing (Audio-Specific)
295// ============================================================================
296
297std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
298 AudioProcessingFunction processor,
299 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
300{
301 return m_processor_control->attach_quick_process(std::move(processor), buffer, token);
302}
303
304std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
306 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
307{
308 return m_processor_control->attach_quick_process(std::move(processor), buffer, token);
309}
310
311std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
312 AudioProcessingFunction processor,
313 ProcessingToken token,
314 uint32_t channel)
315{
316 return m_processor_control->attach_quick_process(std::move(processor), token, channel);
317}
318
319std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
320 AudioProcessingFunction processor,
321 ProcessingToken token)
322{
323 return m_processor_control->attach_quick_process(std::move(processor), token);
324}
325
326std::shared_ptr<BufferProcessor> BufferManager::attach_quick_process(
328 ProcessingToken token)
329{
330 return m_processor_control->attach_quick_process(std::move(processor), token);
331}
332
333// ============================================================================
334// Node Connection (Audio-Specific)
335// ============================================================================
336
338 const std::shared_ptr<Nodes::Node>& node,
339 ProcessingToken token,
340 uint32_t channel,
341 float mix,
342 bool clear_before)
343{
344 m_processor_control->connect_node_to_audio_channel(node, token, channel, mix, clear_before);
345}
346
348 const std::shared_ptr<Nodes::Node>& node,
349 const std::shared_ptr<AudioBuffer>& buffer,
350 float mix,
351 bool clear_before)
352{
353 m_processor_control->connect_node_to_audio_buffer(node, buffer, mix, clear_before);
354}
355
357 const std::shared_ptr<AudioBuffer>& buffer,
358 uint32_t target_channel,
359 uint32_t fade_cycles,
360 ProcessingToken token)
361{
362 m_supply_mixing->route_buffer_to_channel(buffer, target_channel, fade_cycles, token);
363}
364
366{
367 m_supply_mixing->update_routing_states_for_cycle(token);
368}
369
371{
372 m_supply_mixing->cleanup_completed_routing(token);
373}
374
375// ============================================================================
376// Data I/O (Audio-Specific)
377// ============================================================================
378
380 const double* interleaved_data,
381 uint32_t num_frames,
382 ProcessingToken token,
383 uint32_t num_channels)
384{
385 m_supply_mixing->fill_audio_from_interleaved(interleaved_data, num_frames, token, num_channels);
386}
387
389 double* interleaved_data,
390 uint32_t num_frames,
391 ProcessingToken token,
392 uint32_t num_channels) const
393{
394 m_supply_mixing->fill_audio_interleaved(interleaved_data, num_frames, token, num_channels);
395}
396
397std::vector<std::shared_ptr<AudioBuffer>> BufferManager::clone_buffer_for_channels(
398 const std::shared_ptr<AudioBuffer>& buffer,
399 const std::vector<uint32_t>& channels,
400 ProcessingToken token)
401{
402 return m_supply_mixing->clone_audio_buffer_for_channels(buffer, channels, token);
403}
404
405// ============================================================================
406// Input Handling (Audio-Specific)
407// ============================================================================
408
409void BufferManager::process_input(double* input_data, uint32_t num_channels, uint32_t num_frames)
410{
411 m_input_control->process_audio_input(input_data, num_channels, num_frames);
412}
413
414void BufferManager::register_input_listener(const std::shared_ptr<AudioBuffer>& buffer, uint32_t channel)
415{
416 m_input_control->register_audio_input_listener(buffer, channel);
417}
418
419void BufferManager::unregister_input_listener(const std::shared_ptr<AudioBuffer>& buffer, uint32_t channel)
420{
421 m_input_control->unregister_audio_input_listener(buffer, channel);
422}
423
425{
426 return m_input_control->get_audio_input_channel_count();
427}
428
429std::shared_ptr<Buffers::InputAudioBuffer> BufferManager::get_input_buffer(uint32_t channel) const
430{
431 return m_input_control->get_input_buffer(channel);
432}
433
434// ============================================================================
435// Buffer Supply/Mixing (Audio-Specific)
436// ============================================================================
437
439 const std::shared_ptr<AudioBuffer>& buffer,
440 ProcessingToken token,
441 uint32_t channel,
442 double mix, bool force)
443{
444 return m_supply_mixing->supply_audio_buffer_to(buffer, token, channel, mix, force);
445}
446
448 const std::shared_ptr<AudioBuffer>& buffer,
449 ProcessingToken token,
450 uint32_t channel)
451{
452 return m_supply_mixing->remove_supplied_audio_buffer(buffer, token, channel);
453}
454
455// ============================================================================
456// Utility
457// ============================================================================
458
460{
461 m_access_control->initialize_buffer_service();
462}
463
465{
466 m_access_control->terminate_active_buffers();
467}
468
469// ============================================================================
470// Private
471// ============================================================================
472
474{
475 if (!m_unit_manager->has_audio_unit(token)) {
476 return;
477 }
478
479 auto& unit = m_unit_manager->get_audio_unit_mutable(token);
480
481 if (unit.custom_processor) {
482 unit.custom_processor(unit.root_buffers, processing_units);
483 return;
484 }
485
486 for (uint32_t channel = 0; channel < unit.channel_count; ++channel) {
487 process_channel(token, channel, processing_units);
488 }
489}
490
492{
493 if (!m_unit_manager->has_graphics_unit(token)) {
494 return;
495 }
496
497 auto& unit = m_unit_manager->get_graphics_unit_mutable(token);
498
499 if (unit.custom_processor) {
500 unit.custom_processor(unit.root_buffer, processing_units);
501 return;
502 }
503
504 auto root_buffer = m_access_control->get_root_graphics_buffer(token);
505
506 // if (!node_output_data.empty()) {
507 // root_buffer->set_node_output(node_output_data);
508 // }
509
510 root_buffer->process_default();
511
512 unit.get_chain()->process(root_buffer);
513
514 m_global_processing_chain->process(root_buffer);
515
516 if (auto chain = root_buffer->get_processing_chain()) {
517 chain->process_final(root_buffer);
518 }
519}
520
521} // namespace MayaFlux::Buffers
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)
BufferManager(uint32_t default_out_channels=2, uint32_t default_in_channels=0, uint64_t default_sample_rate=48000, uint32_t default_buffer_size=512, uint32_t default_frame_rate=60, ProcessingToken default_audio_token=ProcessingToken::AUDIO_BACKEND, ProcessingToken default_graphics_token=ProcessingToken::GRAPHICS_BACKEND)
Creates a new multimodal buffer manager.
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 route_buffer_to_channel(const std::shared_ptr< AudioBuffer > &buffer, uint32_t target_channel, uint32_t fade_cycles, ProcessingToken token)
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::shared_ptr< Buffers::InputAudioBuffer > get_input_buffer(uint32_t channel) const
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
uint32_t get_num_channels(ProcessingToken token) const
Gets the number of channels for a token (audio-specific)
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.
bool supply_buffer_to(const std::shared_ptr< AudioBuffer > &buffer, ProcessingToken token, uint32_t channel, double mix=1.0, bool force=false)
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)
std::shared_ptr< BufferProcessor > attach_quick_process(AudioProcessingFunction processor, const std::shared_ptr< Buffer > &buffer, ProcessingToken token=ProcessingToken::AUDIO_BACKEND)
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 cleanup_completed_routing(ProcessingToken token)
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.
void update_routing_states(ProcessingToken token)
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.
std::function< void(const std::shared_ptr< AudioBuffer > &)> AudioProcessingFunction
Audio processing function - receives correctly-typed AudioBuffer.
uint32_t s_preferred_buffer_size
Global default buffer size.
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::function< void(std::vector< std::shared_ptr< RootAudioBuffer > > &, uint32_t)> RootAudioProcessingFunction
std::function< void(const std::shared_ptr< VKBuffer > &)> GraphicsProcessingFunction
Graphics processing function - receives correctly-typed VKBuffer.
uint32_t s_preferred_frame_rate
Global default frame rate.
uint64_t s_registered_sample_rate
Global default sample rate.
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
std::vector< double > mix(const std::vector< std::vector< double > > &streams)
Mix multiple data streams with equal weighting.
Definition Yantra.cpp:945