MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BufferProcessingControl.cpp
Go to the documentation of this file.
2
5
12
14
15namespace MayaFlux::Buffers {
16
18public:
20 : m_function(std::move(function))
21 {
22 }
23
24 void processing_function(std::shared_ptr<Buffer> buffer) override
25 {
26 std::visit([buffer](auto& fn) {
27 if constexpr (std::is_same_v<decltype(fn), AudioProcessingFunction&>) {
28 if (auto audio_buf = std::dynamic_pointer_cast<AudioBuffer>(buffer)) {
29 fn(audio_buf);
30 }
31 } else {
32 if (auto vk_buf = std::dynamic_pointer_cast<VKBuffer>(buffer)) {
33 fn(vk_buf);
34 }
35 }
36 },
38 }
39
40 void on_attach(std::shared_ptr<Buffer> buffer) override
41 {
42 if (auto audio_buffer = std::dynamic_pointer_cast<AudioBuffer>(buffer)) {
45 }
46 } else if (auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer)) {
49 }
50 } else {
52 std::source_location::current(),
53 "QuickProcess can only be attached to AudioBuffer or VKBuffer");
54 }
55 }
56
57 [[nodiscard]] bool is_compatible_with(std::shared_ptr<Buffer> buffer) const override
58 {
59 return std::dynamic_pointer_cast<AudioBuffer>(buffer) != nullptr || std::dynamic_pointer_cast<VKBuffer>(buffer) != nullptr;
60 }
61
62private:
64};
65
67 TokenUnitManager& unit_manager,
68 BufferAccessControl& access_control)
69 : m_unit_manager(unit_manager)
70 , m_access_control(access_control)
71{
72}
73
74// ============================================================================
75// Token-Dispatching Processor Management
76// ============================================================================
77
79 const std::shared_ptr<BufferProcessor>& processor,
80 const std::shared_ptr<Buffer>& buffer,
82{
84 if (auto audio_buffer = std::dynamic_pointer_cast<AudioBuffer>(buffer)) {
85 add_audio_processor(processor, audio_buffer);
86 }
88 add_graphics_processor(processor, buffer, token);
89 }
90}
91
93 const std::shared_ptr<BufferProcessor>& processor,
95 uint32_t channel)
96{
98 add_audio_processor_to_channel(processor, token, channel);
99 }
100}
101
103 const std::shared_ptr<BufferProcessor>& processor,
105{
109 add_graphics_processor(processor, token);
110 }
111}
112
114 const std::shared_ptr<BufferProcessor>& processor,
115 const std::shared_ptr<Buffer>& buffer,
117{
119 if (auto audio_buffer = std::dynamic_pointer_cast<AudioBuffer>(buffer)) {
120 remove_audio_processor(processor, audio_buffer);
121 }
124 }
125}
126
128 const std::shared_ptr<BufferProcessor>& processor,
130 uint32_t channel)
131{
133 if (channel == 0) {
135 } else {
136 remove_audio_processor_from_channel(processor, token, channel);
137 }
140 }
141}
142
144 const std::shared_ptr<BufferProcessor>& processor,
146{
151 }
152}
153
154// ============================================================================
155// Processor Management - Audio
156// ============================================================================
157
159 const std::shared_ptr<BufferProcessor>& processor,
160 const std::shared_ptr<AudioBuffer>& buffer)
161{
162 uint32_t channel_id = buffer->get_channel_id();
163
164 for (const auto& token : m_unit_manager.get_active_audio_tokens()) {
165 const auto& unit = m_unit_manager.get_audio_unit(token);
166 if (channel_id < unit.channel_count) {
167 auto processing_chain = unit.get_chain(channel_id);
168 processing_chain->add_processor(processor, buffer);
169 buffer->set_processing_chain(processing_chain);
170 return;
171 }
172 }
173
174 // Fallback: use global processing chain if no token matches
175 // This requires BufferManager to provide access to global chain
176 // For now, we log a warning
178 "Could not find matching token for audio buffer with channel ID {}", channel_id);
179}
180
182 const std::shared_ptr<BufferProcessor>& processor,
184 uint32_t channel)
185{
187 auto root_buffer = m_access_control.get_root_audio_buffer(token, channel);
188 chain->add_processor(processor, root_buffer);
189}
190
192 const std::shared_ptr<BufferProcessor>& processor,
194{
196 for (uint32_t i = 0; i < unit.channel_count; ++i) {
197 auto chain = unit.get_chain(i);
198 auto root_buffer = unit.get_buffer(i);
199 chain->add_processor(processor, root_buffer);
200 }
201}
202
204 const std::shared_ptr<BufferProcessor>& processor,
205 const std::shared_ptr<AudioBuffer>& buffer)
206{
207 uint32_t channel_id = buffer->get_channel_id();
208
209 for (const auto& token : m_unit_manager.get_active_audio_tokens()) {
210 const auto& unit = m_unit_manager.get_audio_unit(token);
211 if (channel_id < unit.channel_count) {
212 auto processing_chain = unit.get_chain(channel_id);
213 processing_chain->remove_processor(processor, buffer);
214 if (auto buf_chain = buffer->get_processing_chain()) {
215 buf_chain->remove_processor(processor, buffer);
216 }
217 return;
218 }
219 }
220}
221
223 const std::shared_ptr<BufferProcessor>& processor,
225 uint32_t channel)
226{
228 return;
229 }
230
232 if (channel >= unit.channel_count) {
233 return;
234 }
235
236 auto chain = unit.get_chain(channel);
237 auto root_buffer = unit.get_buffer(channel);
238 chain->remove_processor(processor, root_buffer);
239}
240
242 const std::shared_ptr<BufferProcessor>& processor,
244{
246 return;
247 }
248
250 for (uint32_t i = 0; i < unit.channel_count; ++i) {
251 auto chain = unit.get_chain(i);
252 auto root_buffer = unit.get_buffer(i);
253 chain->remove_processor(processor, root_buffer);
254 }
255}
256
258 const std::shared_ptr<BufferProcessor>& processor,
260{
262 return;
263 }
264
266 for (uint32_t i = 0; i < unit.channel_count; ++i) {
267 auto chain = unit.get_chain(i);
268 auto root_buffer = unit.get_buffer(i);
269 chain->add_final_processor(processor, root_buffer);
270 }
271}
272
273// ============================================================================
274// Quick Processing - Audio
275// ============================================================================
276
277std::shared_ptr<BufferProcessor> BufferProcessingControl::attach_quick_process(
278 BufferProcessingFunction processor,
279 const std::shared_ptr<Buffer>& buffer, ProcessingToken token)
280{
281 auto quick_process = std::make_shared<QuickProcess>(std::move(processor));
282 add_processor(quick_process, buffer, token);
283 return quick_process;
284}
285
286std::shared_ptr<BufferProcessor> BufferProcessingControl::attach_quick_process(
287 BufferProcessingFunction processor,
289 uint32_t channel)
290{
291 auto quick_process = std::make_shared<QuickProcess>(std::move(processor));
292 add_audio_processor_to_channel(quick_process, token, channel);
293 return quick_process;
294}
295
296std::shared_ptr<BufferProcessor> BufferProcessingControl::attach_quick_process(
297 BufferProcessingFunction processor,
299{
300 auto quick_process = std::make_shared<QuickProcess>(std::move(processor));
301 add_processor(quick_process, token);
302 return quick_process;
303}
304
305// ============================================================================
306// Node Connection - Audio
307// ============================================================================
308
310 const std::shared_ptr<Nodes::Node>& node,
312 uint32_t channel,
313 float mix,
314 bool clear_before)
315{
317
318 auto processor = std::make_shared<NodeSourceProcessor>(node, mix, clear_before);
319 processor->set_processing_token(token);
320
321 add_audio_processor_to_channel(processor, token, channel);
322}
323
325 const std::shared_ptr<Nodes::Node>& node,
326 const std::shared_ptr<AudioBuffer>& buffer,
327 float mix,
328 bool clear_before)
329{
330 auto processor = std::make_shared<NodeSourceProcessor>(node, mix, clear_before);
331 add_audio_processor(processor, buffer);
332}
333
334// ============================================================================
335// Processor Management - Graphics
336// ============================================================================
337
339 const std::shared_ptr<BufferProcessor>& processor,
341{
344 chain->add_processor(processor, root_buffer);
345}
346
348 const std::shared_ptr<BufferProcessor>& processor,
349 const std::shared_ptr<Buffer>& buffer,
351{
353 chain->add_processor(processor, buffer);
354 buffer->set_processing_chain(chain, false);
355}
356
358 const std::shared_ptr<BufferProcessor>& processor,
360{
362 auto chain = unit.get_chain();
363 auto root_buffer = unit.get_buffer();
364 chain->add_final_processor(processor, root_buffer);
365}
366
368 const std::shared_ptr<BufferProcessor>& processor,
370{
373 "Token {} not found when removing graphics processor",
374 static_cast<int>(token));
375 return;
376 }
377
379 auto chain = unit.get_chain();
380 auto root_buffer = unit.get_buffer();
381 chain->remove_processor(processor, root_buffer);
382}
383
384} // namespace MayaFlux::Buffers
#define MF_WARN(comp, ctx,...)
static MayaFlux::Nodes::ProcessingToken token
Definition Timers.cpp:8
std::shared_ptr< RootGraphicsBuffer > get_root_graphics_buffer(ProcessingToken token)
Gets the root graphics buffer for a specific token.
void ensure_audio_channels(ProcessingToken token, uint32_t channel_count)
Ensures minimum number of audio channels exist for a token.
std::shared_ptr< BufferProcessingChain > get_graphics_processing_chain(ProcessingToken token)
Gets the processing chain for a graphics token.
std::shared_ptr< BufferProcessingChain > get_audio_processing_chain(ProcessingToken token, uint32_t channel)
Gets the processing chain for an audio token and channel.
std::shared_ptr< RootAudioBuffer > get_root_audio_buffer(ProcessingToken token, uint32_t channel)
Gets the root audio buffer for a specific token and channel.
Token-aware buffer and unit access patterns.
void remove_audio_processor_from_token(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Removes a processor from all channels in an audio token.
void connect_node_to_audio_channel(const std::shared_ptr< Nodes::Node > &node, ProcessingToken token, uint32_t channel, float mix=0.5F, bool clear_before=false)
Connects a node to a specific audio token and channel.
void set_audio_final_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Sets a final processor for an audio token (applied to all channels)
void add_audio_processor_to_token(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Adds a processor to all channels in an audio token.
void add_graphics_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Adds a processor to the graphics processing chain.
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 (dispatches based on buffer/token)
void add_audio_processor_to_channel(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token, uint32_t channel)
Adds a processor to a specific audio token and channel.
void connect_node_to_audio_buffer(const std::shared_ptr< Nodes::Node > &node, const std::shared_ptr< AudioBuffer > &buffer, float mix=0.5F, bool clear_before=true)
Connects a node directly to a specific audio buffer.
void set_final_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Sets a final processor for a token (dispatches based on token)
void remove_audio_processor(const std::shared_ptr< BufferProcessor > &processor, const std::shared_ptr< AudioBuffer > &buffer)
Removes a processor from a specific audio buffer.
void add_audio_processor(const std::shared_ptr< BufferProcessor > &processor, const std::shared_ptr< AudioBuffer > &buffer)
Adds a processor to a specific audio buffer.
void set_graphics_final_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Sets a final processor for the graphics processing chain.
void remove_graphics_processor(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token)
Removes a processor from the graphics processing chain.
TokenUnitManager & m_unit_manager
Reference to the token/unit manager.
BufferProcessingControl(TokenUnitManager &unit_manager, BufferAccessControl &access_control)
Creates a new processing control handler.
void remove_audio_processor_from_channel(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token, uint32_t channel)
Removes a processor from a specific audio token and channel.
std::shared_ptr< BufferProcessor > attach_quick_process(BufferProcessingFunction processor, const std::shared_ptr< Buffer > &buffer, ProcessingToken token=ProcessingToken::AUDIO_BACKEND)
Creates and attaches a quick processing function to buffer.
void remove_processor(const std::shared_ptr< BufferProcessor > &processor, const std::shared_ptr< Buffer > &buffer, ProcessingToken token=ProcessingToken::AUDIO_BACKEND)
Removes a processor from a buffer (dispatches based on buffer/token)
BufferAccessControl & m_access_control
Reference to the buffer access control.
void remove_processor_from_token(const std::shared_ptr< BufferProcessor > &processor, ProcessingToken token, uint32_t channel=0)
Removes a processor from a token (dispatches based on token)
Central computational transformation interface for continuous buffer processing.
QuickProcess(BufferProcessingFunction function)
bool is_compatible_with(std::shared_ptr< Buffer > buffer) const override
Checks if this processor can handle the specified buffer type.
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when this processor is attached to a buffer.
void processing_function(std::shared_ptr< Buffer > buffer) override
The core processing function that must be implemented by derived classes.
std::vector< ProcessingToken > get_active_audio_tokens() const
Gets all active audio processing tokens.
RootGraphicsUnit & get_graphics_unit_mutable(ProcessingToken token)
Gets an existing graphics unit without creating if missing (mutable)
const RootAudioUnit & get_audio_unit(ProcessingToken token) const
Gets an existing audio unit without creating if missing.
bool has_audio_unit(ProcessingToken token) const
Checks if an audio unit exists for the given token.
RootAudioUnit & get_audio_unit_mutable(ProcessingToken token)
Gets an existing audio unit without creating if missing (mutable)
RootAudioUnit & get_or_create_audio_unit(ProcessingToken token)
Gets or creates a root audio unit for the specified token.
bool has_graphics_unit(ProcessingToken token) const
Checks if a graphics unit exists for the given token.
Token-scoped unit storage and lifecycle management.
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.
@ AUDIO_PARALLEL
High-performance audio processing with GPU acceleration.
std::variant< AudioProcessingFunction, GraphicsProcessingFunction > BufferProcessingFunction
@ BufferManagement
Buffer Management (Buffers::BufferManager, creating buffers)
@ Core
Core engine, backend, subsystems.
std::vector< double > mix(const std::vector< std::vector< double > > &streams)
Mix multiple data streams with equal weighting.
Definition Yantra.cpp:1019
std::shared_ptr< BufferProcessingChain > get_chain(uint32_t channel) const
std::shared_ptr< BufferProcessingChain > get_chain() const