MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NDData.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <glm/glm.hpp>
4
5#include "GpuDataFormat.hpp"
6
7#include "typeindex"
8
9namespace MayaFlux::Kakshya {
10
11namespace detail {
12
13 template <typename V>
15
16 template <typename... Vecs>
17 struct span_const_from_vector_variant<std::variant<Vecs...>> {
18 using type = std::variant<std::span<const typename Vecs::value_type>...>;
19 };
20
21} // namespace detail
22
23/**
24 * @brief Memory layout for multi-dimensional data.
25 *
26 * Specifies how multi-dimensional data is mapped to linear memory.
27 * - ROW_MAJOR: Last dimension varies fastest (C/C++ style).
28 * - COLUMN_MAJOR: First dimension varies fastest (Fortran/MATLAB style).
29 *
30 * This abstraction enables flexible, efficient access patterns for
31 * digital-first, data-driven workflows, unconstrained by analog conventions.
32 */
33enum class MemoryLayout : uint8_t {
34 ROW_MAJOR, ///< C/C++ style (last dimension varies fastest)
35 COLUMN_MAJOR ///< Fortran/MATLAB style (first dimension varies fastest)
36};
37
38/**
39 * @brief Data organization strategy for multi-channel/multi-frame data.
40 *
41 * Determines how logical units (channels, frames) are stored in memory.
42 */
43enum class OrganizationStrategy : uint8_t {
44 INTERLEAVED, ///< Single DataVariant with interleaved data (LRLRLR for stereo)
45 PLANAR, ///< Separate DataVariant per logical unit (LLL...RRR for stereo)
46 HYBRID, ///< Mixed approach based on access patterns
47 USER_DEFINED ///< Custom organization
48};
49
50/**
51 * @brief Multi-type data storage for different precision needs.
52 *
53 * DataVariant enables containers to store and expose data in the most
54 * appropriate format for the application, supporting high-precision,
55 * standard-precision, integer, and complex types. This abstraction
56 * is essential for digital-first, data-driven processing pipelines.
57 */
58using DataVariant = std::variant<
59 std::vector<double>, ///< High precision floating point
60 std::vector<float>, ///< Standard precision floating point
61 std::vector<uint8_t>, ///< 8-bit data (images, compressed audio)
62 std::vector<uint16_t>, ///< 16-bit data (CD audio, images)
63 std::vector<uint32_t>, ///< 32-bit data (high precision int)
64 std::vector<std::complex<float>>, ///< Complex data (spectral)
65 std::vector<std::complex<double>>, ///< High precision complex
66 std::vector<glm::vec2>, ///< 2D vector data
67 std::vector<glm::vec3>, ///< 3D vector data
68 std::vector<glm::vec4>, ///< 4D vector data
69 std::vector<glm::mat4> ///< 4x4 matrix data
70 >;
71
72/**
73 * @brief Type traits to determine if a type is a valid DataVariant element.
74 *
75 * This trait is used to constrain template functions that operate on DataVariant types,
76 * ensuring that only supported data types are used in the context of NDData containers.
77 */
78template <typename T>
79struct is_data_variant_element : std::false_type { };
80
81/** high precision floating point data (double) (audio) */
82template <>
83struct is_data_variant_element<double> : std::true_type { };
84
85/** standard precision floating point data (float) (params) */
86template <>
87struct is_data_variant_element<float> : std::true_type { };
88
89/** 8-bit unsigned integer data (uint8_t) (images, compressed audio) */
90template <>
91struct is_data_variant_element<uint8_t> : std::true_type { };
92
93/** 16-bit unsigned integer data (uint16_t) (CD audio, images) */
94template <>
95struct is_data_variant_element<uint16_t> : std::true_type { };
96
97/** 32-bit unsigned integer data (uint32_t) (high precision int) */
98template <>
99struct is_data_variant_element<uint32_t> : std::true_type { };
100
101/** complex data (spectral) */
102template <>
103struct is_data_variant_element<std::complex<float>> : std::true_type { };
104
105/** high precision complex data (spectral) */
106template <>
107struct is_data_variant_element<std::complex<double>> : std::true_type { };
108
109/** 2D vector data (glm::vec2) */
110template <>
111struct is_data_variant_element<glm::vec2> : std::true_type { };
112
113/** 3D vector data (glm::vec3) */
114template <>
115struct is_data_variant_element<glm::vec3> : std::true_type { };
116
117/** 4D vector data (glm::vec4) */
118template <>
119struct is_data_variant_element<glm::vec4> : std::true_type { };
120
121/** 4x4 matrix data (glm::mat4) */
122template <>
123struct is_data_variant_element<glm::mat4> : std::true_type { };
124
125/** Concept to constrain types to valid DataVariant elements */
126template <typename T>
127concept DataVariantElement = is_data_variant_element<std::remove_cvref_t<T>>::value;
128
129/**
130 * @brief Data modality types for cross-modal analysis
131 */
132enum class DataModality : uint8_t {
133 AUDIO_1D, ///< 1D audio signal
134 AUDIO_MULTICHANNEL, ///< Multi-channel audio
135 IMAGE_2D, ///< 2D image (grayscale or single channel)
136 IMAGE_COLOR, ///< 2D RGB/RGBA image
137 IMAGE_COLOR_ARRAY, ///< 4D (idx + 2D + color)
138 DEPTH_MAP, ///< [height, width, components] - range/disparity image
139 VIDEO_GRAYSCALE, ///< 3D video (time + 2D grayscale)
140 VIDEO_COLOR, ///< 4D video (time + 2D + color)
141 VIDEO_DEPTH, ///< [frames, height, width, components] - streaming range data
142 TEXTURE_2D, ///< 2D texture data
143 TENSOR_ND, ///< N-dimensional tensor
144 SPECTRAL_2D, ///< 2D spectral data (time + frequency)
145 VOLUMETRIC_3D, ///< 3D volumetric data
146 VERTICES_3D, ///< 3D vertex data (positions, normals, etc.)
147 VERTEX_POSITIONS_3D, // glm::vec3 - vertex positions
148 VERTEX_NORMALS_3D, // glm::vec3 - vertex normals
149 VERTEX_TANGENTS_3D, // glm::vec3 - tangent vectors
150 VERTEX_COLORS_RGB, // glm::vec3 - RGB colors
151 VERTEX_COLORS_RGBA, // glm::vec4 - RGBA colors
152 TEXTURE_COORDS_2D, // glm::vec2 - UV coordinates
153 TRANSFORMATION_MATRIX, // glm::mat4 - transform matrices
154 SCALAR_F32, ///< Single-channel float data
155 UNKNOWN ///< Unknown or undefined modality
156};
157
158/**
159 * @brief Convert DataModality enum to string representation.
160 * @param modality DataModality value
161 * @return String view of the modality name
162 */
163MAYAFLUX_API std::string_view modality_to_string(DataModality modality);
164
165/**
166 * @brief Check if a modality represents structured data (vectors, matrices).
167 * @param modality DataModality value
168 * @return True if structured, false otherwise
169 */
171{
172 switch (modality) {
180 return true;
181 default:
182 return false;
183 }
184}
185
186/**
187 * @brief Minimal dimension descriptor focusing on structure only.
188 *
189 * DataDimension describes a single axis of an N-dimensional dataset,
190 * providing semantic hints (such as TIME, CHANNEL, SPATIAL_X, etc.)
191 * and structural information (name, size, stride).
192 *
193 * This abstraction enables containers to describe arbitrary data
194 * organizations, supporting digital-first, data-driven processing
195 * without imposing analog metaphors (e.g., "track", "tape", etc.).
196 */
197struct MAYAFLUX_API DataDimension {
198 /**
199 * @brief Semantic role of the dimension.
200 *
201 * Used to indicate the intended interpretation of the dimension,
202 * enabling generic algorithms to adapt to data structure.
203 */
204 enum class Role : uint8_t {
205 TIME, ///< Temporal progression (samples, frames, steps)
206 CHANNEL, ///< Parallel streams (audio channels, color channels)
207 SPATIAL_X, ///< Spatial X axis (images, tensors)
208 SPATIAL_Y, ///< Spatial Y axis
209 SPATIAL_Z, ///< Spatial Z axis
210 FREQUENCY, ///< Spectral/frequency axis
211 POSITION, ///< Vertex positions (3D space)
212 NORMAL, ///< Surface normals
213 TANGENT, ///< Tangent vectors
214 BITANGENT, ///< Bitangent vectors
215 UV, ///< Texture coordinates
216 COLOR, ///< Color data (RGB/RGBA)
217 DEPTH, ///< Distance from the observation point (depth, disparity, range)
218 INDEX, ///< Index buffer data
219 MIP_LEVEL, ///< Mipmap levels
220 CUSTOM ///< User-defined or application-specific
221 };
222
223 /**
224 * @brief Grouping information for sub-dimensions.
225 *
226 * Used to indicate that this dimension is composed of groups
227 * of sub-dimensions (e.g., color channels grouped per pixel).
228 */
230 uint8_t count;
231 uint8_t offset;
232
234 : count(0)
235 , offset(0)
236 {
237 }
238 ComponentGroup(uint8_t c, uint8_t o = 0)
239 : count(c)
240 , offset(o)
241 {
242 }
243 };
244
245 std::optional<ComponentGroup> grouping;
246
247 /**
248 * @brief Numeric interpretation of the values along this dimension.
249 *
250 * Size and stride describe how many numbers there are and where they sit.
251 * This describes what they mean: the span that maps onto [0, 1] under
252 * normalisation, and the raw value marking an absent reading.
253 *
254 * Absent for dimensions whose values are already normalised or whose
255 * range is implied by the storage type.
256 */
257 struct ValueRange {
258 double min {};
259 double max {};
260 std::optional<double> invalid;
261 };
262
263 std::optional<ValueRange> value_range;
264
265 std::string name; ///< Human-readable identifier for the dimension
266 uint64_t size {}; ///< Number of elements in this dimension
267 uint64_t stride {}; ///< Memory stride (elements between consecutive indices)
268 Role role = Role::CUSTOM; ///< Semantic hint for common operations
269
270 DataDimension() = default;
271
272 /**
273 * @brief Construct a dimension descriptor.
274 * @param n Name of the dimension
275 * @param s Size (number of elements)
276 * @param st Stride (default: 1)
277 * @param r Semantic role (default: CUSTOM)
278 */
279 DataDimension(std::string n, uint64_t s, uint64_t st = 1, Role r = Role::CUSTOM);
280
281 /**
282 * @brief Convenience constructor for a temporal (time) dimension.
283 * @param samples Number of samples/frames
284 * @param name Optional name (default: "time")
285 * @return DataDimension representing time
286 */
287 static DataDimension time(uint64_t samples, std::string name = "time");
288
289 /**
290 * @brief Convenience constructor for a channel dimension.
291 * @param count Number of channels
292 * @param stride Memory stride (default: 1)
293 * @return DataDimension representing channels
294 */
295 static DataDimension channel(uint64_t count, uint64_t stride = 1);
296
297 /**
298 * @brief Convenience constructor for a depth dimension.
299 *
300 * The component axis of a range image. Size is the number of values per
301 * pixel: 1 for plain depth, 2 for depth paired with confidence.
302 *
303 * Carries no numeric interpretation by itself. Chain with_range() to
304 * declare the span and invalid marker, since raw depth is rarely in [0, 1].
305 *
306 * @param count Components per pixel.
307 * @param stride Memory stride (default: 1).
308 * @return DataDimension representing depth components.
309 */
310 static DataDimension depth(uint64_t count = 1, uint64_t stride = 1);
311
312 /**
313 * @brief Convenience constructor for a frequency dimension.
314 * @param bins Number of frequency bins
315 * @param name Optional name (default: "frequency")
316 * @return DataDimension representing frequency
317 */
318 static DataDimension frequency(uint64_t bins, std::string name = "frequency");
319
320 /**
321 * @brief Convenience constructor for a spatial dimension.
322 * @param size Number of elements along this axis
323 * @param axis Axis character ('x', 'y', or 'z')
324 * @param stride Memory stride (default: 1)
325 * @param name Optional name (default: "pixels")
326 * @return DataDimension representing a spatial axis
327 */
328 static DataDimension spatial(uint64_t size, char axis, uint64_t stride = 1, std::string name = "spatial");
329
330 /**
331 * @brief Convenience constructor for an array dimension.
332 * @param count Number of array elements
333 * @param name Optional name (default: "array")
334 * @return DataDimension representing an array
335 */
336 static DataDimension spatial_1d(uint64_t width);
337
338 /**
339 * @brief Convenience constructor for a 2D spatial dimension.
340 * @param width Width in elements
341 * @param height Height in elements
342 * @return DataDimension representing 2D spatial data
343 */
344 static DataDimension spatial_2d(uint64_t width, uint64_t height);
345
346 /**
347 * @brief Convenience constructor for a 3D spatial dimension.
348 * @param width Width in elements
349 * @param height Height in elements
350 * @param depth Depth in elements
351 * @return DataDimension representing 3D spatial data
352 */
353 static DataDimension spatial_3d(uint64_t width, uint64_t height, uint64_t depth);
354
355 /**
356 * @brief Create dimension with component grouping
357 * @param name Dimension name
358 * @param element_count Number of elements (not components)
359 * @param components_per_element Components per element (e.g., 3 for vec3)
360 * @param role Semantic role
361 */
362 static DataDimension grouped(std::string name, uint64_t element_count, uint8_t components_per_element, Role role = Role::CUSTOM);
363
364 /**
365 * @brief Attach a value range. Chainable.
366 * @param min Value mapping to 0.0.
367 * @param max Value mapping to 1.0. Must exceed min.
368 * @param invalid Raw value marking an absent reading.
369 */
370 DataDimension& with_range(double min, double max, std::optional<double> invalid = std::nullopt);
371
372 /**
373 * @brief Create dimension for vertex positions (vec3)
374 */
375 static DataDimension vertex_positions(uint64_t count);
376
377 /**
378 * @brief Create dimension for vertex normals (vec3)
379 */
380 static DataDimension vertex_normals(uint64_t count);
381
382 /**
383 * @brief Create dimension for texture coordinates (vec2)
384 */
385 static DataDimension texture_coords(uint64_t count);
386
387 /**
388 * @brief Create dimension for colors (vec3 or vec4)
389 */
390 static DataDimension vertex_colors(uint64_t count, bool has_alpha = false);
391
392 /**
393 * @brief Create dimension for mipmap levels.
394 */
395 static DataDimension mipmap_levels(uint64_t levels);
396
397 /**
398 * @brief Data container combining variants and dimensions.
399 */
400 using DataModule = std::pair<std::vector<DataVariant>, std::vector<DataDimension>>;
401
402 /**
403 * @brief Create data module for a specific modality.
404 * @tparam T Data type for storage
405 * @param modality Target data modality
406 * @param shape Dimensional sizes
407 * @param default_value Initial value for elements
408 * @param layout Memory layout strategy
409 * @param strategy Organization strategy
410 * @return DataModule with appropriate structure
411 */
412 template <typename T>
414 DataModality modality,
415 const std::vector<uint64_t>& shape,
416 T default_value = T {},
417 MemoryLayout layout = MemoryLayout::ROW_MAJOR,
418 OrganizationStrategy strategy = OrganizationStrategy::PLANAR)
419 {
420 auto dims = create_dimensions(modality, shape, layout);
421 auto variants = create_variants(modality, shape, default_value, strategy);
422
423 return { std::move(variants), std::move(dims) };
424 }
425
426 /**
427 * @brief Create dimension descriptors for a data modality.
428 * @param modality Target data modality
429 * @param shape Dimensional sizes
430 * @param layout Memory layout strategy
431 * @return Vector of DataDimension objects
432 */
433 static std::vector<DataDimension> create_dimensions(
434 DataModality modality,
435 const std::vector<uint64_t>& shape,
436 MemoryLayout layout = MemoryLayout::ROW_MAJOR);
437
438 /**
439 * @brief Create 1D audio data module.
440 * @tparam T Data type for storage
441 * @param samples Number of audio samples
442 * @param default_value Initial value for elements
443 * @return DataModule for 1D audio
444 */
445 template <typename T>
446 static DataModule create_audio_1d(uint64_t samples, T default_value = T {})
447 {
448 return create_for_modality(DataModality::AUDIO_1D, { samples }, default_value);
449 }
450
451 /**
452 * @brief Create multi-channel audio data module.
453 * @tparam T Data type for storage
454 * @param samples Number of audio samples
455 * @param channels Number of audio channels
456 * @param default_value Initial value for elements
457 * @return DataModule for multi-channel audio
458 */
459 template <typename T>
460 static DataModule create_audio_multichannel(uint64_t samples, uint64_t channels, T default_value = T {})
461 {
462 return create_for_modality(DataModality::AUDIO_MULTICHANNEL, { samples, channels }, default_value);
463 }
464
465 /**
466 * @brief Create 2D image data module.
467 * @tparam T Data type for storage
468 * @param height Image height in pixels
469 * @param width Image width in pixels
470 * @param default_value Initial value for elements
471 * @return DataModule for 2D image
472 */
473 template <typename T>
474 static DataModule create_image_2d(uint64_t height, uint64_t width, T default_value = T {})
475 {
476 return create_for_modality(DataModality::IMAGE_2D, { height, width }, default_value);
477 }
478
479 /**
480 * @brief Create 2D spectral data module.
481 * @tparam T Data type for storage
482 * @param time_windows Number of time windows
483 * @param frequency_bins Number of frequency bins
484 * @param default_value Initial value for elements
485 * @return DataModule for spectral data
486 */
487 template <typename T>
488 static DataModule create_spectral_2d(uint64_t time_windows, uint64_t frequency_bins, T default_value = T {})
489 {
490 return create_for_modality(DataModality::SPECTRAL_2D, { time_windows, frequency_bins }, default_value);
491 }
492
493 /**
494 * @brief Calculate memory strides based on shape and layout.
495 * @param shape Dimensional sizes
496 * @param layout Memory layout strategy
497 * @return Vector of stride values for each dimension
498 */
499 static std::vector<uint64_t> calculate_strides(
500 const std::vector<uint64_t>& shape,
501 MemoryLayout layout);
502
503private:
504 /**
505 * @brief Create data variants for a specific modality.
506 * @tparam T Data type for storage
507 * @param modality Target data modality
508 * @param shape Dimensional sizes
509 * @param default_value Initial value for elements
510 * @param org Organization strategy
511 * @return Vector of DataVariant objects
512 */
513 template <typename T>
514 static std::vector<DataVariant> create_variants(
515 DataModality modality,
516 const std::vector<uint64_t>& shape,
517 T default_value,
518 OrganizationStrategy org = OrganizationStrategy::PLANAR)
519 {
520 std::vector<DataVariant> variants;
521
522 if (org == OrganizationStrategy::INTERLEAVED) {
523 uint64_t total = std::accumulate(shape.begin(), shape.end(), uint64_t(1), std::multiplies<>());
524 variants.emplace_back(std::vector<T>(total, default_value));
525 return variants;
526 }
527
528 switch (modality) {
529 case DataModality::AUDIO_1D:
530 variants.emplace_back(std::vector<T>(shape[0], default_value));
531 break;
532
533 case DataModality::AUDIO_MULTICHANNEL: {
534 uint64_t samples = shape[0];
535 uint64_t channels = shape[1];
536 variants.reserve(channels);
537 for (uint64_t ch = 0; ch < channels; ++ch) {
538 variants.emplace_back(std::vector<T>(samples, default_value));
539 }
540 break;
541 }
542
543 case DataModality::IMAGE_2D:
544 variants.emplace_back(std::vector<T>(shape[0] * shape[1], default_value));
545 break;
546
547 case DataModality::IMAGE_COLOR: {
548 uint64_t height = shape[0];
549 uint64_t width = shape[1];
550 uint64_t channels = shape[2];
551 uint64_t pixels = height * width;
552 variants.reserve(channels);
553 for (uint64_t ch = 0; ch < channels; ++ch) {
554 variants.emplace_back(std::vector<T>(pixels, default_value));
555 }
556 break;
557 }
558
559 case DataModality::DEPTH_MAP: {
560 uint64_t pixels = shape[0] * shape[1];
561 uint64_t components = shape[2];
562 variants.reserve(components);
563 for (uint64_t c = 0; c < components; ++c) {
564 variants.emplace_back(std::vector<T>(pixels, default_value));
565 }
566 break;
567 }
568
569 case DataModality::SPECTRAL_2D:
570 variants.emplace_back(std::vector<T>(shape[0] * shape[1], default_value));
571 break;
572
573 case DataModality::VOLUMETRIC_3D:
574 variants.emplace_back(std::vector<T>(shape[0] * shape[1] * shape[2], default_value));
575 break;
576
577 case DataModality::VIDEO_GRAYSCALE: {
578 uint64_t frames = shape[0];
579 uint64_t height = shape[1];
580 uint64_t width = shape[2];
581 uint64_t frame_size = height * width;
582 variants.reserve(frames);
583 for (uint64_t f = 0; f < frames; ++f) {
584 variants.emplace_back(std::vector<T>(frame_size, default_value));
585 }
586 break;
587 }
588
589 case DataModality::VIDEO_COLOR: {
590 uint64_t frames = shape[0];
591 uint64_t height = shape[1];
592 uint64_t width = shape[2];
593 uint64_t channels = shape[3];
594 uint64_t frame_size = height * width;
595 variants.reserve(frames * channels);
596 for (uint64_t f = 0; f < frames; ++f) {
597 for (uint64_t ch = 0; ch < channels; ++ch) {
598 variants.emplace_back(std::vector<T>(frame_size, default_value));
599 }
600 }
601 break;
602 }
603
604 case DataModality::VIDEO_DEPTH: {
605 uint64_t frames = shape[0];
606 uint64_t pixels = shape[1] * shape[2];
607 uint64_t components = shape[3];
608 variants.reserve(components);
609 for (uint64_t c = 0; c < components; ++c) {
610 variants.emplace_back(std::vector<T>(frames * pixels, default_value));
611 }
612 break;
613 }
614
615 default:
616 uint64_t total = std::accumulate(shape.begin(), shape.end(), uint64_t(1), std::multiplies<>());
617 variants.emplace_back(std::vector<T>(total, default_value));
618 break;
619 }
620
621 return variants;
622 }
623};
624
626
627/**
628 * @class FrameView
629 * @brief Zero-copy typed view over one frame of container storage.
630 *
631 * FrameView is the return type of NDDataContainer::get_frame(). It holds a
632 * DataSpanVariant — a span into the container's live storage — without copying
633 * or converting data. The active span alternative matches the container's native
634 * element type: uint8_t for 8-bit image and video, uint16_t for 16-bit image,
635 * float for HDR image, double for audio.
636 *
637 * Callers retrieve typed data via as(), which returns an empty span on type
638 * mismatch rather than throwing. element_type() provides a runtime query for
639 * callers whose branch depends on the native type.
640 *
641 * @par Lifetime
642 * The span inside FrameView points directly into the owning container's internal
643 * buffer. It is valid only for the duration of the current processing turn.
644 * FrameView must not be stored across buffer cycles, frame callbacks, or any
645 * point at which the container may write new data.
646 *
647 * @par Threading
648 * FrameView is not thread-safe. The container's read lock (if any) is held only
649 * during get_frame_span_impl(); it is released before FrameView is returned.
650 * Callers must not access the view concurrently with container writes.
651 *
652 * @see NDDataContainer::get_frame(), DataSpanVariant, DataVariantElement
653 */
655public:
656 /** @brief Construct an empty FrameView. empty() returns true. */
657 FrameView() = default;
658
659 /**
660 * @brief Construct from a DataSpanVariant produced by get_frame_span_impl().
661 * @param span Active alternative must match the container's native element type.
662 */
664 : m_span(span)
665 {
666 }
667
668 /** @brief Returns true if the view holds no elements. */
669 [[nodiscard]] bool empty() const
670 {
671 return std::visit([](const auto& s) { return s.empty(); }, m_span);
672 }
673
674 /** @brief Number of elements in the frame, in units of the native element type. */
675 [[nodiscard]] size_t size() const
676 {
677 return std::visit([](const auto& s) { return s.size(); }, m_span);
678 }
679
680 /**
681 * @brief Runtime query for the native element type of this frame.
682 *
683 * Returns std::type_index of the active span's value_type. Typical values:
684 * - typeid(uint8_t) — 8-bit image/video (RGBA, etc.)
685 * - typeid(uint16_t) — 16-bit image (UNORM or half-float encoded)
686 * - typeid(float) — HDR image (R32F/RGBA32F)
687 * - typeid(double) — audio
688 *
689 * Use this to branch once before calling as<T>() when the container type
690 * is not statically known at the call site.
691 */
692 [[nodiscard]] std::type_index element_type() const
693 {
694 return std::visit([](const auto& s) {
695 return std::type_index(typeid(typename std::decay_t<decltype(s)>::value_type));
696 },
697 m_span);
698 }
699
700 /**
701 * @brief Return a typed span over the frame data without conversion.
702 *
703 * Returns an empty span if T does not match the native element type.
704 * Callers should query element_type() first when the type is not statically known.
705 * The returned span is valid only for the lifetime of the owning container's frame buffer.
706 *
707 * @tparam T Element type. Must satisfy DataVariantElement.
708 * @return Span of const T, empty on type mismatch.
709 */
710 /**
711 * @brief Return a typed span over the frame data without conversion or allocation.
712 *
713 * Returns an empty span if T does not match the native element type.
714 * No exception is thrown on mismatch; check empty() or call element_type() first
715 * when the container type is not statically known.
716 *
717 * The returned span aliases the container's internal buffer directly.
718 * See class-level lifetime and threading notes.
719 *
720 * @tparam T Element type. Must satisfy DataVariantElement.
721 * @return Span of const T into live storage, empty on type mismatch.
722 */
723 template <DataVariantElement T>
724 [[nodiscard]] std::span<const T> as() const
725 {
726 const auto* s = std::get_if<std::span<const T>>(&m_span);
727 return s ? *s : std::span<const T> {};
728 }
729
730 /**
731 * @brief Direct access to the underlying DataSpanVariant for internal use.
732 *
733 * Intended for infrastructure (processors, Yantra pipeline) that must
734 * forward the view without branching on type. Not for general callers.
735 */
736 [[nodiscard]] const DataSpanVariant& raw() const { return m_span; }
737
738private:
740};
741
742} // namespace MayaFlux::Kakshya
uint64_t offset
Definition Composite.cpp:10
const std::vector< float > * pixels
Definition Decoder.cpp:48
bool size
uint32_t total
double frequency
glm::ivec3 min
glm::ivec3 max
glm::vec3 value
std::string name
Definition VKDevice.cpp:123
size_t count
uint32_t channels
uint32_t width
uint32_t height
uint32_t depth
FrameView()=default
Construct an empty FrameView.
const DataSpanVariant & raw() const
Direct access to the underlying DataSpanVariant for internal use.
Definition NDData.hpp:736
std::span< const T > as() const
Return a typed span over the frame data without conversion.
Definition NDData.hpp:724
size_t size() const
Number of elements in the frame, in units of the native element type.
Definition NDData.hpp:675
std::type_index element_type() const
Runtime query for the native element type of this frame.
Definition NDData.hpp:692
FrameView(DataSpanVariant span)
Construct from a DataSpanVariant produced by get_frame_span_impl().
Definition NDData.hpp:663
bool empty() const
Returns true if the view holds no elements.
Definition NDData.hpp:669
Zero-copy typed view over one frame of container storage.
Definition NDData.hpp:654
Concept to constrain types to valid DataVariant elements.
Definition NDData.hpp:127
typename detail::span_const_from_vector_variant< DataVariant >::type DataSpanVariant
Definition NDData.hpp:625
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
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:132
@ DEPTH_MAP
[height, width, components] - range/disparity image
@ AUDIO_MULTICHANNEL
Multi-channel audio.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ VIDEO_DEPTH
[frames, height, width, components] - streaming range data
@ UNKNOWN
Unknown or undefined modality.
@ IMAGE_COLOR_ARRAY
4D (idx + 2D + color)
@ VERTICES_3D
3D vertex data (positions, normals, etc.)
@ SCALAR_F32
Single-channel float data.
@ VOLUMETRIC_3D
3D volumetric data
@ VIDEO_GRAYSCALE
3D video (time + 2D grayscale)
@ VIDEO_COLOR
4D video (time + 2D + color)
@ TENSOR_ND
N-dimensional tensor.
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
MemoryLayout
Memory layout for multi-dimensional data.
Definition NDData.hpp:33
@ ROW_MAJOR
C/C++ style (last dimension varies fastest)
@ COLUMN_MAJOR
Fortran/MATLAB style (first dimension varies fastest)
OrganizationStrategy
Data organization strategy for multi-channel/multi-frame data.
Definition NDData.hpp:43
@ HYBRID
Mixed approach based on access patterns.
@ PLANAR
Separate DataVariant per logical unit (LLL...RRR for stereo)
@ INTERLEAVED
Single DataVariant with interleaved data (LRLRLR for stereo)
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
Definition NDData.cpp:102
bool is_structured_modality(DataModality modality)
Check if a modality represents structured data (vectors, matrices).
Definition NDData.hpp:170
Grouping information for sub-dimensions.
Definition NDData.hpp:229
Numeric interpretation of the values along this dimension.
Definition NDData.hpp:257
static DataModule create_audio_multichannel(uint64_t samples, uint64_t channels, T default_value=T {})
Create multi-channel audio data module.
Definition NDData.hpp:460
std::optional< ValueRange > value_range
Definition NDData.hpp:263
Role
Semantic role of the dimension.
Definition NDData.hpp:204
static DataModule create_spectral_2d(uint64_t time_windows, uint64_t frequency_bins, T default_value=T {})
Create 2D spectral data module.
Definition NDData.hpp:488
std::string name
Human-readable identifier for the dimension.
Definition NDData.hpp:265
static DataModule create_audio_1d(uint64_t samples, T default_value=T {})
Create 1D audio data module.
Definition NDData.hpp:446
static DataModule create_image_2d(uint64_t height, uint64_t width, T default_value=T {})
Create 2D image data module.
Definition NDData.hpp:474
std::pair< std::vector< DataVariant >, std::vector< DataDimension > > DataModule
Data container combining variants and dimensions.
Definition NDData.hpp:400
static std::vector< DataVariant > create_variants(DataModality modality, const std::vector< uint64_t > &shape, T default_value, OrganizationStrategy org=OrganizationStrategy::PLANAR)
Create data variants for a specific modality.
Definition NDData.hpp:514
static DataModule create_for_modality(DataModality modality, const std::vector< uint64_t > &shape, T default_value=T {}, MemoryLayout layout=MemoryLayout::ROW_MAJOR, OrganizationStrategy strategy=OrganizationStrategy::PLANAR)
Create data module for a specific modality.
Definition NDData.hpp:413
std::optional< ComponentGroup > grouping
Definition NDData.hpp:245
Minimal dimension descriptor focusing on structure only.
Definition NDData.hpp:197
std::variant< std::span< const typename Vecs::value_type >... > type
Definition NDData.hpp:18
Type traits to determine if a type is a valid DataVariant element.
Definition NDData.hpp:79