MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ContainerBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
6
7namespace MayaFlux::Buffers {
8
9/**
10 * @class ContainerToBufferAdapter
11 * @brief Adapter for bridging N-dimensional containers and AudioBuffer interface.
12 *
13 * ContainerToBufferAdapter enables seamless integration between N-dimensional
14 * data containers (such as Kakshya::StreamContainer or SoundFileContainer) and the AudioBuffer
15 * processing system. It extracts audio data from containers and presents it as a standard
16 * AudioBuffer for use in block-based DSP, node networks, and hardware output.
17 *
18 * Key responsibilities:
19 * - Maps N-dimensional container data (time/channel/other axes) to linear audio buffer format.
20 * - Handles dimension selection, channel extraction, and position tracking.
21 * - Synchronizes processing state and lifecycle between container and buffer.
22 * - Supports automatic or manual advancement of read position for streaming or block-based workflows.
23 * - Enables zero-copy operation when possible, falling back to cached extraction as needed.
24 *
25 * This adapter is foundational for digital-first workflows where data may originate from
26 * files, streams, or procedural sources, and must be routed into the buffer system for
27 * further processing or output. While currently focused on audio, the design can be
28 * extended to support other data container types as more reader processors are implemented.
29 *
30 * @see ContainerBuffer, StreamContainer, SoundFileContainer, ContiguousAccessProcessor
31 */
32class MAYAFLUX_API ContainerToBufferAdapter : public BufferProcessor {
33public:
34 explicit ContainerToBufferAdapter(std::shared_ptr<Kakshya::StreamContainer> container);
35
36 /**
37 * @brief Extracts and processes data from the container into the target AudioBuffer.
38 * Handles dimension mapping, position tracking, and state synchronization.
39 * @param buffer The AudioBuffer to fill.
40 */
41 void processing_function(std::shared_ptr<Buffer> buffer) override;
42
43 /**
44 * @brief Attach the adapter to an AudioBuffer.
45 * Registers for container state changes and prepares for processing.
46 * @param buffer The AudioBuffer to attach to.
47 */
48 void on_attach(std::shared_ptr<Buffer> buffer) override;
49
50 /**
51 * @brief Detach the adapter from its AudioBuffer.
52 * Cleans up state and unregisters callbacks.
53 * @param buffer The AudioBuffer to detach from.
54 */
55 void on_detach(std::shared_ptr<Buffer> buffer) override;
56
57 /**
58 * @brief Set which channel dimension to extract from the container.
59 * @param channel_index Index in the channel dimension (default: 0)
60 */
61 void set_source_channel(uint32_t channel_index);
62 uint32_t get_source_channel() const { return m_source_channel; }
63
64 /**
65 * @brief Set the container to adapt.
66 * @param container The StreamContainer to extract data from.
67 */
68 void set_container(std::shared_ptr<Kakshya::StreamContainer> container);
69 std::shared_ptr<Kakshya::StreamContainer> get_container() const { return m_container; }
70
71 /**
72 * @brief Enable or disable automatic advancement of the container's read position.
73 * When enabled, the adapter will advance the container after each process call.
74 * @param enable True to enable auto-advance, false for manual control.
75 */
76 void set_auto_advance(bool enable) { m_auto_advance = enable; }
77 bool get_auto_advance() const { return m_auto_advance; }
78
79 /**
80 * @brief Enable or disable buffer state flag updates.
81 * When enabled, the adapter will update buffer processing/removal flags based on container state.
82 * @param update True to enable state updates.
83 */
84 void set_update_flags(bool update) { m_update_flags = update; }
85 bool get_update_flags() const { return m_update_flags; }
86
87private:
88 std::shared_ptr<Kakshya::StreamContainer> m_container;
89 uint32_t m_source_channel {};
90 bool m_auto_advance = true;
91 bool m_update_flags = true;
92
93 uint32_t m_time_reader_id = UINT32_MAX;
94 uint32_t m_channel_reader_id = UINT32_MAX;
95
96 uint32_t m_num_channels { 1 };
97 uint32_t m_reader_id {};
98
99 uint64_t m_consumption_offset {}; // Track position within current production
100
101 // Cache for efficiency
102 mutable std::vector<double> m_temp_buffer;
103
104 /**
105 * @brief Analyze the container's dimensions and update mapping info.
106 */
108
109 /**
110 * @brief Extract channel data from the container into the output buffer.
111 * @param output Output span to fill.
112 */
113 void extract_channel_data(std::span<double> output);
114
115 /**
116 * @brief Respond to container state changes (e.g., READY, PROCESSED, NEEDS_REMOVAL).
117 * Updates buffer state flags as needed.
118 * @param container The container whose state changed.
119 * @param state The new processing state.
120 */
121 void on_container_state_change(std::shared_ptr<Kakshya::SignalSourceContainer> container,
123};
124
125/**
126 * @class ContainerBuffer
127 * @brief AudioBuffer implementation backed by a StreamContainer.
128 *
129 * ContainerBuffer provides a bridge between the digital-first container system and
130 * the traditional AudioBuffer interface. It enables zero-copy or efficient extraction
131 * of audio data from StreamContainers (such as SoundFileContainer) for use in
132 * block-based DSP, node networks, and hardware output.
133 *
134 * Key responsibilities:
135 * - Maintains a reference to the backing StreamContainer and source channel.
136 * - Supports zero-copy operation when container memory layout matches buffer needs.
137 * - Falls back to cached extraction when zero-copy is not possible.
138 * - Integrates with ContainerToBufferAdapter for data extraction and state management.
139 * - Can be initialized and reconfigured at runtime for flexible routing.
140 *
141 * While currently focused on audio, this pattern can be extended to other data types
142 * as more container reader processors are implemented.
143 *
144 * @see ContainerToBufferAdapter, StreamContainer, SoundFileContainer
145 */
146class MAYAFLUX_API ContainerBuffer : public AudioBuffer {
147public:
148 /**
149 * @brief Construct a ContainerBuffer for a specific channel and container.
150 * @param channel_id Buffer channel index.
151 * @param num_samples Number of samples in the buffer.
152 * @param container Backing StreamContainer.
153 * @param source_channel Channel index in the container (default: 0).
154 */
155 ContainerBuffer(uint32_t channel_id,
156 uint32_t num_samples,
157 std::shared_ptr<Kakshya::StreamContainer> container,
158 uint32_t source_channel = 0);
159
160 /**
161 * @brief Initialize the buffer after construction.
162 * Must be called after the buffer is owned by a shared_ptr.
163 */
164 void initialize();
165
166 /**
167 * @brief Get the backing StreamContainer.
168 */
169 std::shared_ptr<Kakshya::StreamContainer> get_container() const { return m_container; }
170
171 /**
172 * @brief Get the source channel in the container.
173 */
174 uint32_t get_source_channel() const { return m_source_channel; }
175
176 /**
177 * @brief Update the container reference.
178 * @param container New StreamContainer to use.
179 */
180 void set_container(std::shared_ptr<Kakshya::StreamContainer> container);
181
182 /**
183 * @brief Check if buffer data is directly mapped to container (zero-copy).
184 * @return True if zero-copy mode is active.
185 */
186 bool is_zero_copy() const { return m_zero_copy_mode; }
187
188protected:
189 /**
190 * @brief Create the default processor (ContainerToBufferAdapter) for this buffer.
191 * @return Shared pointer to the created processor.
192 */
193 std::shared_ptr<BufferProcessor> create_default_processor() override;
194
195private:
196 std::shared_ptr<Kakshya::StreamContainer> m_container;
198 std::shared_ptr<BufferProcessor> m_pending_adapter;
199 bool m_zero_copy_mode = false;
200
201 /**
202 * @brief Attempt to enable zero-copy operation if container layout allows.
203 */
204 void setup_zero_copy_if_possible();
205};
206
207} // namespace MayaFlux::Buffers
Concrete audio implementation of the Buffer interface for double-precision audio data.
Central computational transformation interface for continuous buffer processing.
std::shared_ptr< Kakshya::StreamContainer > m_container
bool is_zero_copy() const
Check if buffer data is directly mapped to container (zero-copy).
uint32_t get_source_channel() const
Get the source channel in the container.
std::shared_ptr< Kakshya::StreamContainer > get_container() const
Get the backing StreamContainer.
std::shared_ptr< BufferProcessor > m_pending_adapter
AudioBuffer implementation backed by a StreamContainer.
std::shared_ptr< Kakshya::StreamContainer > get_container() const
void analyze_container_dimensions()
Analyze the container's dimensions and update mapping info.
void set_auto_advance(bool enable)
Enable or disable automatic advancement of the container's read position.
void set_update_flags(bool update)
Enable or disable buffer state flag updates.
std::shared_ptr< Kakshya::StreamContainer > m_container
Adapter for bridging N-dimensional containers and AudioBuffer interface.
void initialize()
Definition main.cpp:11
ProcessingState
Represents the current processing lifecycle state of a container.