MayaFlux 0.1.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
5namespace MayaFlux::Kakshya {
6
7/**
8 * @enum GpuDataFormat
9 * @brief GPU data formats with explicit precision levels
10 */
11enum class GpuDataFormat : uint8_t {
12 FLOAT32, // 32-bit float (standard GPU)
13 VEC2_F32, // glm::vec2 (32-bit components)
14 VEC3_F32, // glm::vec3 (32-bit components)
15 VEC4_F32, // glm::vec4 (32-bit components)
16
17 FLOAT64, // 64-bit double (audio precision)
18 VEC2_F64, // glm::dvec2 (64-bit components)
19 VEC3_F64, // glm::dvec3 (64-bit components)
20 VEC4_F64, // glm::dvec4 (64-bit components)
21
22 INT32,
23 UINT32
24};
25
26/**
27 * @brief Memory layout for multi-dimensional data.
28 *
29 * Specifies how multi-dimensional data is mapped to linear memory.
30 * - ROW_MAJOR: Last dimension varies fastest (C/C++ style).
31 * - COLUMN_MAJOR: First dimension varies fastest (Fortran/MATLAB style).
32 *
33 * This abstraction enables flexible, efficient access patterns for
34 * digital-first, data-driven workflows, unconstrained by analog conventions.
35 */
36enum class MemoryLayout : uint8_t {
37 ROW_MAJOR, ///< C/C++ style (last dimension varies fastest)
38 COLUMN_MAJOR ///< Fortran/MATLAB style (first dimension varies fastest)
39};
40
41/**
42 * @brief Data organization strategy for multi-channel/multi-frame data.
43 *
44 * Determines how logical units (channels, frames) are stored in memory.
45 */
46enum class OrganizationStrategy : uint8_t {
47 INTERLEAVED, ///< Single DataVariant with interleaved data (LRLRLR for stereo)
48 PLANAR, ///< Separate DataVariant per logical unit (LLL...RRR for stereo)
49 HYBRID, ///< Mixed approach based on access patterns
50 USER_DEFINED ///< Custom organization
51};
52
53/**
54 * @brief Multi-type data storage for different precision needs.
55 *
56 * DataVariant enables containers to store and expose data in the most
57 * appropriate format for the application, supporting high-precision,
58 * standard-precision, integer, and complex types. This abstraction
59 * is essential for digital-first, data-driven processing pipelines.
60 */
61using DataVariant = std::variant<
62 std::vector<double>, ///< High precision floating point
63 std::vector<float>, ///< Standard precision floating point
64 std::vector<uint8_t>, ///< 8-bit data (images, compressed audio)
65 std::vector<uint16_t>, ///< 16-bit data (CD audio, images)
66 std::vector<uint32_t>, ///< 32-bit data (high precision int)
67 std::vector<std::complex<float>>, ///< Complex data (spectral)
68 std::vector<std::complex<double>>, ///< High precision complex
69 std::vector<glm::vec2>, ///< 2D vector data
70 std::vector<glm::vec3>, ///< 3D vector data
71 std::vector<glm::vec4>, ///< 4D vector data
72 std::vector<glm::mat4> ///< 4x4 matrix data
73 >;
74
75/**
76 * @brief Data modality types for cross-modal analysis
77 */
78enum class DataModality : uint8_t {
79 AUDIO_1D, ///< 1D audio signal
80 AUDIO_MULTICHANNEL, ///< Multi-channel audio
81 IMAGE_2D, ///< 2D image (grayscale or single channel)
82 IMAGE_COLOR, ///< 2D RGB/RGBA image
83 VIDEO_GRAYSCALE, ///< 3D video (time + 2D grayscale)
84 VIDEO_COLOR, ///< 4D video (time + 2D + color)
85 TEXTURE_2D, ///< 2D texture data
86 TENSOR_ND, ///< N-dimensional tensor
87 SPECTRAL_2D, ///< 2D spectral data (time + frequency)
88 VOLUMETRIC_3D, ///< 3D volumetric data
89 VERTEX_POSITIONS_3D, // glm::vec3 - vertex positions
90 VERTEX_NORMALS_3D, // glm::vec3 - vertex normals
91 VERTEX_TANGENTS_3D, // glm::vec3 - tangent vectors
92 VERTEX_COLORS_RGB, // glm::vec3 - RGB colors
93 VERTEX_COLORS_RGBA, // glm::vec4 - RGBA colors
94 TEXTURE_COORDS_2D, // glm::vec2 - UV coordinates
95 TRANSFORMATION_MATRIX, // glm::mat4 - transform matrices
96 UNKNOWN ///< Unknown or undefined modality
97};
98
99/**
100 * @brief Convert DataModality enum to string representation.
101 * @param modality DataModality value
102 * @return String view of the modality name
103 */
104std::string_view modality_to_string(DataModality modality);
105
106/**
107 * @brief Check if a modality represents structured data (vectors, matrices).
108 * @param modality DataModality value
109 * @return True if structured, false otherwise
110 */
112{
113 switch (modality) {
121 return true;
122 default:
123 return false;
124 }
125}
126
127/**
128 * @brief Minimal dimension descriptor focusing on structure only.
129 *
130 * DataDimension describes a single axis of an N-dimensional dataset,
131 * providing semantic hints (such as TIME, CHANNEL, SPATIAL_X, etc.)
132 * and structural information (name, size, stride).
133 *
134 * This abstraction enables containers to describe arbitrary data
135 * organizations, supporting digital-first, data-driven processing
136 * without imposing analog metaphors (e.g., "track", "tape", etc.).
137 */
138struct MAYAFLUX_API DataDimension {
139 /**
140 * @brief Semantic role of the dimension.
141 *
142 * Used to indicate the intended interpretation of the dimension,
143 * enabling generic algorithms to adapt to data structure.
144 */
145 enum class Role : uint8_t {
146 TIME, ///< Temporal progression (samples, frames, steps)
147 CHANNEL, ///< Parallel streams (audio channels, color channels)
148 SPATIAL_X, ///< Spatial X axis (images, tensors)
149 SPATIAL_Y, ///< Spatial Y axis
150 SPATIAL_Z, ///< Spatial Z axis
151 FREQUENCY, ///< Spectral/frequency axis
152 POSITION, ///< Vertex positions (3D space)
153 NORMAL, ///< Surface normals
154 TANGENT, ///< Tangent vectors
155 BITANGENT, ///< Bitangent vectors
156 UV, ///< Texture coordinates
157 COLOR, ///< Color data (RGB/RGBA)
158 INDEX, ///< Index buffer data
159 MIP_LEVEL, ///< Mipmap levels
160 CUSTOM ///< User-defined or application-specific
161 };
162
163 /**
164 * @brief Grouping information for sub-dimensions.
165 *
166 * Used to indicate that this dimension is composed of groups
167 * of sub-dimensions (e.g., color channels grouped per pixel).
168 */
170 uint8_t count;
171 uint8_t offset;
172
174 : count(0)
175 , offset(0)
176 {
177 }
178 ComponentGroup(uint8_t c, uint8_t o = 0)
179 : count(c)
180 , offset(o)
181 {
182 }
183 };
184
185 std::optional<ComponentGroup> grouping;
186
187 std::string name; ///< Human-readable identifier for the dimension
188 uint64_t size {}; ///< Number of elements in this dimension
189 uint64_t stride {}; ///< Memory stride (elements between consecutive indices)
190 Role role = Role::CUSTOM; ///< Semantic hint for common operations
191
192 DataDimension() = default;
193
194 /**
195 * @brief Construct a dimension descriptor.
196 * @param n Name of the dimension
197 * @param s Size (number of elements)
198 * @param st Stride (default: 1)
199 * @param r Semantic role (default: CUSTOM)
200 */
201 DataDimension(std::string n, uint64_t s, uint64_t st = 1, Role r = Role::CUSTOM);
202
203 /**
204 * @brief Convenience constructor for a temporal (time) dimension.
205 * @param samples Number of samples/frames
206 * @param name Optional name (default: "time")
207 * @return DataDimension representing time
208 */
209 static DataDimension time(uint64_t samples, std::string name = "time");
210
211 /**
212 * @brief Convenience constructor for a channel dimension.
213 * @param count Number of channels
214 * @param stride Memory stride (default: 1)
215 * @return DataDimension representing channels
216 */
217 static DataDimension channel(uint64_t count, uint64_t stride = 1);
218
219 /**
220 * @brief Convenience constructor for a frequency dimension.
221 * @param bins Number of frequency bins
222 * @param name Optional name (default: "frequency")
223 * @return DataDimension representing frequency
224 */
225 static DataDimension frequency(uint64_t bins, std::string name = "frequency");
226
227 /**
228 * @brief Convenience constructor for a spatial dimension.
229 * @param size Number of elements along this axis
230 * @param axis Axis character ('x', 'y', or 'z')
231 * @param stride Memory stride (default: 1)
232 * @param name Optional name (default: "pixels")
233 * @return DataDimension representing a spatial axis
234 */
235 static DataDimension spatial(uint64_t size, char axis, uint64_t stride = 1, std::string name = "spatial");
236
237 /**
238 * @brief Convenience constructor for an array dimension.
239 * @param count Number of array elements
240 * @param name Optional name (default: "array")
241 * @return DataDimension representing an array
242 */
243 static DataDimension spatial_1d(uint64_t width);
244
245 /**
246 * @brief Convenience constructor for a 2D spatial dimension.
247 * @param width Width in elements
248 * @param height Height in elements
249 * @return DataDimension representing 2D spatial data
250 */
251 static DataDimension spatial_2d(uint64_t width, uint64_t height);
252
253 /**
254 * @brief Convenience constructor for a 3D spatial dimension.
255 * @param width Width in elements
256 * @param height Height in elements
257 * @param depth Depth in elements
258 * @return DataDimension representing 3D spatial data
259 */
260 static DataDimension spatial_3d(uint64_t width, uint64_t height, uint64_t depth);
261
262 /**
263 * @brief Create dimension with component grouping
264 * @param name Dimension name
265 * @param element_count Number of elements (not components)
266 * @param components_per_element Components per element (e.g., 3 for vec3)
267 * @param role Semantic role
268 */
269 static DataDimension grouped(std::string name, uint64_t element_count, uint8_t components_per_element, Role role = Role::CUSTOM);
270
271 /**
272 * @brief Create dimension for vertex positions (vec3)
273 */
274 static DataDimension vertex_positions(uint64_t count);
275
276 /**
277 * @brief Create dimension for vertex normals (vec3)
278 */
279 static DataDimension vertex_normals(uint64_t count);
280
281 /**
282 * @brief Create dimension for texture coordinates (vec2)
283 */
284 static DataDimension texture_coords(uint64_t count);
285
286 /**
287 * @brief Create dimension for colors (vec3 or vec4)
288 */
289 static DataDimension vertex_colors(uint64_t count, bool has_alpha = false);
290
291 /**
292 * @brief Create dimension for mipmap levels.
293 */
294 static DataDimension mipmap_levels(uint64_t levels);
295
296 /**
297 * @brief Data container combining variants and dimensions.
298 */
299 using DataModule = std::pair<std::vector<DataVariant>, std::vector<DataDimension>>;
300
301 /**
302 * @brief Create data module for a specific modality.
303 * @tparam T Data type for storage
304 * @param modality Target data modality
305 * @param shape Dimensional sizes
306 * @param default_value Initial value for elements
307 * @param layout Memory layout strategy
308 * @param strategy Organization strategy
309 * @return DataModule with appropriate structure
310 */
311 template <typename T>
313 DataModality modality,
314 const std::vector<uint64_t>& shape,
315 T default_value = T {},
316 MemoryLayout layout = MemoryLayout::ROW_MAJOR,
317 OrganizationStrategy strategy = OrganizationStrategy::PLANAR)
318 {
319 auto dims = create_dimensions(modality, shape, layout);
320 auto variants = create_variants(modality, shape, default_value, strategy);
321
322 return { std::move(variants), std::move(dims) };
323 }
324
325 /**
326 * @brief Create dimension descriptors for a data modality.
327 * @param modality Target data modality
328 * @param shape Dimensional sizes
329 * @param layout Memory layout strategy
330 * @return Vector of DataDimension objects
331 */
332 static std::vector<DataDimension> create_dimensions(
333 DataModality modality,
334 const std::vector<uint64_t>& shape,
335 MemoryLayout layout = MemoryLayout::ROW_MAJOR);
336
337 /**
338 * @brief Create 1D audio data module.
339 * @tparam T Data type for storage
340 * @param samples Number of audio samples
341 * @param default_value Initial value for elements
342 * @return DataModule for 1D audio
343 */
344 template <typename T>
345 static DataModule create_audio_1d(uint64_t samples, T default_value = T {})
346 {
347 return create_for_modality(DataModality::AUDIO_1D, { samples }, default_value);
348 }
349
350 /**
351 * @brief Create multi-channel audio data module.
352 * @tparam T Data type for storage
353 * @param samples Number of audio samples
354 * @param channels Number of audio channels
355 * @param default_value Initial value for elements
356 * @return DataModule for multi-channel audio
357 */
358 template <typename T>
359 static DataModule create_audio_multichannel(uint64_t samples, uint64_t channels, T default_value = T {})
360 {
361 return create_for_modality(DataModality::AUDIO_MULTICHANNEL, { samples, channels }, default_value);
362 }
363
364 /**
365 * @brief Create 2D image data module.
366 * @tparam T Data type for storage
367 * @param height Image height in pixels
368 * @param width Image width in pixels
369 * @param default_value Initial value for elements
370 * @return DataModule for 2D image
371 */
372 template <typename T>
373 static DataModule create_image_2d(uint64_t height, uint64_t width, T default_value = T {})
374 {
375 return create_for_modality(DataModality::IMAGE_2D, { height, width }, default_value);
376 }
377
378 /**
379 * @brief Create 2D spectral data module.
380 * @tparam T Data type for storage
381 * @param time_windows Number of time windows
382 * @param frequency_bins Number of frequency bins
383 * @param default_value Initial value for elements
384 * @return DataModule for spectral data
385 */
386 template <typename T>
387 static DataModule create_spectral_2d(uint64_t time_windows, uint64_t frequency_bins, T default_value = T {})
388 {
389 return create_for_modality(DataModality::SPECTRAL_2D, { time_windows, frequency_bins }, default_value);
390 }
391
392 /**
393 * @brief Calculate memory strides based on shape and layout.
394 * @param shape Dimensional sizes
395 * @param layout Memory layout strategy
396 * @return Vector of stride values for each dimension
397 */
398 static std::vector<uint64_t> calculate_strides(
399 const std::vector<uint64_t>& shape,
400 MemoryLayout layout);
401
402private:
403 /**
404 * @brief Create data variants for a specific modality.
405 * @tparam T Data type for storage
406 * @param modality Target data modality
407 * @param shape Dimensional sizes
408 * @param default_value Initial value for elements
409 * @param org Organization strategy
410 * @return Vector of DataVariant objects
411 */
412 template <typename T>
413 static std::vector<DataVariant> create_variants(
414 DataModality modality,
415 const std::vector<uint64_t>& shape,
416 T default_value,
417 OrganizationStrategy org = OrganizationStrategy::PLANAR)
418 {
419 std::vector<DataVariant> variants;
420
421 if (org == OrganizationStrategy::INTERLEAVED) {
422 uint64_t total = std::accumulate(shape.begin(), shape.end(), uint64_t(1), std::multiplies<>());
423 variants.emplace_back(std::vector<T>(total, default_value));
424 return variants;
425 }
426
427 switch (modality) {
428 case DataModality::AUDIO_1D:
429 variants.emplace_back(std::vector<T>(shape[0], default_value));
430 break;
431
432 case DataModality::AUDIO_MULTICHANNEL: {
433 uint64_t samples = shape[0];
434 uint64_t channels = shape[1];
435 variants.reserve(channels);
436 for (uint64_t ch = 0; ch < channels; ++ch) {
437 variants.emplace_back(std::vector<T>(samples, default_value));
438 }
439 break;
440 }
441
442 case DataModality::IMAGE_2D:
443 variants.emplace_back(std::vector<T>(shape[0] * shape[1], default_value));
444 break;
445
446 case DataModality::IMAGE_COLOR: {
447 uint64_t height = shape[0];
448 uint64_t width = shape[1];
449 uint64_t channels = shape[2];
450 uint64_t pixels = height * width;
451 variants.reserve(channels);
452 for (uint64_t ch = 0; ch < channels; ++ch) {
453 variants.emplace_back(std::vector<T>(pixels, default_value));
454 }
455 break;
456 }
457
458 case DataModality::SPECTRAL_2D:
459 variants.emplace_back(std::vector<T>(shape[0] * shape[1], default_value));
460 break;
461
462 case DataModality::VOLUMETRIC_3D:
463 variants.emplace_back(std::vector<T>(shape[0] * shape[1] * shape[2], default_value));
464 break;
465
466 case DataModality::VIDEO_GRAYSCALE: {
467 uint64_t frames = shape[0];
468 uint64_t height = shape[1];
469 uint64_t width = shape[2];
470 uint64_t frame_size = height * width;
471 variants.reserve(frames);
472 for (uint64_t f = 0; f < frames; ++f) {
473 variants.emplace_back(std::vector<T>(frame_size, default_value));
474 }
475 break;
476 }
477
478 case DataModality::VIDEO_COLOR: {
479 uint64_t frames = shape[0];
480 uint64_t height = shape[1];
481 uint64_t width = shape[2];
482 uint64_t channels = shape[3];
483 uint64_t frame_size = height * width;
484 variants.reserve(frames * channels);
485 for (uint64_t f = 0; f < frames; ++f) {
486 for (uint64_t ch = 0; ch < channels; ++ch) {
487 variants.emplace_back(std::vector<T>(frame_size, default_value));
488 }
489 }
490 break;
491 }
492
493 default:
494 uint64_t total = std::accumulate(shape.begin(), shape.end(), uint64_t(1), std::multiplies<>());
495 variants.emplace_back(std::vector<T>(total, default_value));
496 break;
497 }
498
499 return variants;
500 }
501};
502
503} // namespace MayaFlux::Kakshya
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:73
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:78
@ AUDIO_MULTICHANNEL
Multi-channel audio.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ UNKNOWN
Unknown or undefined modality.
@ 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:36
@ 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:46
@ 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)
bool is_structured_modality(DataModality modality)
Check if a modality represents structured data (vectors, matrices).
Definition NDData.hpp:111
GpuDataFormat
GPU data formats with explicit precision levels.
Definition NDData.hpp:11
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
Definition NDData.cpp:80
Grouping information for sub-dimensions.
Definition NDData.hpp:169
static DataModule create_audio_multichannel(uint64_t samples, uint64_t channels, T default_value=T {})
Create multi-channel audio data module.
Definition NDData.hpp:359
Role
Semantic role of the dimension.
Definition NDData.hpp:145
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:387
std::string name
Human-readable identifier for the dimension.
Definition NDData.hpp:187
static DataModule create_audio_1d(uint64_t samples, T default_value=T {})
Create 1D audio data module.
Definition NDData.hpp:345
static DataModule create_image_2d(uint64_t height, uint64_t width, T default_value=T {})
Create 2D image data module.
Definition NDData.hpp:373
std::pair< std::vector< DataVariant >, std::vector< DataDimension > > DataModule
Data container combining variants and dimensions.
Definition NDData.hpp:299
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:413
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:312
std::optional< ComponentGroup > grouping
Definition NDData.hpp:185
Minimal dimension descriptor focusing on structure only.
Definition NDData.hpp:138