MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
DynamicSoundStream.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Kakshya {
6
7/**
8 * @class DynamicSoundStream
9 * @brief Dynamic capacity streaming audio container with automatic resizing and circular buffering.
10 *
11 * DynamicSoundStream extends SoundStreamContainer to provide dynamic capacity management
12 * for real-time audio streaming scenarios where the buffer size cannot be predetermined.
13 * It combines the full functionality of SoundStreamContainer with:
14 *
15 * **Key Features:**
16 * - **Dynamic Resizing**: Automatically expands capacity when writing beyond current bounds
17 * - **Circular Buffering**: Optional fixed-size circular buffer mode for continuous streaming
18 * - **Buffer-Sized Operations**: Optimized read/write operations using buffer-sized chunks
19 * - **Capacity Management**: Manual control over buffer allocation and expansion strategies
20 * - **Real-time Safe**: Lock-free operations where possible for audio thread compatibility
21 *
22 * **Use Cases:**
23 * - Real-time audio recording with unknown duration
24 * - Streaming buffers that grow dynamically during playback
25 * - Circular delay lines and feedback systems
26 * - Live audio processing with variable latency requirements
27 * - Audio looping and granular synthesis applications
28 *
29 * **Memory Management:**
30 * The container supports two primary modes:
31 * 1. **Linear Mode**: Automatically expands as data is written, suitable for recording
32 * 2. **Circular Mode**: Fixed-size buffer that wraps around, ideal for delay effects
33 *
34 * **Thread Safety:**
35 * Inherits full thread safety from SoundStreamContainer including shared/exclusive locks
36 * for concurrent read/write access and atomic state management for processing coordination.
37 *
38 * **Integration:**
39 * Fully compatible with the MayaFlux processing ecosystem including DataProcessor implementations,
40 * region-based operations, buffer manager integration, and sample-accurate timing.
41 *
42 * @note When auto-resize is enabled, write operations may trigger memory allocation.
43 * For real-time audio threads, consider pre-allocating capacity or using circular mode.
44 *
45 * @warning Circular mode discards old data when capacity is exceeded. Ensure appropriate
46 * capacity sizing for your use case to prevent data loss.
47 */
48class MAYAFLUX_API DynamicSoundStream : public SoundStreamContainer {
49public:
50 /**
51 * @brief Construct a DynamicSoundStream with specified audio parameters.
52 * @param sample_rate Sample rate in Hz for temporal calculations and timing
53 * @param num_channels Number of audio channels (typically 1=mono, 2=stereo)
54 */
55 DynamicSoundStream(uint32_t sample_rate = 48000, uint32_t num_channels = 2);
56
57 /**
58 * @brief Write audio frame data to the container with automatic capacity management.
59 * @param data Span of interleaved audio samples to write
60 * @param start_frame Frame index where writing begins (default: append at end)
61 % @param channel Channel index for planar data (default: 0)
62 * @return Number of frames actually written
63 */
64 uint64_t write_frames(std::span<const double> data, uint64_t start_frame = 0, uint32_t channel = 0);
65 uint64_t write_frames(std::vector<std::span<const double>> data, uint64_t start_frame = 0);
66
67 /**
68 * @brief Read audio frames using sequential reading with automatic position management.
69 * @param output Span to fill with interleaved audio data
70 * @param count Maximum number of frames to read
71 * @return Number of frames actually read (may be less than requested)
72 */
73 inline uint64_t read_frames(std::span<double> output, uint64_t count)
74 {
75 return read_sequential(output, count);
76 }
77
78 /**
79 * @brief Enable or disable automatic capacity expansion during write operations.
80 * @param enable True to enable auto-resize, false to disable
81 */
82 inline void set_auto_resize(bool enable) { m_auto_resize = enable; }
83
84 /**
85 * @brief Check if automatic capacity expansion is currently enabled.
86 * @return True if auto-resize is enabled, false otherwise
87 */
88 inline bool get_auto_resize() const { return m_auto_resize; }
89
90 /**
91 * @brief Pre-allocate capacity for the specified number of frames.
92 * Essential for real-time scenarios where allocation delays are unacceptable.
93 * @param required_frames Minimum number of frames the container should hold
94 */
95 void ensure_capacity(uint64_t required_frames);
96
97 /**
98 * @brief Enable circular buffer mode with fixed capacity.
99 * Writes wrap around at capacity boundary, potentially overwriting older data.
100 * @param capacity Fixed number of frames the circular buffer can hold
101 */
102 void enable_circular_buffer(uint64_t capacity);
103
104 /**
105 * @brief Disable circular buffer mode and return to linear operation.
106 * Preserves all current data and restores auto-resize behavior.
107 */
108 void disable_circular_buffer();
109
110 /**
111 * @brief Check if the container is currently operating in circular buffer mode.
112 * @return True if circular mode is active, false if in linear mode
113 */
114 bool is_circular() const { return m_is_circular; }
115
116 /**
117 * @brief Get the fixed capacity of the circular buffer if enabled.
118 * @return Capacity in frames if circular mode is active, 0 otherwise
119 */
120 std::span<const double> get_channel_frames(uint32_t channel, uint64_t start_frame, uint64_t num_frames) const;
121
122 void get_channel_frames(std::span<double> output, uint32_t channel, uint64_t start_frame) const;
123
124 uint64_t get_circular_capacity() const { return m_circular_capacity; }
125
126private:
127 bool m_auto_resize; ///< Enable automatic capacity expansion
128 bool m_is_circular {}; ///< True when operating in circular buffer mode
129 uint64_t m_circular_capacity {}; ///< Fixed capacity for circular mode
130
131 void expand_to(uint64_t target_frames);
132
133 std::vector<DataVariant> create_expanded_data(uint64_t new_frame_count);
134
135 void set_all_data(const DataVariant& new_data);
136 void set_all_data(const std::vector<DataVariant>& new_data);
137
138 uint64_t validate(std::vector<std::span<const double>>& data, uint64_t start_frame = 0);
139
140 uint64_t validate_single_channel(std::span<const double> data, uint64_t start_frame = 0, uint32_t channel = 0);
141};
142
143} // namespace MayaFlux::Kakshya
bool m_auto_resize
Enable automatic capacity expansion.
bool get_auto_resize() const
Check if automatic capacity expansion is currently enabled.
void set_auto_resize(bool enable)
Enable or disable automatic capacity expansion during write operations.
bool is_circular() const
Check if the container is currently operating in circular buffer mode.
uint64_t read_frames(std::span< double > output, uint64_t count)
Read audio frames using sequential reading with automatic position management.
Dynamic capacity streaming audio container with automatic resizing and circular buffering.
Concrete base implementation for streaming audio containers.
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