MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
RegionSegment.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Region.hpp"
4
5namespace MayaFlux::Kakshya {
6
7/**
8 * @struct RegionCache
9 * @brief Stores cached data for a region, with metadata for cache management.
10 */
11struct MAYAFLUX_API RegionCache {
12 std::vector<DataVariant> data; ///< Cached data
13 Region source_region; ///< Region this cache corresponds to
14 std::chrono::steady_clock::time_point load_time; ///< When cache was loaded
15 size_t access_count = 0; ///< Number of times accessed
16 bool is_dirty = false; ///< Whether cache is dirty
17
19 {
20 access_count++;
21 }
22
24 {
25 is_dirty = true;
26 }
27
28 std::chrono::duration<double> age() const
29 {
30 return std::chrono::steady_clock::now() - load_time;
31 }
32};
33
34/**
35 * @struct RegionSegment
36 * @brief Represents a discrete segment of audio data with caching capabilities.
37 *
38 * Defines a time-bounded segment of audio that can be cached for efficient
39 * playback and manipulation in non-linear processing contexts.
40 */
41struct MAYAFLUX_API RegionSegment {
42 Region source_region; ///< Associated region
43 std::vector<uint64_t> offset_in_region; ///< Offset within the source region
44 std::vector<uint64_t> segment_size; ///< Size in each dimension
45
46 RegionCache cache; ///< Multi-channel cached audio data
47 bool is_cached = false; ///< Flag indicating if data is cached
48
49 std::vector<uint64_t> current_position { 0 }; ///< Current position within segment
50 bool is_active = false;
51 RegionState state = RegionState::IDLE;
52
53 std::unordered_map<std::string, std::any> processing_metadata; ///< Arbitrary processing metadata
54
55 RegionSegment() = default;
56
57 /**
58 * @brief Construct a segment from a region (full region).
59 * @param region The source region.
60 */
61 explicit RegionSegment(const Region& region)
62 : source_region(region)
63 , offset_in_region(region.start_coordinates.size(), 0)
64 , segment_size(region.start_coordinates.size())
65 , current_position(region.start_coordinates.size(), 0)
66 {
67 for (size_t i = 0; i < segment_size.size(); ++i) {
68 segment_size[i] = region.get_span(i);
69 }
70 }
71
72 /**
73 * @brief Construct a segment from a region with offset and size.
74 * @param region The source region.
75 * @param offset Offset within the region.
76 * @param size Size of the segment.
77 */
79 const std::vector<uint64_t>& offset,
80 const std::vector<uint64_t>& size)
81 : source_region(std::move(region))
82 , offset_in_region(offset)
83 , segment_size(size)
84 , current_position(size.size(), 0)
85 {
86 }
87
88 /**
89 * @brief Get the total number of elements in the segment.
90 */
91 uint64_t get_total_elements() const
92 {
93 uint64_t total = 1;
94 for (auto s : segment_size) {
95 total *= s;
96 }
97 return total;
98 }
99
100 /**
101 * @brief Check if a position is within this segment.
102 * @param pos The N-dimensional position.
103 * @return True if contained, false otherwise.
104 */
105 bool contains_position(const std::vector<uint64_t>& pos) const
106 {
107 if (pos.size() != offset_in_region.size())
108 return false;
109
110 for (size_t i = 0; i < pos.size(); ++i) {
111 if (pos[i] < offset_in_region[i] || pos[i] >= offset_in_region[i] + segment_size[i]) {
112 return false;
113 }
114 }
115 return true;
116 }
117
118 /**
119 * @brief Get the age of the cache in seconds.
120 * @return Age in seconds, or -1 if not cached.
121 */
123 {
124 if (!is_cached)
125 return -1.0;
126 return cache.age().count();
127 }
128
129 /* bool has_data_for_dimension(size_t dimension) const
130 {
131 return dimension < cached_data.size() && !get_cached_element_size(dimension);
132 } */
133
134 // Get data for a specific dimension
135 /* const DataVariant& get_dimension_data(size_t dimension) const
136 {
137 static const DataVariant temp;
138 return dimension < cached_data.size() ? cached_data[dimension] : temp;
139 } */
140
142 {
143 is_active = true;
144 state = RegionState::ACTIVE;
145 }
146
148 {
149 is_active = false;
150 state = RegionState::IDLE;
151 }
152
153 /**
154 * @brief Mark this segment as cached and store the data.
155 * @param data The cached data.
156 */
157 void mark_cached(const std::vector<DataVariant>& data)
158 {
159 cache.data = data;
160 cache.source_region = source_region;
161 is_cached = true;
162 cache.load_time = std::chrono::steady_clock::now();
163 cache.is_dirty = false;
164 state = RegionState::READY;
165 }
166
167 /**
168 * @brief Clear the cache for this segment.
169 */
171 {
172 cache.data.clear();
173 is_cached = false;
174 if (state == RegionState::READY) {
175 state = RegionState::IDLE;
176 }
177 }
178
179 /**
180 * @brief Reset the current position within the segment.
181 */
183 {
184 std::ranges::fill(current_position, 0);
185 }
186
187 /**
188 * @brief Advance the current position within the segment.
189 * @param steps Number of steps to advance.
190 * @param dimension Dimension to advance.
191 * @return True if not at end, false if at end.
192 */
193 bool advance_position(uint64_t steps = 1, uint32_t dimension = 0)
194 {
195
196 if (current_position.empty() || segment_size.empty() || dimension >= current_position.size()) {
197 return false;
198 }
199
200 current_position[dimension] += steps;
201
202 // return current_position[dimension] < segment_size[dimension];
203
204 for (size_t dim = dimension; dim < current_position.size(); ++dim) {
205 if (current_position[dim] >= segment_size[dim]) {
206 if (dim == current_position.size() - 1) {
207 return false;
208 }
209
210 uint64_t overflow = current_position[dim] / segment_size[dim];
211 current_position[dim] = current_position[dim] % segment_size[dim];
212
213 if (dim + 1 < current_position.size()) {
214 current_position[dim + 1] += overflow;
215 }
216 } else {
217 break;
218 }
219 }
220
221 return !is_at_end();
222 }
223
224 /**
225 * @brief Check if the current position is at the end of the segment.
226 */
227 bool is_at_end() const
228 {
229 if (current_position.empty() || segment_size.empty())
230 return true;
231
232 return current_position.back() >= segment_size.back();
233 }
234
235 /**
236 * @brief Set processing metadata for this segment.
237 * @param key Metadata key.
238 * @param value Metadata value.
239 */
240 void set_processing_metadata(const std::string& key, std::any value)
241 {
242 processing_metadata[key] = std::move(value);
243 }
244
245 /**
246 * @brief Get processing metadata for this segment.
247 * @tparam T Expected type.
248 * @param key Metadata key.
249 * @return Optional value if present and convertible.
250 */
251 template <typename T>
252 std::optional<T> get_processing_metadata(const std::string& key) const
253 {
254 auto it = processing_metadata.find(key);
255 if (it != processing_metadata.end()) {
256 return safe_any_cast<T>(it->second);
257 }
258 return std::nullopt;
259 }
260};
261
262} // namespace MayaFlux::Kakshya
RegionState
Processing state for regions.
Definition Region.hpp:38
Region source_region
Region this cache corresponds to.
std::vector< DataVariant > data
Cached data.
bool is_dirty
Whether cache is dirty.
std::chrono::duration< double > age() const
std::chrono::steady_clock::time_point load_time
When cache was loaded.
Stores cached data for a region, with metadata for cache management.
bool advance_position(uint64_t steps=1, uint32_t dimension=0)
Advance the current position within the segment.
Region source_region
Associated region.
bool contains_position(const std::vector< uint64_t > &pos) const
Check if a position is within this segment.
uint64_t get_total_elements() const
Get the total number of elements in the segment.
RegionCache cache
Multi-channel cached audio data.
void set_processing_metadata(const std::string &key, std::any value)
Set processing metadata for this segment.
std::vector< uint64_t > offset_in_region
Offset within the source region.
std::unordered_map< std::string, std::any > processing_metadata
Arbitrary processing metadata.
std::optional< T > get_processing_metadata(const std::string &key) const
Get processing metadata for this segment.
RegionSegment(Region region, const std::vector< uint64_t > &offset, const std::vector< uint64_t > &size)
Construct a segment from a region with offset and size.
void mark_cached(const std::vector< DataVariant > &data)
Mark this segment as cached and store the data.
std::vector< uint64_t > segment_size
Size in each dimension.
bool is_at_end() const
Check if the current position is at the end of the segment.
double get_cache_age_seconds() const
Get the age of the cache in seconds.
void reset_position()
Reset the current position within the segment.
void clear_cache()
Clear the cache for this segment.
RegionSegment(const Region &region)
Construct a segment from a region (full region).
Represents a discrete segment of audio data with caching capabilities.
uint64_t get_span(uint32_t dimension_index=0) const
Get the span (length) of the region along a dimension.
Definition Region.hpp:284
Represents a point or span in N-dimensional space.
Definition Region.hpp:67