MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ capture_operation()

void MayaFlux::Kriya::BufferPipeline::capture_operation ( BufferOperation &  op,
uint64_t  cycle 
)
private

Definition at line 121 of file BufferPipelineCapture.cpp.

122{
123 if (route_image(op)) {
124 return;
125 }
126
127 Kakshya::DataVariant buffer_data;
128
129 if (op.m_capture.get_audio_buffer()) {
130 bool should_process = op.m_capture.get_processing_control() == BufferCapture::ProcessingControl::ON_CAPTURE;
131 buffer_data = detail::extract_buffer_data(op.m_capture.get_audio_buffer(), should_process);
132 } else if (op.m_capture.get_graphics_buffer()) {
133 auto graphics_data = read_graphics_buffer(op, op.m_capture.get_graphics_buffer());
134 if (!graphics_data) {
135 return;
136 }
137 buffer_data = std::move(*graphics_data);
138 }
139
140 if (op.m_capture.m_data_ready_callback) {
141 op.m_capture.m_data_ready_callback(buffer_data, cycle);
142 }
143
144 auto capture_mode = op.m_capture.get_mode();
145
146 switch (capture_mode) {
148 m_operation_data[&op] = buffer_data;
149 break;
150
152 auto it = m_operation_data.find(&op);
153 if (it == m_operation_data.end()) {
154 m_operation_data[&op] = buffer_data;
155 } else {
156 try {
157 append_capture_data(it->second, buffer_data);
158
159 } catch (const std::bad_variant_access& e) {
162 "Data type mismatch during ACCUMULATE capture: {}",
163 e.what());
164 m_operation_data[&op] = buffer_data;
165 }
166 }
167 break;
168 }
170 uint32_t circular_size = op.m_capture.get_circular_size();
171 if (circular_size == 0) {
172 circular_size = 4096;
173 }
174
175 auto it = m_operation_data.find(&op);
176 if (it == m_operation_data.end()) {
177 m_operation_data[&op] = buffer_data;
178 } else {
179 try {
180 update_circular_capture(it->second, buffer_data, circular_size);
181
182 } catch (const std::bad_variant_access& e) {
185 "Data type mismatch during CIRCULAR capture: {}",
186 e.what());
187 m_operation_data[&op] = buffer_data;
188 } catch (std::exception& e) {
191 std::source_location::current(),
192 "Error during CIRCULAR capture: {}",
193 e.what());
194 m_operation_data[&op] = buffer_data;
195 }
196 }
197 break;
198 }
200 uint32_t window_size = op.m_capture.get_window_size();
201 float overlap_ratio = op.m_capture.get_overlap_ratio();
202
203 if (window_size == 0) {
204 window_size = 512;
205 }
206
207 auto hop_size = static_cast<uint32_t>((float)window_size * (1.0F - overlap_ratio));
208 if (hop_size == 0)
209 hop_size = 1;
210
211 auto it = m_operation_data.find(&op);
212 if (it == m_operation_data.end()) {
213 m_operation_data[&op] = buffer_data;
214 } else {
215 try {
216 update_windowed_capture(it->second, buffer_data, window_size, hop_size);
217
218 } catch (const std::bad_variant_access& e) {
220 "Data type mismatch during WINDOWED capture: {}", e.what());
221 m_operation_data[&op] = buffer_data;
222 }
223 }
224 break;
225 }
226
228 if (op.m_capture.m_stop_condition && op.m_capture.m_stop_condition()) {
229 m_operation_data[&op] = buffer_data;
230 }
231 break;
232 }
233
234 default:
235 m_operation_data[&op] = buffer_data;
236 break;
237 }
238
239 if (has_immediate_routing(op)) {
240 auto current_it = std::ranges::find_if(m_operations,
241 [&op](const BufferOperation& o) { return &o == &op; });
242
243 if (current_it != m_operations.end()) {
244 auto next_it = std::next(current_it);
245 if (next_it != m_operations.end() && next_it->get_type() == BufferOperation::OpType::ROUTE) {
246
247 if (next_it->m_target_audio_buffer) {
248 if (!m_buffer_manager) {
249 error<std::invalid_argument>(Journal::Component::Kriya,
251 std::source_location::current(),
252 "BufferPipeline has no BufferManager for immediate ROUTE-to-buffer");
253 }
254
255 if (!next_it->m_attached_processor) {
256 auto writer = std::make_shared<Buffers::AudioWriteProcessor>();
257 m_buffer_manager->add_processor(writer, next_it->m_target_audio_buffer,
259 next_it->m_attached_processor = writer;
260 }
261
262 std::static_pointer_cast<Buffers::AudioWriteProcessor>(next_it->m_attached_processor)
263 ->set_data(buffer_data);
264 } else if (next_it->m_target_graphics_buffer) {
265 queue_graphics_write(*next_it, next_it->m_target_graphics_buffer, buffer_data);
266 } else if (next_it->m_target_audio_stream) {
267 detail::write_to_container(next_it->m_target_audio_stream, buffer_data, next_it->m_target_audio_channel);
268 } else if (next_it->m_target_graphics_stream) {
269 detail::write_to_container(next_it->m_target_graphics_stream, buffer_data);
270 }
271
272 size_t route_index = std::distance(m_operations.begin(), next_it);
273 if (route_index < m_data_states.size()) {
274 m_data_states[route_index] = DataState::CONSUMED;
275 }
276 }
277 }
278 }
279}
#define MF_ERROR(comp, ctx,...)
@ TRANSIENT
Single cycle capture (default) - data expires after 1 cycle.
@ CIRCULAR
Circular buffer with overwrite.
@ ACCUMULATE
Accumulate over multiple cycles in container.
@ WINDOWED
Rolling window capture with overlap.
@ TRIGGERED
Capture only when condition met.
@ ROUTE
Route data to destination (buffer or container)
std::unordered_map< BufferOperation *, Kakshya::DataVariant > m_operation_data
void queue_graphics_write(BufferOperation &op, const std::shared_ptr< Buffers::VKBuffer > &target, const Kakshya::DataVariant &data)
std::optional< Kakshya::DataVariant > read_graphics_buffer(BufferOperation &op, const std::shared_ptr< Buffers::VKBuffer > &buffer)
std::vector< BufferOperation > m_operations
std::vector< DataState > m_data_states
bool route_image(BufferOperation &op)
std::shared_ptr< Buffers::BufferManager > m_buffer_manager
bool has_immediate_routing(const BufferOperation &op) const
@ AUDIO_BACKEND
Standard audio processing backend configuration.
@ CoroutineScheduling
Coroutine scheduling and temporal coordination (Vruta::TaskScheduler)
void error_rethrow(Component component, Context context, std::source_location location=std::source_location::current(), std::string_view additional_context="")
Catch and log an exception, then rethrow it.
@ Kriya
Automatable tasks and fluent scheduling api for Nodes and Buffers.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Definition NDData.hpp:70
Kakshya::DataVariant extract_buffer_data(const std::shared_ptr< Buffers::AudioBuffer > &buffer, bool should_process)
void write_to_container(const std::shared_ptr< Kakshya::DynamicSoundStream > &container, const Kakshya::DataVariant &data, uint32_t channel)

References MayaFlux::Kriya::BufferCapture::get_audio_buffer(), MayaFlux::Kriya::BufferCapture::get_circular_size(), MayaFlux::Kriya::BufferCapture::get_graphics_buffer(), MayaFlux::Kriya::BufferCapture::get_mode(), MayaFlux::Kriya::BufferCapture::get_overlap_ratio(), MayaFlux::Kriya::BufferCapture::get_processing_control(), MayaFlux::Kriya::BufferCapture::get_window_size(), MayaFlux::Kriya::BufferOperation::m_capture, MayaFlux::Kriya::BufferCapture::m_data_ready_callback, MayaFlux::Kriya::BufferCapture::m_stop_condition, and MF_ERROR.

Referenced by process_operation().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: