MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Region.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#ifdef MAYAFLUX_PLATFORM_WINDOWS
6#ifdef CALLBACK
7#undef CALLBACK
8#endif // CALLBACK
9#endif // MAYAFLUX_PLATFORM_WINDOWS
10
11namespace MayaFlux::Kakshya {
12
13/**
14 * @enum RegionSelectionPattern
15 * @brief Describes how regions are selected for processing or playback.
16 */
17enum class RegionSelectionPattern : uint8_t {
18 ALL, ///< Process all regions
19 SEQUENTIAL, ///< Process regions in order
20 RANDOM, ///< Random selection
21 ROUND_ROBIN, ///< Cycle through regions
22 WEIGHTED, ///< Weighted random selection
23 OVERLAP, ///< Overlapping selection
24 EXCLUSIVE, ///< Mutually exclusive selection
25 CUSTOM ///< User-defined selection logic
26};
27
28/**
29 * @enum RegionTransition
30 * @brief Describes how transitions between regions are handled.
31 */
32enum class RegionTransition : uint8_t {
33 IMMEDIATE, ///< No transition, jump directly
34 CROSSFADE, ///< Crossfade between regions
35 OVERLAP, ///< Overlap regions during transition
36 GATED, ///< Hard gate between regions
37 CALLBACK ///< Use callback for custom transition
38};
39
40/**
41 * @enum RegionState
42 * @brief Processing state for regions.
43 */
44enum class RegionState : uint8_t {
45 IDLE, ///< Not being processed
46 LOADING, ///< Data being loaded
47 READY, ///< Ready for processing
48 ACTIVE, ///< Currently being processed
49 TRANSITIONING, ///< In transition to another region
50 UNLOADING ///< Being removed from memory
51};
52
53/**
54 * @struct Region
55 * @brief Represents a point or span in N-dimensional space.
56 *
57 * Regions represent precise locations or segments within signal data,
58 * defined by start and end frame positions. Each region can have additional
59 * attributes stored in a flexible key-value map, allowing for rich metadata
60 * association with each point.
61 *
62 * Common DSP-specific uses include:
63 * - Marking transients and onset detection points
64 * - Identifying spectral features or frequency domain events
65 * - Defining zero-crossing boundaries for phase analysis
66 * - Marking signal transformation points (e.g., filter application boundaries)
67 * - Storing analysis results like RMS peaks, harmonic content points, or noise floors
68 *
69 * The flexible attribute system allows for storing any computed values or metadata
70 * associated with specific signal locations, enabling advanced signal processing
71 * workflows and algorithmic decision-making.
72 */
73struct MAYAFLUX_API Region {
74 /** @brief Starting frame index (inclusive) */
75 std::vector<uint64_t> start_coordinates;
76
77 /** @brief Ending frame index (inclusive) */
78 std::vector<uint64_t> end_coordinates;
79
80 /** @brief Flexible key-value store for region-specific attributes */
81 std::unordered_map<std::string, std::any> attributes;
82
83 Region() = default;
84
85 /**
86 * @brief Construct a point-like region (single coordinate).
87 * @param coordinates The N-dimensional coordinates.
88 * @param attributes Optional metadata.
89 */
90 Region(const std::vector<uint64_t>& coordinates,
91 std::unordered_map<std::string, std::any> attributes = {})
92 : start_coordinates(coordinates)
93 , end_coordinates(coordinates)
94 , attributes(std::move(attributes))
95 {
96 }
97
98 /**
99 * @brief Construct a span-like region (start and end coordinates).
100 * @param start Start coordinates (inclusive).
101 * @param end End coordinates (inclusive).
102 * @param attributes Optional metadata.
103 */
104 Region(std::vector<uint64_t> start,
105 std::vector<uint64_t> end,
106 std::unordered_map<std::string, std::any> attributes = {})
107 : start_coordinates(std::move(start))
108 , end_coordinates(std::move(end))
109 , attributes(std::move(attributes))
110 {
111 }
112
113 /**
114 * @brief Create a Region representing a single time point (e.g., a frame or sample).
115 * @param frame The frame index (time coordinate).
116 * @param label Optional label for this point.
117 * @param extra_data Optional extra metadata (e.g., analysis result).
118 * @return Region at the specified frame.
119 */
120 static Region time_point(uint64_t frame,
121 const std::string& label = "",
122 const std::any& extra_data = {})
123 {
124 std::unordered_map<std::string, std::any> attrs;
125 if (!label.empty())
126 attrs["label"] = label;
127 if (extra_data.has_value())
128 attrs["data"] = extra_data;
129 attrs["type"] = "time_point";
130 return Region({ frame }, attrs);
131 }
132
133 /**
134 * @brief Create a Region representing a time span (e.g., a segment of frames).
135 * @param start_frame Start frame index (inclusive).
136 * @param end_frame End frame index (inclusive).
137 * @param label Optional label for this span.
138 * @param extra_data Optional extra metadata.
139 * @return Region covering the specified time span.
140 */
141 static Region time_span(uint64_t start_frame,
142 uint64_t end_frame,
143 const std::string& label = "",
144 const std::any& extra_data = {})
145 {
146 std::unordered_map<std::string, std::any> attrs;
147 if (!label.empty())
148 attrs["label"] = label;
149 if (extra_data.has_value())
150 attrs["data"] = extra_data;
151 attrs["type"] = "time_span";
152 return Region({ start_frame }, { end_frame }, attrs);
153 }
154
155 /**
156 * @brief Create a Region for a single audio sample/channel location.
157 * @param frame The frame index (time).
158 * @param channel The channel index.
159 * @param label Optional label for this region.
160 * @return Region at the specified frame/channel.
161 */
162 static Region audio_point(uint64_t frame,
163 uint32_t channel,
164 const std::string& label = "")
165 {
166 std::unordered_map<std::string, std::any> attrs;
167 if (!label.empty())
168 attrs["label"] = label;
169 attrs["type"] = "audio_point";
170 return Region({ frame, channel }, attrs);
171 }
172
173 /**
174 * @brief Create a Region representing a span in audio (frames and channels).
175 * @param start_frame Start frame index (inclusive).
176 * @param end_frame End frame index (inclusive).
177 * @param start_channel Start channel index (inclusive).
178 * @param end_channel End channel index (inclusive).
179 * @param label Optional label for this region.
180 * @return Region covering the specified audio region.
181 */
182 static Region audio_span(uint64_t start_frame,
183 uint64_t end_frame,
184 uint32_t start_channel,
185 uint32_t end_channel,
186 const std::string& label = "")
187 {
188 std::unordered_map<std::string, std::any> attrs;
189 if (!label.empty())
190 attrs["label"] = label;
191 attrs["type"] = "audio_region";
192 return Region({ start_frame, start_channel },
193 { end_frame, end_channel }, attrs);
194 }
195
196 /**
197 * @brief Create a Region representing a rectangular region in an image.
198 * @param x1 Top-left X coordinate.
199 * @param y1 Top-left Y coordinate.
200 * @param x2 Bottom-right X coordinate.
201 * @param y2 Bottom-right Y coordinate.
202 * @param label Optional label for this rectangle.
203 * @return Region covering the specified image rectangle.
204 */
205 static Region image_rect(uint64_t x1, uint64_t y1,
206 uint64_t x2, uint64_t y2,
207 const std::string& label = "")
208 {
209 std::unordered_map<std::string, std::any> attrs;
210 if (!label.empty())
211 attrs["label"] = label;
212 attrs["type"] = "image_rect";
213 return Region({ x1, y1 }, { x2, y2 }, attrs);
214 }
215
216 /**
217 * @brief Create a Region representing a region in a video (frames and spatial rectangle).
218 * @param start_frame Start frame index (inclusive).
219 * @param end_frame End frame index (inclusive).
220 * @param x1 Top-left X coordinate.
221 * @param y1 Top-left Y coordinate.
222 * @param x2 Bottom-right X coordinate.
223 * @param y2 Bottom-right Y coordinate.
224 * @param label Optional label for this region.
225 * @return Region covering the specified video region.
226 */
227 static Region video_region(uint64_t start_frame,
228 uint64_t end_frame,
229 uint64_t x1, uint64_t y1,
230 uint64_t x2, uint64_t y2,
231 const std::string& label = "")
232 {
233 std::unordered_map<std::string, std::any> attrs;
234 if (!label.empty())
235 attrs["label"] = label;
236 attrs["type"] = "video_region";
237 return Region({ start_frame, x1, y1 },
238 { end_frame, x2, y2 }, attrs);
239 }
240
241 /**
242 * @brief Check if this region is a single point (start == end).
243 */
244 bool is_point() const
245 {
246 return start_coordinates == end_coordinates;
247 }
248
249 /**
250 * @brief Check if the given coordinates are contained within this region.
251 * @param coordinates N-dimensional coordinates to check.
252 * @return True if contained, false otherwise.
253 */
254 bool contains(const std::vector<uint64_t>& coordinates) const
255 {
256 if (coordinates.size() != start_coordinates.size())
257 return false;
258
259 for (size_t i = 0; i < start_coordinates.size(); i++) {
260 if (coordinates[i] < start_coordinates[i] || coordinates[i] > end_coordinates[i]) {
261 return false;
262 }
263 }
264 return true;
265 }
266
267 /**
268 * @brief Check if this region overlaps with another region.
269 * @param other The other region.
270 * @return True if overlapping, false otherwise.
271 */
272 bool overlaps(const Region& other) const
273 {
274 if (start_coordinates.size() != other.start_coordinates.size())
275 return false;
276
277 for (size_t i = 0; i < start_coordinates.size(); i++) {
278 if (end_coordinates[i] < other.start_coordinates[i] || start_coordinates[i] > other.end_coordinates[i]) {
279 return false;
280 }
281 }
282 return true;
283 }
284
285 /**
286 * @brief Get the span (length) of the region along a dimension.
287 * @param dimension_index The dimension to query.
288 * @return The span (number of elements) along the dimension.
289 */
290 uint64_t get_span(uint32_t dimension_index = 0) const
291 {
292 if (dimension_index >= start_coordinates.size())
293 return 0;
294 return end_coordinates[dimension_index] - start_coordinates[dimension_index] + 1;
295 }
296
297 /**
298 * @brief Get the total volume (number of elements) in the region.
299 * @return The product of spans across all dimensions.
300 */
301 uint64_t get_volume() const
302 {
303 uint64_t volume = 1;
304 for (size_t i = 0; i < start_coordinates.size(); i++) {
305 volume *= get_span(i);
306 }
307 return volume;
308 }
309
310 /**
311 * @brief Get the duration (span) along a specific dimension.
312 * @param dimension_index The dimension to query.
313 * @return The duration (number of elements) along the dimension.
314 */
315 uint64_t get_duration(uint32_t dimension_index = 0) const
316 {
317 if (dimension_index >= start_coordinates.size()) {
318 return 0;
319 }
320 return end_coordinates[dimension_index] - start_coordinates[dimension_index] + 1;
321 }
322
323 /**
324 * @brief Get an attribute value by key, with type conversion support.
325 * @tparam T The expected type.
326 * @param key The attribute key.
327 * @return Optional value if present and convertible.
328 */
329 template <typename T>
330 std::optional<T> get_attribute(const std::string& key) const
331 {
332 auto it = attributes.find(key);
333 if (it == attributes.end()) {
334 return std::nullopt;
335 }
336
337 return safe_any_cast<T>(it->second);
338 }
339
340 /**
341 * @brief Set an attribute value by key.
342 * @param key The attribute key.
343 * @param value The value to set.
344 */
345 void set_attribute(const std::string& key, std::any value)
346 {
347 attributes[key] = std::move(value);
348 }
349
350 /**
351 * @brief Get the label attribute (if present).
352 * @return The label string, or empty if not set.
353 */
354 std::string get_label() const
355 {
356 auto label = get_attribute<std::string>("label");
357 return label.value_or("");
358 }
359
360 /**
361 * @brief Set the label attribute.
362 * @param label The label string.
363 */
364 void set_label(const std::string& label)
365 {
366 set_attribute("label", label);
367 }
368
369 /**
370 * @brief Translate the region by an offset vector.
371 * @param offset The offset for each dimension (can be negative).
372 * @return A new translated Region.
373 */
374 Region translate(const std::vector<int64_t>& offset) const
375 {
376 Region result = *this;
377 for (size_t i = 0; i < std::min(offset.size(), start_coordinates.size()); i++) {
378 if (offset[i] < 0 && std::abs(offset[i]) > static_cast<int64_t>(result.start_coordinates[i])) {
379 result.start_coordinates[i] = 0;
380 } else {
381 result.start_coordinates[i] += offset[i];
382 }
383
384 if (offset[i] < 0 && std::abs(offset[i]) > static_cast<int64_t>(result.end_coordinates[i])) {
385 result.end_coordinates[i] = 0;
386 } else {
387 result.end_coordinates[i] += offset[i];
388 }
389 }
390 return result;
391 }
392
393 /**
394 * @brief Scale the region about its center by the given factors.
395 * @param factors Scaling factors for each dimension.
396 * @return A new scaled Region.
397 */
398 Region scale(const std::vector<double>& factors) const
399 {
400 Region result = *this;
401 for (size_t i = 0; i < std::min<size_t>(factors.size(), start_coordinates.size()); i++) {
402 uint64_t center = (start_coordinates[i] + end_coordinates[i]) / 2;
403 uint64_t half_span = get_span(i) / 2;
404 auto new_half_span = static_cast<uint64_t>((double)half_span * factors[i]);
405
406 result.start_coordinates[i] = center - new_half_span;
407 result.end_coordinates[i] = center + new_half_span;
408 }
409 return result;
410 }
411
412 /**
413 * @brief Equality comparison for Regions.
414 */
415 bool operator==(const Region& other) const
416 {
417 if (start_coordinates.size() != other.start_coordinates.size() || end_coordinates.size() != other.end_coordinates.size()) {
418 return false;
419 }
420
421 for (size_t i = 0; i < start_coordinates.size(); ++i) {
422 if (start_coordinates[i] != other.start_coordinates[i]) {
423 return false;
424 }
425 }
426
427 for (size_t i = 0; i < end_coordinates.size(); ++i) {
428 if (end_coordinates[i] != other.end_coordinates[i]) {
429 return false;
430 }
431 }
432
433 return true;
434 }
435
436 /**
437 * @brief Inequality comparison for Regions.
438 */
439 bool operator!=(const Region& other) const
440 {
441 return !(*this == other);
442 }
443};
444
445} // namespace MayaFlux::Kakshya
RegionSelectionPattern
Describes how regions are selected for processing or playback.
Definition Region.hpp:17
@ SEQUENTIAL
Process regions in order.
@ CUSTOM
User-defined selection logic.
@ WEIGHTED
Weighted random selection.
@ EXCLUSIVE
Mutually exclusive selection.
RegionTransition
Describes how transitions between regions are handled.
Definition Region.hpp:32
@ GATED
Hard gate between regions.
@ CROSSFADE
Crossfade between regions.
@ IMMEDIATE
No transition, jump directly.
@ CALLBACK
Use callback for custom transition.
RegionState
Processing state for regions.
Definition Region.hpp:44
@ ACTIVE
Currently being processed.
@ READY
Ready for processing.
@ UNLOADING
Being removed from memory.
@ TRANSITIONING
In transition to another region.
@ IDLE
Not being processed.
@ LOADING
Data being loaded.
void set_label(const std::string &label)
Set the label attribute.
Definition Region.hpp:364
uint64_t get_duration(uint32_t dimension_index=0) const
Get the duration (span) along a specific dimension.
Definition Region.hpp:315
bool is_point() const
Check if this region is a single point (start == end).
Definition Region.hpp:244
static Region audio_point(uint64_t frame, uint32_t channel, const std::string &label="")
Create a Region for a single audio sample/channel location.
Definition Region.hpp:162
static Region audio_span(uint64_t start_frame, uint64_t end_frame, uint32_t start_channel, uint32_t end_channel, const std::string &label="")
Create a Region representing a span in audio (frames and channels).
Definition Region.hpp:182
static Region time_span(uint64_t start_frame, uint64_t end_frame, const std::string &label="", const std::any &extra_data={})
Create a Region representing a time span (e.g., a segment of frames).
Definition Region.hpp:141
Region(const std::vector< uint64_t > &coordinates, std::unordered_map< std::string, std::any > attributes={})
Construct a point-like region (single coordinate).
Definition Region.hpp:90
void set_attribute(const std::string &key, std::any value)
Set an attribute value by key.
Definition Region.hpp:345
Region translate(const std::vector< int64_t > &offset) const
Translate the region by an offset vector.
Definition Region.hpp:374
bool operator!=(const Region &other) const
Inequality comparison for Regions.
Definition Region.hpp:439
std::unordered_map< std::string, std::any > attributes
Flexible key-value store for region-specific attributes.
Definition Region.hpp:81
uint64_t get_span(uint32_t dimension_index=0) const
Get the span (length) of the region along a dimension.
Definition Region.hpp:290
Region scale(const std::vector< double > &factors) const
Scale the region about its center by the given factors.
Definition Region.hpp:398
std::optional< T > get_attribute(const std::string &key) const
Get an attribute value by key, with type conversion support.
Definition Region.hpp:330
uint64_t get_volume() const
Get the total volume (number of elements) in the region.
Definition Region.hpp:301
std::vector< uint64_t > end_coordinates
Ending frame index (inclusive)
Definition Region.hpp:78
static Region video_region(uint64_t start_frame, uint64_t end_frame, uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, const std::string &label="")
Create a Region representing a region in a video (frames and spatial rectangle).
Definition Region.hpp:227
bool overlaps(const Region &other) const
Check if this region overlaps with another region.
Definition Region.hpp:272
std::string get_label() const
Get the label attribute (if present).
Definition Region.hpp:354
std::vector< uint64_t > start_coordinates
Starting frame index (inclusive)
Definition Region.hpp:75
bool contains(const std::vector< uint64_t > &coordinates) const
Check if the given coordinates are contained within this region.
Definition Region.hpp:254
static Region image_rect(uint64_t x1, uint64_t y1, uint64_t x2, uint64_t y2, const std::string &label="")
Create a Region representing a rectangular region in an image.
Definition Region.hpp:205
bool operator==(const Region &other) const
Equality comparison for Regions.
Definition Region.hpp:415
Region(std::vector< uint64_t > start, std::vector< uint64_t > end, std::unordered_map< std::string, std::any > attributes={})
Construct a span-like region (start and end coordinates).
Definition Region.hpp:104
static Region time_point(uint64_t frame, const std::string &label="", const std::any &extra_data={})
Create a Region representing a single time point (e.g., a frame or sample).
Definition Region.hpp:120
Represents a point or span in N-dimensional space.
Definition Region.hpp:73