Construct a GranularMatrix with grammar rules appropriate for the requested output type.
REGION_GROUP: registers segment, attribute, sort (existing behaviour). CONTAINER: registers segment, attribute, sort, then appends reconstruct. The reconstruct rule reads the source container from ExecutionContext::execution_metadata["container"] and writes stitched per-channel audio into a SoundFileContainer. CONTAINER_ADDITIVE: same as CONTAINER but uses an overlap-add reconstruct rule
763{
764 auto matrix = std::make_shared<GranularMatrix>();
765
766 matrix->create_operation<
SegmentOp>(
"segment");
767 matrix->create_operation<
AttributeOp>(
"attribute");
768 matrix->create_operation<
SortOp>(
"sort");
769
770 matrix->get_grammar()->create_rule("segment")
771 .with_context(ComputationContext::TEMPORAL)
772 .with_priority(100)
773 .with_description("Fixed hop-size grain segmentation")
775 .executes(segment_grains)
776 .build();
777
778 matrix->get_grammar()->create_rule("attribute")
779 .with_context(attribution_context)
780 .with_priority(75)
781 .with_description("Per-grain feature attribution via analyzer or lambda")
783 .executes(attribute_grains)
784 .build();
785
786 matrix->get_grammar()->create_rule("sort")
787 .with_context(ComputationContext::STRUCTURAL)
788 .with_priority(50)
789 .with_description("Attribute-keyed grain sort, CPU or GPU")
791 .executes(sort_grains)
792 .build();
793
794 if (
output == GranularOutput::CONTAINER) {
795 matrix->get_grammar()->create_rule("reconstruct")
796 .with_context(ComputationContext::STRUCTURAL)
797 .with_priority(25)
798 .with_description("Stitch sorted grains into a SoundFileContainer")
800 .executes(reconstruct_grains)
801 .build();
802 }
else if (
output == GranularOutput::CONTAINER_ADDITIVE) {
803 auto ola_executor =
804 [t = std::move(taper)](
const std::any& in,
const ExecutionContext& ctx) -> std::any {
806 if (t) {
808 }
809 return reconstruct_grains_additive(in, patched);
810 };
811
812 matrix->get_grammar()->create_rule("reconstruct")
813 .with_context(ComputationContext::STRUCTURAL)
814 .with_priority(25)
815 .with_description("Additive grain reconstruction into SoundFileContainer")
816 .matches_type<Kakshya::RegionGroup>()
817 .executes(ola_executor)
818 .build();
819 }
else if (
output == GranularOutput::STREAM) {
820 matrix->get_grammar()->create_rule("reconstruct")
821 .with_context(ComputationContext::STRUCTURAL)
822 .with_priority(25)
823 .with_description("Stitch sorted grains into a DynamicSoundStream")
824 .matches_type<Kakshya::RegionGroup>()
825 .executes(reconstruct_grains_stream)
826 .build();
827 }
else if (
output == GranularOutput::STREAM_ADDITIVE) {
828 auto ola_executor =
829 [t = std::move(taper)](const std::any& in, const ExecutionContext& ctx) -> std::any {
830 ExecutionContext patched = ctx;
831 if (t)
834 };
835
836 matrix->get_grammar()->create_rule("reconstruct")
837 .with_context(ComputationContext::STRUCTURAL)
838 .with_priority(25)
839 .with_description("Additive grain reconstruction into DynamicSoundStream")
840 .matches_type<Kakshya::RegionGroup>()
841 .executes(ola_executor)
842 .build();
843 }
844
845 return matrix;
846}
std::shared_ptr< Core::VKImage > output
Computes a scalar attribute per grain and writes it onto each Region.
Segments container audio into fixed hop-size grain windows.
Sorts grains by a named attribute key, with optional GPU dispatch.
const ComputationGrammar::Rule::Executor reconstruct_grains_additive_stream
Grammar rule executor — OLA reconstruct into DynamicSoundStream.
Organizes related signal regions into a categorized collection.
std::unordered_map< std::string, std::any > execution_metadata
Arbitrary metadata parameters used by operations.
Context information controlling how a compute operation executes.