MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
RootAudioBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "RootBuffer.hpp"
4
7
8namespace MayaFlux::Buffers {
9
10/**
11 * @class RootAudioBuffer
12 * @brief Top-level aggregation buffer for computational data streams
13 *
14 * RootAudioBuffer serves as the final convergence point for data streams in each channel
15 * before output to hardware interfaces. Similar to RootNode in the node system,
16 * there is typically one RootAudioBuffer per output channel in a multi-channel system.
17 *
18 * Key responsibilities:
19 * - Aggregating and combining data from multiple tributary buffers
20 * - Receiving direct output from computational node networks (via set_node_output)
21 * - Applying final normalization and boundary enforcement to ensure valid output
22 * - Ensuring thread-safe access to shared data resources
23 *
24 * RootAudioBuffer implements a hierarchical data aggregation pattern where multiple
25 * computational streams (child buffers and node output) are combined through a
26 * configurable mixing algorithm before being transmitted to hardware interfaces.
27 */
28class MAYAFLUX_API RootAudioBuffer : public RootBuffer<AudioBuffer> {
29public:
30 /**
31 * @brief Creates a new root aggregation buffer for a channel
32 * @param channel_id Channel identifier in multi-channel systems
33 * @param num_samples Buffer capacity in samples (default: 512)
34 *
35 * Initializes a root buffer with the specified channel ID and capacity.
36 * The buffer is automatically configured with a ChannelProcessor as
37 * its default processor for data aggregation.
38 */
39 RootAudioBuffer(uint32_t channel_id, uint32_t num_samples = 512);
40
41 void initialize();
42
43 /**
44 * @brief Virtual destructor for proper resource management
45 */
46 ~RootAudioBuffer() override = default;
47
48 /**
49 * @brief Processes this buffer using its default aggregation processor
50 *
51 * For a root buffer, this typically involves:
52 * 1. Processing all tributary buffers to ensure current data
53 * 2. Combining tributary outputs with direct node network output
54 * 3. Applying final normalization to ensure valid output ranges
55 *
56 * This method is thread-safe and can be called from real-time threads.
57 */
58 virtual void process_default() override;
59
60 /**
61 * @brief Resizes this buffer and all tributary buffers
62 * @param num_samples New buffer capacity in samples
63 *
64 * Adjusts the capacity of this buffer and all its tributary buffers to
65 * ensure consistent buffer dimensions throughout the aggregation hierarchy.
66 */
67 virtual void resize(uint32_t num_samples) override;
68
69 /**
70 * @brief Sets direct node network output data for this buffer
71 * @param data Vector of data samples from node network processing
72 *
73 * This allows computational node networks to directly contribute data
74 * to the root buffer, which is combined with tributary buffer outputs.
75 * The data is copied to ensure thread safety between computational domains.
76 */
77 void set_node_output(const std::vector<double>& data);
78
79 /**
80 * @brief Gets the current node network output data
81 * @return Constant reference to the node output vector
82 */
83 inline const std::vector<double>& get_node_output() const { return m_node_output; }
84
85 /**
86 * @brief Checks if this buffer has node network output data
87 * @return true if node output is present, false otherwise
88 */
89 inline bool has_node_output() const { return m_has_node_output; }
90
91 /**
92 * @brief Activates/deactivates processing for the current token
93 * @param active Whether this buffer should process when its token is active
94 *
95 * For RootAudioBuffer, this controls whether the buffer participates in
96 * token-based processing cycles. When inactive, the buffer won't process
97 * even if its token is being processed by the system.
98 */
99 inline virtual void set_token_active(bool active) override { m_token_active = active; }
100
101 /**
102 * @brief Checks if the buffer is active for its assigned token
103 * @return True if the buffer will process when its token is processed
104 */
105 inline virtual bool is_token_active() const override { return m_token_active; }
106
107protected:
108 /**
109 * @brief Creates the default processor for this buffer type
110 * @return Shared pointer to a ChannelProcessor
111 *
112 * Root buffers use a ChannelProcessor as their default processor,
113 * which handles combining tributary buffers and node network output.
114 */
115 virtual std::shared_ptr<BufferProcessor> create_default_processor() override;
116
117private:
118 /**
119 * @brief Data received directly from computational node networks
120 */
121 std::vector<double> m_node_output;
122
123 /**
124 * @brief Flag indicating if node network output data is present
125 */
127
128 /**
129 * @brief Flag indicating if this buffer is active for token processing
130 */
132};
133
134/**
135 * @class ChannelProcessor
136 * @brief Processor that implements hierarchical data aggregation for root buffers
137 *
138 * ChannelProcessor is the default processor for RootAudioBuffer objects.
139 * It implements a configurable algorithm for combining data from tributary
140 * buffers and direct node network output to produce the final output for a channel.
141 *
142 * This processor is automatically created and attached to root buffers,
143 * but can be replaced with custom aggregation algorithms if needed.
144 *
145 * Token Compatibility:
146 * - Primary Token: AUDIO_BACKEND (sample-rate, CPU, sequential processing)
147 * - Compatible with other audio processing tokens through token compatibility rules
148 * - Not compatible with GRAPHICS_BACKEND tokens due to different processing models
149 */
150class MAYAFLUX_API ChannelProcessor : public BufferProcessor {
151public:
152 /**
153 * @brief Creates a new channel aggregation processor
154 * @param root_buffer Shared pointer to the root buffer this processor will manage
155 *
156 * The processor maintains a raw pointer to its root buffer to avoid
157 * circular references, as the root buffer already owns a shared_ptr
158 * to this processor in the object composition hierarchy.
159 */
160 ChannelProcessor(std::shared_ptr<Buffer> root_buffer);
161
162 /**
163 * @brief Processes a buffer by combining tributary buffers and node network output
164 * @param buffer Buffer to process (should be the root buffer)
165 *
166 * This method implements a hierarchical data aggregation algorithm:
167 * 1. Processes all tributary buffers to ensure current data
168 * 2. Combines their outputs into the root buffer using a weighted averaging algorithm
169 * 3. Incorporates node network output if present
170 *
171 * The combination algorithm can be customized in the implementation.
172 */
173 void processing_function(std::shared_ptr<Buffer> buffer) override;
174
175 /**
176 * @brief Called when processor is attached to a buffer
177 * @param buffer Buffer being attached to
178 *
179 * Validates that the buffer is a compatible RootAudioBuffer and ensures
180 * token compatibility for proper processing pipeline integration.
181 */
182 void on_attach(std::shared_ptr<Buffer> buffer) override;
183
184 /**
185 * @brief Checks compatibility with a specific buffer type
186 * @param buffer Buffer to check compatibility with
187 * @return True if compatible (buffer is RootAudioBuffer), false otherwise
188 */
189 bool is_compatible_with(std::shared_ptr<Buffer> buffer) const override;
190
191private:
192 /**
193 * @brief Shared pointer to the root buffer this processor manages
194 */
195 std::shared_ptr<RootAudioBuffer> m_root_buffer;
196};
197
198/**
199 * @class FinalLimiterProcessor
200 * @brief Processor that enforces boundary conditions on output data
201 *
202 * FinalLimiterProcessor is typically used as the final processor in
203 * a root buffer's processing chain. It ensures that output values
204 * remain within defined boundaries before transmission to hardware interfaces.
205 *
206 * This boundary enforcement is critical for root buffers since they connect
207 * directly to hardware interfaces, where out-of-range values can cause
208 * distortion, artifacts, or potentially damage physical components.
209 *
210 * Token Compatibility:
211 * - Primary Token: AUDIO_BACKEND (optimized for audio sample rate processing)
212 * - Can adapt to GPU_PROCESS tokens for parallel limiting when beneficial
213 * - Compatible with SEQUENTIAL and PARALLEL processing modes
214 */
215class MAYAFLUX_API FinalLimiterProcessor : public BufferProcessor {
216public:
217 /**
218 * @brief Creates a new final limiter processor
219 *
220 * Initializes the processor with default AUDIO_BACKEND token for
221 * standard audio processing compatibility.
222 */
224
225 /**
226 * @brief Processes a buffer by enforcing boundary conditions
227 * @param buffer Buffer to process
228 *
229 * This method applies a non-linear boundary enforcement algorithm to ensure
230 * all values stay within the valid range (typically -1.0 to 1.0) before
231 * being transmitted to hardware interfaces, while preserving the perceptual
232 * characteristics of the original signal.
233 */
234 void processing_function(std::shared_ptr<Buffer> buffer) override;
235
236 /**
237 * @brief Called when processor is attached to a buffer
238 * @param buffer Buffer being attached to
239 *
240 * Validates that the buffer is an AudioBuffer-derived type and ensures
241 * token compatibility for proper audio processing.
242 */
243 void on_attach(std::shared_ptr<Buffer> buffer) override;
244
245 /**
246 * @brief Checks compatibility with a specific buffer type
247 * @param buffer Buffer to check compatibility with
248 * @return True if compatible (buffer is AudioBuffer-derived), false otherwise
249 */
250 bool is_compatible_with(std::shared_ptr<Buffer> buffer) const override;
251};
252
253}
Central computational transformation interface for continuous buffer processing.
std::shared_ptr< RootAudioBuffer > m_root_buffer
Shared pointer to the root buffer this processor manages.
Processor that implements hierarchical data aggregation for root buffers.
Processor that enforces boundary conditions on output data.
const std::vector< double > & get_node_output() const
Gets the current node network output data.
bool m_token_active
Flag indicating if this buffer is active for token processing.
std::vector< double > m_node_output
Data received directly from computational node networks.
bool m_has_node_output
Flag indicating if node network output data is present.
~RootAudioBuffer() override=default
Virtual destructor for proper resource management.
virtual bool is_token_active() const override
Checks if the buffer is active for its assigned token.
virtual void set_token_active(bool active) override
Activates/deactivates processing for the current token.
bool has_node_output() const
Checks if this buffer has node network output data.
Top-level aggregation buffer for computational data streams.
void initialize()
Definition main.cpp:11