38 uint32_t num_channels = 2,
39 uint64_t initial_capacity = 0,
40 bool circular_mode =
false);
44 std::vector<DataDimension> get_dimensions()
const override;
45 uint64_t get_total_elements()
const override;
49 uint64_t get_frame_size()
const override;
50 uint64_t get_num_frames()
const override;
52 std::vector<DataVariant> get_region_data(
const Region& region)
const override;
60 void gather_frames(std::span<const uint64_t> frames, std::span<double>
out)
const;
62 void set_region_data(
const Region& region,
const std::vector<DataVariant>& data)
override;
64 std::vector<DataVariant> get_region_group_data(
const RegionGroup& group)
const override;
65 std::vector<DataVariant> get_segments_data(
const std::vector<RegionSegment>& segment)
const override;
69 uint64_t coordinates_to_linear_index(
const std::vector<uint64_t>& coordinates)
const override;
70 std::vector<uint64_t> linear_index_to_coordinates(uint64_t linear_index)
const override;
72 void clear()
override;
74 const void* get_raw_data()
const override;
75 bool has_data()
const override;
84 std::unordered_map<std::string, RegionGroup> get_all_region_groups()
const override;
87 bool is_region_loaded(
const Region& region)
const override;
88 void load_region(
const Region& region)
override;
89 void unload_region(
const Region& region)
override;
91 void set_read_position(
const std::vector<uint64_t>&
position)
override;
92 void update_read_position_for_channel(
size_t channel, uint64_t frame)
override;
93 const std::vector<uint64_t>& get_read_position()
const override;
94 void advance_read_position(
const std::vector<uint64_t>& frames)
override;
95 bool is_at_end()
const override;
96 void reset_read_position()
override;
102 void set_looping(
bool enable)
override;
103 bool is_looping()
const override {
return m_looping_enabled; }
104 void set_loop_region(
const Region& region)
override;
105 Region get_loop_region()
const override;
107 bool is_ready()
const override;
108 std::vector<uint64_t> get_remaining_frames()
const override;
109 uint64_t read_sequential(std::span<double> output, uint64_t
count)
override;
110 uint64_t peek_sequential(std::span<double> output, uint64_t
count, uint64_t
offset = 0)
const override;
119 m_state_callback = std::move(
callback);
125 m_state_callback =
nullptr;
128 bool is_ready_for_processing()
const override;
129 void mark_ready_for_processing(
bool ready)
override;
131 void create_default_processor()
override;
132 void process_default()
override;
134 void set_default_processor(
const std::shared_ptr<DataProcessor>& processor)
override;
135 std::shared_ptr<DataProcessor> get_default_processor()
const override;
137 std::shared_ptr<DataProcessingChain> get_processing_chain()
override;
140 uint32_t register_dimension_reader(uint32_t dimension_index)
override;
141 void unregister_dimension_reader(uint32_t dimension_index)
override;
142 bool has_active_readers()
const override;
143 void mark_dimension_consumed(uint32_t dimension_index, uint32_t reader_id)
override;
144 bool all_dimensions_consumed()
const override;
146 virtual void clear_all_consumption();
150 return m_processed_data;
155 return m_processed_data;
174 return static_cast<uint32_t
>(m_structure.get_channel_count());
183 return m_processing_token_channel.compare_exchange_strong(expected, channel);
188 return m_processing_token_channel.load() == channel;
195 std::span<const double> get_data_as_double()
const;
197 inline const std::vector<DataVariant>&
get_data()
override {
return m_data; }
204 DataAccess channel_data(
size_t channel)
override;
209 std::vector<DataAccess> all_channel_data()
override;
212 void setup_dimensions();
217 const std::vector<std::span<double>>& get_span_cache()
const;
220 void invalidate_span_cache();
225 std::atomic<int> m_processing_token_channel { -1 };
227 uint32_t m_sample_rate = 48000;
228 uint32_t m_num_channels {};
229 uint64_t m_num_frames {};
232 bool m_looping_enabled =
false;
235 bool m_circular_mode {};
236 uint64_t m_circular_write_position {};
238 std::atomic<ProcessingState> m_processing_state { ProcessingState::IDLE };
259 mutable std::atomic<bool> m_double_extraction_dirty {
true };
266 return get_frame_typed(frame_index);
269 void get_frames_impl(
void* output,
size_t count, uint64_t start_frame, uint64_t num_frames,
const std::type_info&
type)
const override;
271 void get_value_impl(
const std::vector<uint64_t>&
coords,
272 void*
out,
const std::type_info&
type)
const override;
274 void set_value_impl(
const std::vector<uint64_t>&
coords,
275 const void* in,
const std::type_info&
type)
override;
279 mutable std::atomic<bool> m_span_cache_dirty {
true };
281 std::span<const double> get_frame_typed(uint64_t frame_index)
const;
282 void get_frames_typed(std::span<double> output, uint64_t start_frame, uint64_t num_frames)
const;
std::optional< glm::vec3 > position
BufferProcessingChain * chain
std::vector< float > * out
std::vector< glm::ivec3 > coords
vk::PhysicalDeviceType type
Type-erased accessor for NDData with semantic view construction.
Memory::Seqlock m_reader_lock
std::optional< std::vector< std::span< double > > > m_span_cache
std::unordered_map< std::string, RegionGroup > m_region_groups
std::unordered_map< uint32_t, int > m_active_readers
std::unordered_set< uint32_t > m_consumed_dimensions
const std::vector< DataVariant > & get_data() override
Get a reference to the raw data stored in the container.
const std::vector< DataVariant > & get_processed_data() const override
Get a const reference to the processed data buffer.
std::vector< DataVariant > & get_processed_data() override
Get a mutable reference to the processed data buffer.
std::vector< std::atomic< uint64_t > > m_read_position
void unregister_state_change_callback() override
Unregister the state change callback, if any.
std::shared_ptr< DataProcessingChain > m_processing_chain
std::vector< double > m_cached_ext_buffer
~SoundStreamContainer() override=default
void set_structure(ContainerDataStructure structure) override
Set the data structure for this container.
bool is_looping() const override
Check if looping is enabled for the stream.
auto get_frame_span_impl(uint64_t frame_index) const -> DataSpanVariant override
Implementation-specific method to retrieve a frame span.
void set_processing_chain(const std::shared_ptr< DataProcessingChain > &chain) override
Set the processing chain for this container.
const ContainerDataStructure & get_structure() const override
std::vector< DataVariant > m_processed_data
void reset_processing_token() override
std::vector< DataVariant > m_data
void mark_buffers_for_processing(bool) override
Mark associated buffers for processing in the next cycle.
virtual uint32_t get_sample_rate() const
MemoryLayout get_memory_layout() const override
Get the memory layout used by this container.
Memory::Seqlock m_region_lock
Memory::Seqlock m_data_lock
void register_state_change_callback(std::function< void(const std::shared_ptr< SignalSourceContainer > &, ProcessingState)> callback) override
Register a callback to be invoked on processing state changes.
ProcessingState get_processing_state() const override
Get the current processing state of the container.
bool try_acquire_processing_token(int channel) override
virtual uint32_t get_num_channels() const
std::unordered_map< uint32_t, std::unordered_set< uint32_t > > m_reader_consumed_dimensions
std::shared_ptr< DataProcessor > m_default_processor
uint64_t get_temporal_rate() const override
Get the temporal rate (e.g., sample rate, frame rate) of the stream.
std::mutex m_extraction_mutex
bool has_processing_token(int channel) const override
Memory::Seqlock m_cb_lock
std::type_index value_element_type() const override
Runtime query for the native scalar element type of this container.
ContainerDataStructure & get_structure() override
Get the data structure defining this container's layout.
void mark_buffers_for_removal() override
Mark associated buffers for removal from the system.
std::function< void(std::shared_ptr< SignalSourceContainer >, ProcessingState)> m_state_callback
ContainerDataStructure m_structure
std::unordered_map< uint32_t, uint32_t > m_dimension_to_next_reader_id
Concrete base implementation for streaming audio containers.
Data-driven interface for temporal stream containers with navigable read position.
RAII guard that brackets a Seqlock write region.
Sequence lock for fixed-size data regions.
ProcessingState
Represents the current processing lifecycle state of a container.
void remove_region_group(std::unordered_map< std::string, RegionGroup > &groups, const std::string &name)
Remove a RegionGroup by name from a group map.
std::optional< RegionGroup > get_region_group(const std::unordered_map< std::string, RegionGroup > &groups, const std::string &name)
Get a RegionGroup by name from a group map.
typename detail::span_const_from_vector_variant< DataVariant >::type DataSpanVariant
MemoryLayout
Memory layout for multi-dimensional data.
uint64_t time_to_position(double time, double sample_rate)
Convert time (seconds) to position (samples/frames) given a sample rate.
double position_to_time(uint64_t position, double sample_rate)
Convert position (samples/frames) to time (seconds) given a sample rate.
void add_region_group(std::unordered_map< std::string, RegionGroup > &groups, const RegionGroup &group)
Add a RegionGroup to a group map.
Container structure for consistent dimension ordering.
Organizes related signal regions into a categorized collection.
Represents a point or span in N-dimensional space.