15 std::string resolve_qualifier(
AnalysisType type,
const std::string& qualifier)
17 if (!qualifier.empty()) {
30 error<std::invalid_argument>(
32 std::source_location::current(),
33 "resolve_qualifier: no default qualifier for AnalysisType {}",
34 static_cast<int>(type));
38 std::shared_ptr<Kakshya::SoundFileContainer> run_to_container(
39 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
46 auto seg_op = matrix->get_operation<
SegmentOp>(
"segment");
47 auto attr_op = matrix->get_operation<
AttributeOp>(
"attribute");
48 auto sort_op = matrix->get_operation<
SortOp>(
"sort");
54 auto seg = seg_op->apply_operation(input);
69 auto result = safe_any_cast_or_throw<
72 return std::dynamic_pointer_cast<Kakshya::SoundFileContainer>(result.data);
75 std::shared_ptr<Kakshya::DynamicSoundStream> run_to_stream(
76 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
83 auto seg_op = matrix->get_operation<
SegmentOp>(
"segment");
84 auto attr_op = matrix->get_operation<
AttributeOp>(
"attribute");
85 auto sort_op = matrix->get_operation<
SortOp>(
"sort");
91 auto seg = seg_op->apply_operation(input);
105 auto result = safe_any_cast_or_throw<
108 return std::dynamic_pointer_cast<Kakshya::DynamicSoundStream>(result.data);
115 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
116 const auto& regions = datum.data.regions;
118 if (regions.empty()) {
120 std::source_location::current(),
"reconstruct_grains: RegionGroup contains no grains");
123 if (!datum.container || !*datum.container) {
125 std::source_location::current(),
"reconstruct_grains: no source container in datum");
128 auto source = *datum.container;
129 const auto num_ch =
static_cast<uint32_t
>(source->get_structure().get_channel_count());
130 const auto org = source->get_structure().organization;
131 const uint32_t sample_rate = [&]() -> uint32_t {
132 if (
auto sc = std::dynamic_pointer_cast<Kakshya::SoundStreamContainer>(source))
133 return sc->get_sample_rate();
137 const auto grain_sz = safe_any_cast_or_default<uint32_t>(
138 datum.data.get_attribute<uint32_t>(
"grain_size").has_value()
139 ? std::any(datum.data.get_attribute<uint32_t>(
"grain_size").value())
143 std::vector<std::vector<double>> channel_data(num_ch);
144 for (uint32_t ch = 0; ch < num_ch; ++ch)
145 channel_data[ch].reserve(regions.size() * grain_sz);
148 [&channel_data](
size_t , uint32_t ch, std::span<double> samples) {
149 channel_data[ch].insert(channel_data[ch].end(), samples.begin(), samples.end());
153 std::dynamic_pointer_cast<Kakshya::SignalSourceContainer>(
161 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
162 const auto& regions = datum.
data.regions;
164 if (regions.empty()) {
166 std::source_location::current(),
"reconstruct_grains_additive: RegionGroup contains no grains");
169 if (!datum.container || !*datum.container) {
171 std::source_location::current(),
"reconstruct_grains_additive: no source container in datum");
174 auto source = *datum.container;
175 const auto num_ch =
static_cast<uint32_t
>(source->get_structure().get_channel_count());
176 const auto org = source->get_structure().organization;
177 const uint32_t sample_rate = [&]() -> uint32_t {
178 if (
auto sc = std::dynamic_pointer_cast<Kakshya::SoundStreamContainer>(source))
179 return sc->get_sample_rate();
183 const auto grain_sz = safe_any_cast_or_default<uint32_t>(
184 datum.data.get_attribute<uint32_t>(
"grain_size").has_value()
185 ? std::any(datum.data.get_attribute<uint32_t>(
"grain_size").value())
188 const auto hop_sz = safe_any_cast_or_default<uint32_t>(
189 datum.data.get_attribute<uint32_t>(
"hop_size").has_value()
190 ? std::any(datum.data.get_attribute<uint32_t>(
"hop_size").value())
194 const auto taper = safe_any_cast_or_default<GrainTaper>(
195 ctx.execution_metadata.contains(
"grain_taper")
196 ? ctx.execution_metadata.at(
"grain_taper")
200 const size_t out_len = (regions.size() - 1) * hop_sz + grain_sz;
201 std::vector<std::vector<double>> channel_data(num_ch, std::vector<double>(out_len, 0.0));
204 [&channel_data, hop_sz](
size_t gi, uint32_t ch, std::span<double> samples) {
205 const size_t offset = gi * hop_sz;
206 auto& dest = channel_data[ch];
207 for (
size_t s = 0; s < samples.size() && offset + s < dest.size(); ++s)
208 dest[offset + s] += samples[s];
212 std::dynamic_pointer_cast<Kakshya::SignalSourceContainer>(
220 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
221 const auto& regions = datum.
data.regions;
223 if (regions.empty()) {
225 std::source_location::current(),
"reconstruct_grains_stream: RegionGroup contains no grains");
228 if (!datum.container || !*datum.container) {
230 std::source_location::current(),
"reconstruct_grains_stream: no source container in datum");
233 auto source = *datum.container;
234 const auto num_ch =
static_cast<uint32_t
>(source->get_structure().get_channel_count());
235 const uint32_t sample_rate = [&]() -> uint32_t {
236 if (
auto sc = std::dynamic_pointer_cast<Kakshya::SoundStreamContainer>(source))
237 return sc->get_sample_rate();
241 const auto grain_sz = safe_any_cast_or_default<uint32_t>(
242 datum.data.get_attribute<uint32_t>(
"grain_size").has_value()
243 ? std::any(datum.data.get_attribute<uint32_t>(
"grain_size").value())
247 std::vector<std::vector<double>> channel_data(num_ch);
248 for (uint32_t ch = 0; ch < num_ch; ++ch)
249 channel_data[ch].reserve(regions.size() * grain_sz);
252 [&channel_data](
size_t , uint32_t ch, std::span<double> samples) {
253 channel_data[ch].insert(channel_data[ch].end(), samples.begin(), samples.end());
256 auto stream = std::make_shared<Kakshya::DynamicSoundStream>(sample_rate, num_ch);
258 std::vector<std::span<const double>> spans;
259 spans.reserve(num_ch);
260 for (
auto& ch : channel_data)
261 spans.emplace_back(ch);
263 stream->write_frames(spans, 0);
266 std::dynamic_pointer_cast<Kakshya::SignalSourceContainer>(stream), {}
272 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
273 const auto& regions = datum.
data.regions;
275 if (regions.empty()) {
277 std::source_location::current(),
"reconstruct_grains_additive_stream: RegionGroup contains no grains");
280 if (!datum.container || !*datum.container) {
282 std::source_location::current(),
"reconstruct_grains_additive_stream: no source container in datum");
285 auto source = *datum.container;
286 const auto num_ch =
static_cast<uint32_t
>(source->get_structure().get_channel_count());
287 const uint32_t sample_rate = [&]() -> uint32_t {
288 if (
auto sc = std::dynamic_pointer_cast<Kakshya::SoundStreamContainer>(source))
289 return sc->get_sample_rate();
293 const auto grain_sz = safe_any_cast_or_default<uint32_t>(
294 datum.data.get_attribute<uint32_t>(
"grain_size").has_value()
295 ? std::any(datum.data.get_attribute<uint32_t>(
"grain_size").value())
298 const auto hop_sz = safe_any_cast_or_default<uint32_t>(
299 datum.data.get_attribute<uint32_t>(
"hop_size").has_value()
300 ? std::any(datum.data.get_attribute<uint32_t>(
"hop_size").value())
304 const auto taper = safe_any_cast_or_default<GrainTaper>(
305 ctx.execution_metadata.contains(
"grain_taper")
306 ? ctx.execution_metadata.at(
"grain_taper")
310 const uint64_t out_frames = hop_sz * regions.size() + grain_sz;
311 std::vector<std::vector<double>> channel_data(num_ch, std::vector<double>(out_frames, 0.0));
314 [&](
size_t gi, uint32_t ch, std::span<double> samples) {
315 std::vector<double> grain(samples.begin(), samples.end());
318 const uint64_t offset = gi * hop_sz;
319 for (uint64_t i = 0; i < grain.size() && offset + i < out_frames; ++i)
320 channel_data[ch][offset + i] += grain[i];
323 auto stream = std::make_shared<Kakshya::DynamicSoundStream>(sample_rate, num_ch);
325 std::vector<std::span<const double>> spans;
326 spans.reserve(num_ch);
327 for (
auto& ch : channel_data)
328 spans.emplace_back(ch);
330 stream->write_frames(spans, 0);
333 std::dynamic_pointer_cast<Kakshya::SignalSourceContainer>(stream), {}
344 std::shared_ptr<Kakshya::SignalSourceContainer> container;
350 if (param.has_value()) {
351 container = safe_any_cast_or_default<std::shared_ptr<Kakshya::SignalSourceContainer>>(
357 error<std::runtime_error>(
359 std::source_location::current(),
360 "SegmentOp: no container available via Datum or parameters");
363 const auto grain_size = this->
template get_parameter_or_default<uint32_t>(
"grain_size", 1024U);
364 const auto hop_size = this->
template get_parameter_or_default<uint32_t>(
"hop_size", 512U);
365 const auto channel = this->
template get_parameter_or_default<uint32_t>(
"channel", 0U);
367 const auto& structure = container->get_structure();
369 if (
channel >= structure.get_channel_count()) {
370 error<std::runtime_error>(
372 std::source_location::current(),
373 "SegmentOp: channel {} out of range (container has {})",
374 channel, structure.get_channel_count());
377 const auto num_channels = structure.get_channel_count();
378 const auto total = container->get_num_frames();
381 out.data.regions.clear();
382 out.data.current_region_index = 0;
383 out.data.active_indices.clear();
385 for (uint64_t onset = 0; onset + grain_size <= total; onset += hop_size) {
387 std::vector<uint64_t> { onset, 0 },
388 std::vector<uint64_t> { onset + grain_size - 1, num_channels - 1 }
391 out.data.regions.push_back(std::move(grain));
394 out.data.set_attribute<uint32_t>(
"grain_size", grain_size);
395 out.data.set_attribute<uint32_t>(
"hop_size", hop_size);
396 out.data.set_attribute<uint32_t>(
"channel",
channel);
405std::shared_ptr<RegionGroupAnalyzer<Kakshya::RegionGroup>>
410 return std::make_shared<EnergyAnalyzer<Kakshya::RegionGroup, Kakshya::RegionGroup>>();
412 return std::make_shared<StatisticalAnalyzer<Kakshya::RegionGroup, Kakshya::RegionGroup>>();
414 error<std::invalid_argument>(
416 std::source_location::current(),
417 "make_default_analyzer: AnalysisType {} has no registered default analyzer",
418 static_cast<int>(type));
423 const std::any& analysis_result,
425 const std::string& qualifier)
427 const std::string
q = resolve_qualifier(type, qualifier);
430 const auto& ea = safe_any_cast_or_throw<EnergyAnalysis>(analysis_result);
431 if (ea.channels.empty())
433 const auto& ch = ea.channels[0];
435 if (
q ==
"rms" ||
q ==
"mean")
436 return ch.mean_energy;
437 if (
q ==
"peak" ||
q ==
"max")
438 return ch.max_energy;
440 return ch.min_energy;
443 if (
q ==
"dynamic_range")
444 return ch.max_energy - ch.min_energy;
445 if (
q ==
"zero_crossing")
446 return ch.event_positions.empty() ? 0.0 :
static_cast<double>(ch.event_positions.size());
448 return ch.mean_energy;
452 const auto& sa = safe_any_cast_or_throw<StatisticalAnalysis>(analysis_result);
453 if (sa.channel_statistics.empty())
455 const auto& ch = sa.channel_statistics[0];
460 return ch.stat_std_dev;
462 return ch.stat_variance;
482 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
489 exec = safe_any_cast_or_default<AttributeExecutor>(
494 if (
auto p = this->
get_parameter(
"attribute_executor"); p.has_value())
495 exec = safe_any_cast_or_default<AttributeExecutor>(p,
nullptr);
500 return exec(std::span<const double>(samples.data(), samples.size()), ctx);
503 const auto grain_variants = container->get_region_data(grain);
505 const std::string qualifier = [&]() -> std::string {
507 return safe_any_cast_or_default<std::string>(
511 return p.has_value() ? safe_any_cast_or_default<std::string>(p, {}) : std::string {};
516 return safe_any_cast_or_default<AnalysisType>(
526 std::shared_ptr<void> raw_analyzer;
528 raw_analyzer = safe_any_cast_or_default<std::shared_ptr<void>>(
534 raw_analyzer = safe_any_cast_or_default<std::shared_ptr<void>>(p,
nullptr);
541 ->analyze_energy(grain_variants),
548 ->analyze_statistics(grain_variants),
574 if (input.
data.regions.empty())
577 std::shared_ptr<Kakshya::SignalSourceContainer> container;
583 if (param.has_value()) {
584 container = safe_any_cast_or_default<std::shared_ptr<Kakshya::SignalSourceContainer>>(
590 error<std::runtime_error>(
592 std::source_location::current(),
593 "AttributeOp: no container available via Datum or parameters");
596 const auto channel = this->
template get_parameter_or_default<uint32_t>(
"channel", 0U);
597 const auto feature_key = this->
template get_parameter_or_default<std::string>(
"feature_key", std::string(
"feature"));
605 for (
auto& grain : out.data.regions) {
607 grain.set_attribute(feature_key, value);
620 const auto feature_key = this->
template get_parameter_or_default<std::string>(
"feature_key", std::string(
"feature"));
621 const bool ascending = this->
template get_parameter_or_default<bool>(
"ascending",
true);
622 const auto gpu_thresh = this->
template get_parameter_or_default<uint32_t>(
"gpu_sort_threshold", 0U);
623 const auto n =
static_cast<uint32_t
>(input.
data.regions.size());
630 if (gpu_thresh > 0 && n >= gpu_thresh) {
632 uint32_t element_count;
633 uint32_t pass_number;
637 std::vector<float> values(n);
638 for (uint32_t i = 0; i < n; ++i) {
639 auto attr = out.
data.regions[i].get_attribute<
double>(feature_key);
640 values[i] = attr ?
static_cast<float>(*attr) : 0.0F;
643 std::vector<uint32_t> indices(n);
644 std::iota(indices.begin(), indices.end(), 0U);
646 auto executor = std::make_shared<ShaderExecutionContext<>>(
649 .workgroup_size = { 256, 1, 1 },
650 .push_constant_size =
sizeof(SortPC) });
654 .set_output_size(1, n *
sizeof(uint32_t));
656 const uint32_t n_passes = n * 2;
657 executor->set_multipass(n_passes,
658 [n, ascending](uint32_t pass,
void* pc_data) {
661 .pass_number = pass & 1U,
662 .ascending = ascending ? 1U : 0U,
664 std::memcpy(pc_data, &pc,
sizeof(SortPC));
667 auto gpu_sorter = std::make_shared<GpuSorter<>>(executor);
673 auto result = gpu_sorter->apply_operation(sort_input);
676 std::vector<Kakshya::Region> reordered(n);
677 for (uint32_t i = 0; i < n; ++i)
678 reordered[i] = out.
data.regions[sorted_indices[i]];
680 out.
data.regions = std::move(reordered);
681 out.
data.current_region_index = 0;
682 out.
data.active_indices.clear();
686 out.
data.sort_by_attribute(feature_key);
689 std::ranges::reverse(out.
data.regions);
691 out.
data.current_region_index = 0;
692 out.
data.active_indices.clear();
703 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
704 auto op = std::make_shared<SegmentOp>();
706 return op->apply_operation(datum);
711 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
712 auto op = std::make_shared<AttributeOp>();
714 return op->apply_operation(datum);
719 auto datum = safe_any_cast_or_throw<Datum<Kakshya::RegionGroup>>(input);
720 auto op = std::make_shared<SortOp>();
722 return op->apply_operation(datum);
734 auto matrix = std::make_shared<GranularMatrix>();
736 matrix->create_operation<
SegmentOp>(
"segment");
737 matrix->create_operation<
AttributeOp>(
"attribute");
738 matrix->create_operation<
SortOp>(
"sort");
740 matrix->get_grammar()->create_rule(
"segment")
743 .with_description(
"Fixed hop-size grain segmentation")
748 matrix->get_grammar()->create_rule(
"attribute")
749 .with_context(attribution_context)
751 .with_description(
"Per-grain feature attribution via analyzer or lambda")
756 matrix->get_grammar()->create_rule(
"sort")
759 .with_description(
"Attribute-keyed grain sort, CPU or GPU")
765 matrix->get_grammar()->create_rule(
"reconstruct")
768 .with_description(
"Stitch sorted grains into a SoundFileContainer")
774 [t = std::move(taper)](
const std::any& in,
const ExecutionContext& ctx) -> std::any {
782 matrix->get_grammar()->create_rule(
"reconstruct")
785 .with_description(
"Additive grain reconstruction into SoundFileContainer")
787 .executes(ola_executor)
790 matrix->get_grammar()->create_rule(
"reconstruct")
793 .with_description(
"Stitch sorted grains into a DynamicSoundStream")
799 [t = std::move(taper)](
const std::any& in,
const ExecutionContext& ctx) -> std::any {
806 matrix->get_grammar()->create_rule(
"reconstruct")
809 .with_description(
"Additive grain reconstruction into DynamicSoundStream")
811 .executes(ola_executor)
823 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
826 const std::string& qualifier)
832 auto seg_op = matrix->get_operation<
SegmentOp>(
"segment");
833 auto attr_op = matrix->get_operation<
AttributeOp>(
"attribute");
834 auto sort_op = matrix->get_operation<
SortOp>(
"sort");
840 .template then<SegmentOp>(
"segment")
841 .template then<AttributeOp>(
"attribute")
842 .template then<SortOp>(
"sort")
851 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
859 auto seg_op = matrix->get_operation<
SegmentOp>(
"segment");
860 auto attr_op = matrix->get_operation<
AttributeOp>(
"attribute");
861 auto sort_op = matrix->get_operation<
SortOp>(
"sort");
867 .template then<SegmentOp>(
"segment")
868 .template then<AttributeOp>(
"attribute")
869 .template then<SortOp>(
"sort")
878 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
881 const std::string& qualifier,
885 ctx.execution_metadata[
"container"] = container;
888 output, config.
taper);
896 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
902 ctx.execution_metadata[
"container"] = container;
905 output, config.
taper);
913 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
916 const std::string& qualifier,
920 ctx.execution_metadata[
"container"] = container;
923 output, config.
taper);
931 const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
937 ctx.execution_metadata[
"container"] = container;
940 output, config.
taper);
output_type apply_operation(const input_type &input)
Public synchronous execution interface.
EnergyAnalysis analyze_energy(const input_type &data)
Type-safe energy analysis method.
VariantEnergyAnalyzer m_energy_analyzer
static double extract_scalar(const std::any &analysis_result, AnalysisType type, const std::string &qualifier)
Extract a named scalar from a typed analysis result.
Datum< Kakshya::RegionGroup > analyze_implementation(const Datum< Kakshya::RegionGroup > &input) override
double compute_grain_attribute(const Kakshya::Region &grain, const std::shared_ptr< Kakshya::SignalSourceContainer > &container, uint32_t channel, const ExecutionContext &ctx) const
Resolve and execute attribution for a single grain.
VariantStatisticalAnalyzer m_stat_analyzer
static std::shared_ptr< RegionGroupAnalyzer< Kakshya::RegionGroup > > make_default_analyzer(AnalysisType type)
Construct a default-configured analyzer for the given AnalysisType.
Computes a scalar attribute per grain and writes it onto each Region.
Datum< Kakshya::RegionGroup > extract_implementation(const Datum< Kakshya::RegionGroup > &input) override
Segments container audio into fixed hop-size grain windows.
Datum< Kakshya::RegionGroup > sort_implementation(const Datum< Kakshya::RegionGroup > &input) override
Sorts grains by a named attribute key, with optional GPU dispatch.
Concrete GpuExecutionContext for a single fixed shader with fixed bindings.
StatisticalAnalysis analyze_statistics(const input_type &data)
Type-safe statistical analysis method.
std::any get_parameter(const std::string &name) const override
Retrieves a parameter's current value.
virtual std::map< std::string, std::any > get_all_analysis_parameters() const
@ ComputeMatrix
Compute operations (Yantra - algorithms, matrices, DSP)
@ Yantra
DSP algorithms, computational units, matrix operations, Grammar.
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.
std::shared_ptr< SoundFileContainer > make_sound_file_container(std::vector< std::vector< double > > channel_data, uint32_t num_channels, uint32_t sample_rate, OrganizationStrategy org)
Construct a fully populated SoundFileContainer from computed channel data.
void iterate_region_channels(const std::vector< Region > ®ions, const std::shared_ptr< SignalSourceContainer > &source, uint32_t num_channels, const RegionTaper &taper, const RegionWriteFn &write_fn)
Iterate over a set of regions, extracting per-channel samples and dispatching them to a write callbac...
std::vector< double > extract_region_channel(const Region ®ion, const std::shared_ptr< SignalSourceContainer > &container, uint32_t channel)
Extract samples for a single channel within a Region from a container.
const ComputationGrammar::Rule::Executor sort_grains
Grammar rule executor for the sort step.
const ComputationGrammar::Rule::Executor reconstruct_grains_stream
Grammar rule executor — concatenative reconstruct into DynamicSoundStream.
const ComputationGrammar::Rule::Executor attribute_grains
Grammar rule executor for the attribution step.
GranularOutput
Selects the terminal output type produced by make_granular_matrix.
std::function< double(std::span< const double >, const ExecutionContext &)> AttributeExecutor
Span-level escape hatch for fully custom per-grain feature computation.
ExecutionContext make_granular_context(const GranularConfig &config, AnalysisType analysis_type, const std::string &qualifier={})
Construct an ExecutionContext for the granular pipeline using a built-in AnalysisType.
GranularDatum make_granular_input(const std::shared_ptr< Kakshya::SignalSourceContainer > &container, const std::string &group_name="grains")
Construct the initial GranularDatum from a container.
std::shared_ptr< GranularMatrix > make_granular_matrix(ComputationContext attribution_context, GranularOutput output, GrainTaper taper)
Construct a GranularMatrix with grammar rules appropriate for the requested output type.
const ComputationGrammar::Rule::Executor segment_grains
Grammar rule executor for the segmentation step.
const ComputationGrammar::Rule::Executor reconstruct_grains_additive_stream
Grammar rule executor — OLA reconstruct into DynamicSoundStream.
Kakshya::RegionTaper GrainTaper
Per-grain taper applied before accumulation in OLA reconstruction.
GranularDatum process(const std::shared_ptr< Kakshya::SignalSourceContainer > &container, AnalysisType analysis_type, const GranularConfig &config, const std::string &qualifier)
Run segment -> attribute -> sort and return the attributed RegionGroup.
const ComputationGrammar::Rule::Executor reconstruct_grains_additive
Grammar rule executor for additive grain reconstruction.
std::shared_ptr< Kakshya::SoundFileContainer > process_to_container(const std::shared_ptr< Kakshya::SignalSourceContainer > &container, AnalysisType analysis_type, const GranularConfig &config, const std::string &qualifier, GranularOutput output)
Offline granular pipeline terminating in a SoundFileContainer.
const ComputationGrammar::Rule::Executor reconstruct_grains
Grammar rule executor for the reconstruction step.
std::shared_ptr< Kakshya::DynamicSoundStream > process_to_stream(const std::shared_ptr< Kakshya::SignalSourceContainer > &container, AnalysisType analysis_type, const GranularConfig &config, const std::string &qualifier, GranularOutput output)
Offline granular pipeline terminating in a DynamicSoundStream.
AnalysisType
Categories of analysis operations for discovery and organization.
@ FEATURE
Feature extraction and characterization.
@ STATISTICAL
Mean, variance, distribution analysis.
MAYAFLUX_API double extract_scalar_energy(const EnergyAnalysis &analysis, const std::string &qualifier)
Extract a named scalar from an EnergyAnalysis result.
void apply_context_parameters(std::shared_ptr< OperationType > operation, const ExecutionContext &ctx)
Applies context parameters to an operation.
ComputationContext
Defines the computational contexts in which rules can be applied.
@ STRUCTURAL
Graph/tree operations.
@ TEMPORAL
Time-domain operations.
MAYAFLUX_API double extract_scalar_statistics(const StatisticalAnalysis &analysis, const std::string &qualifier)
Extract a named scalar from a StatisticalAnalysis result.
Organizes related signal regions into a categorized collection.
void set_attribute(const std::string &key, std::any value)
Set an attribute value by key.
Represents a point or span in N-dimensional space.
std::function< std::any(const std::any &, const ExecutionContext &)> Executor
Type alias for matcher functions used in computation rules.
T data
The actual computation data.
std::optional< std::shared_ptr< Kakshya::SignalSourceContainer > > container
Optional reference to container, required for regions.
Input/Output container for computation pipeline data flow with structure preservation.
std::unordered_map< std::string, std::any > execution_metadata
Arbitrary metadata parameters used by operations.
Context information controlling how a compute operation executes.
Plain-data description of the compute shader to dispatch.
ComputationContext attribution_context
Scalar parameters shared across all granular pipeline entry points.