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

◆ process_operation()

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

Definition at line 511 of file BufferPipeline.cpp.

512{
513 try {
514 switch (op.get_type()) {
516 capture_operation(op, cycle);
517
518 break;
519 }
520
522 Kakshya::DataVariant input_data;
523 if (m_operation_data.find(&op) != m_operation_data.end()) {
524 input_data = m_operation_data[&op];
525 } else {
526 for (auto& it : m_operation_data) {
527 input_data = it.second;
528 break;
529 }
530 }
531
532 if (op.m_transformer) {
533 auto transformed = op.m_transformer(input_data, cycle);
534 m_operation_data[&op] = transformed;
535
536 const bool has_downstream_route = std::ranges::any_of(
538 [](const BufferOperation& o) {
539 return o.get_type() == BufferOperation::OpType::ROUTE;
540 });
541
542 if (!has_downstream_route) {
543 for (auto& candidate : std::ranges::reverse_view(m_operations)) {
544 if (&candidate == &op)
545 continue;
546 if (candidate.get_type() != BufferOperation::OpType::CAPTURE
547 || !candidate.m_capture.get_buffer()) {
548 continue;
549 }
550 const auto buf = candidate.m_capture.get_buffer();
551 if (std::holds_alternative<std::vector<double>>(transformed)
552 && std::get<std::vector<double>>(transformed).size() == buf->get_data().size()) {
553 write_to_buffer(buf, transformed);
554 }
555 break;
556 }
557 }
558 }
559 break;
560 }
561
563 Kakshya::DataVariant data_to_route;
564 if (m_operation_data.find(&op) != m_operation_data.end()) {
565 data_to_route = m_operation_data[&op];
566 } else {
567 for (auto& it : m_operation_data) {
568 data_to_route = it.second;
569 break;
570 }
571 }
572
573 if (op.m_target_buffer) {
574 if (!m_buffer_manager) {
575 error<std::invalid_argument>(Journal::Component::Kriya,
577 std::source_location::current(),
578 "BufferPipeline has no BufferManager for ROUTE-to-buffer operation");
579 }
580
581 if (!op.m_attached_processor) {
582 auto writer = std::make_shared<Buffers::AudioWriteProcessor>();
583 m_buffer_manager->add_processor(writer, op.m_target_buffer,
585 op.m_attached_processor = writer;
586 }
587
588 std::static_pointer_cast<Buffers::AudioWriteProcessor>(op.m_attached_processor)
589 ->set_data(data_to_route);
590
591 } else if (op.m_target_container) {
592 write_to_container(op.m_target_container, data_to_route);
593 }
594 break;
595 }
596
598 auto loaded_data = read_from_container(op.m_source_container,
599 op.m_start_frame,
600 op.m_load_length);
601
602 if (op.m_target_buffer) {
603 write_to_buffer(op.m_target_buffer, loaded_data);
604 }
605
606 m_operation_data[&op] = loaded_data;
607 break;
608 }
609
611 std::vector<Kakshya::DataVariant> fusion_inputs;
612
613 for (auto& source_buffer : op.m_source_buffers) {
614 bool should_process = op.m_capture.get_processing_control() == BufferCapture::ProcessingControl::ON_CAPTURE;
615 auto buffer_data = extract_buffer_data(source_buffer, should_process);
616 fusion_inputs.push_back(buffer_data);
617 }
618
619 for (auto& source_container : op.m_source_containers) {
620 auto container_data = read_from_container(source_container, 0, 0);
621 fusion_inputs.push_back(container_data);
622 }
623
624 if (op.m_fusion_function && !fusion_inputs.empty()) {
625 auto fused_data = op.m_fusion_function(fusion_inputs, cycle);
626
627 if (op.m_target_buffer) {
628 write_to_buffer(op.m_target_buffer, fused_data);
629 } else if (op.m_target_container) {
630 write_to_container(op.m_target_container, fused_data);
631 }
632
633 m_operation_data[&op] = fused_data;
634 }
635 break;
636 }
637
639 Kakshya::DataVariant data_to_dispatch;
640 if (m_operation_data.find(&op) != m_operation_data.end()) {
641 data_to_dispatch = m_operation_data[&op];
642 } else {
643 for (auto& it : m_operation_data) {
644 data_to_dispatch = it.second;
645 break;
646 }
647 }
648
649 if (op.m_dispatch_handler) {
650 op.m_dispatch_handler(data_to_dispatch, cycle);
651 }
652 break;
653 }
654
656 if (!m_buffer_manager) {
657 error<std::invalid_argument>(Journal::Component::Kriya,
659 std::source_location::current(),
660 "BufferPipeline has no BufferManager for MODIFY operation");
661 }
662
663 if (!op.m_attached_processor) {
664 op.m_attached_processor = m_buffer_manager->attach_quick_process(
665 op.m_buffer_modifier,
666 op.m_target_buffer, Buffers::ProcessingToken::AUDIO_BACKEND);
667 if (m_max_cycles != 0 && op.is_streaming()) {
668 op.m_modify_cycle_count = m_max_cycles - cycle;
669 }
670 }
671
672 if (op.m_modify_cycle_count > 0 && cycle >= op.m_modify_cycle_count - 1) {
673 if (op.m_attached_processor) {
674 m_buffer_manager->remove_processor(
675 op.m_attached_processor,
676 op.m_target_buffer);
677 op.m_attached_processor = nullptr;
678 }
679 }
680
681 break;
682 }
683
685 break;
686
687 default:
690 "Unknown operation type in pipeline : {} : {}",
691 Reflect::enum_to_string(op.get_type()), std::to_string(static_cast<int>(op.get_type())));
692 break;
693 }
694 } catch (const std::exception& e) {
697 std::source_location::current(),
698 "Error processing operation in BufferPipeline: {}",
699 e.what());
700 }
701}
#define MF_ERROR(comp, ctx,...)
@ LOAD
Load data from container to buffer with position control.
@ CONDITION
Conditional operation for branching logic.
@ FUSE
Fuse multiple sources using custom fusion functions.
@ ROUTE
Route data to destination (buffer or container)
@ CAPTURE
Capture data from source buffer using BufferCapture strategy.
@ MODIFY
Modify Buffer Data using custom quick process.
@ DISPATCH
Dispatch to external handler for custom processing.
@ TRANSFORM
Apply transformation function to data variants.
std::unordered_map< BufferOperation *, Kakshya::DataVariant > m_operation_data
static void write_to_container(const std::shared_ptr< Kakshya::DynamicSoundStream > &container, const Kakshya::DataVariant &data)
void capture_operation(BufferOperation &op, uint64_t cycle)
std::vector< BufferOperation > m_operations
static Kakshya::DataVariant read_from_container(const std::shared_ptr< Kakshya::DynamicSoundStream > &container, uint64_t start, uint32_t length)
static void write_to_buffer(const std::shared_ptr< Buffers::AudioBuffer > &buffer, const Kakshya::DataVariant &data)
std::shared_ptr< Buffers::BufferManager > m_buffer_manager
static Kakshya::DataVariant extract_buffer_data(const std::shared_ptr< Buffers::AudioBuffer > &buffer, bool should_process=false)
@ 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:76
constexpr std::string_view enum_to_string(EnumType value) noexcept
Universal enum to string converter using magic_enum (original case)

References MayaFlux::Buffers::AUDIO_BACKEND, MayaFlux::Kriya::BufferOperation::CAPTURE, capture_operation(), MayaFlux::Kriya::BufferOperation::CONDITION, MayaFlux::Journal::CoroutineScheduling, MayaFlux::Kriya::BufferOperation::DISPATCH, MayaFlux::Reflect::enum_to_string(), extract_buffer_data(), MayaFlux::Kriya::BufferOperation::FUSE, MayaFlux::Kriya::BufferCapture::get_processing_control(), MayaFlux::Kriya::BufferOperation::get_type(), MayaFlux::Kriya::BufferOperation::is_streaming(), MayaFlux::Journal::Kriya, MayaFlux::Kriya::BufferOperation::LOAD, MayaFlux::Kriya::BufferOperation::m_attached_processor, m_buffer_manager, MayaFlux::Kriya::BufferOperation::m_buffer_modifier, MayaFlux::Kriya::BufferOperation::m_capture, MayaFlux::Kriya::BufferOperation::m_dispatch_handler, MayaFlux::Kriya::BufferOperation::m_fusion_function, MayaFlux::Kriya::BufferOperation::m_load_length, m_max_cycles, MayaFlux::Kriya::BufferOperation::m_modify_cycle_count, m_operation_data, m_operations, MayaFlux::Kriya::BufferOperation::m_source_buffers, MayaFlux::Kriya::BufferOperation::m_source_container, MayaFlux::Kriya::BufferOperation::m_source_containers, MayaFlux::Kriya::BufferOperation::m_start_frame, MayaFlux::Kriya::BufferOperation::m_target_buffer, MayaFlux::Kriya::BufferOperation::m_target_container, MayaFlux::Kriya::BufferOperation::m_transformer, MF_ERROR, MayaFlux::Kriya::BufferOperation::MODIFY, MayaFlux::Kriya::BufferCapture::ON_CAPTURE, read_from_container(), MayaFlux::Kriya::BufferOperation::ROUTE, MayaFlux::Kriya::BufferOperation::TRANSFORM, write_to_buffer(), and write_to_container().

Referenced by execute_phased(), and execute_streaming().

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