MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ write_frames() [1/2]

uint64_t MayaFlux::Kakshya::DynamicSoundStream::write_frames ( std::span< const double >  data,
uint64_t  start_frame = 0,
uint32_t  channel = 0 
)

Write audio frame data to the container with automatic capacity management.

Parameters
dataSpan of interleaved audio samples to write
start_frameFrame index where writing begins (default: append at end) %
channelChannel index for planar data (default: 0)
Returns
Number of frames actually written

Definition at line 166 of file DynamicSoundStream.cpp.

168{
169 auto num_frames = validate_single_channel(data, start_frame, channel);
170 if (!num_frames)
171 return 0;
172
173 if (m_is_circular && start_frame + num_frames > m_circular_capacity) {
174 uint64_t frames_to_end = m_circular_capacity - start_frame;
175 uint64_t frames_from_start = num_frames - frames_to_end;
176 if (frames_to_end > 0)
177 write_frames(data.subspan(0, frames_to_end), start_frame, channel);
178 if (frames_from_start > 0)
179 write_frames(data.subspan(frames_to_end, frames_from_start), 0, channel);
180 return num_frames;
181 }
182
184 Memory::SeqlockWriteGuard g(m_data_lock);
185 if (m_data.empty())
186 expand_to(start_frame + num_frames);
187
188 auto& interleaved_data = std::get<std::vector<double>>(m_data[0]);
189 const uint32_t num_channels = get_num_channels();
190
191 for (uint64_t frame = 0; frame < num_frames; ++frame) {
192 uint64_t idx = (start_frame + frame) * num_channels + channel;
193 if (idx < interleaved_data.size())
194 interleaved_data[idx] = data[frame];
195 }
196 } else {
197 Memory::SeqlockWriteGuard g(m_data_lock);
198 if (channel >= m_data.size())
199 return 0;
200
201 auto dest_span = convert_variant<double>(m_data[channel]);
202 if (start_frame + num_frames > dest_span.size()) {
203 std::vector<double> current_data(dest_span.begin(), dest_span.end());
204 current_data.resize(start_frame + num_frames, 0.0);
205 m_data[channel] = DataVariant(std::move(current_data));
206 dest_span = convert_variant<double>(m_data[channel]);
207 }
208
209 std::copy(data.begin(), data.begin() + num_frames,
210 dest_span.begin() + start_frame);
211 }
212
213 if (m_is_circular)
215
217 m_double_extraction_dirty.store(true, std::memory_order_release);
218 return num_frames;
219}
uint64_t validate_single_channel(std::span< const double > data, uint64_t start_frame=0, uint32_t channel=0)
bool m_is_circular
True when operating in circular buffer mode.
uint64_t write_frames(std::span< const double > data, uint64_t start_frame=0, uint32_t channel=0)
Write audio frame data to the container with automatic capacity management.
uint64_t m_circular_capacity
Fixed capacity for circular mode.
void invalidate_span_cache()
Invalidate the span cache when data or layout changes.
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:102
@ INTERLEAVED
Single DataVariant with interleaved data (LRLRLR for stereo)

References expand_to(), MayaFlux::Kakshya::SoundStreamContainer::get_num_channels(), MayaFlux::Kakshya::INTERLEAVED, MayaFlux::Kakshya::SoundStreamContainer::invalidate_span_cache(), m_circular_capacity, MayaFlux::Kakshya::SoundStreamContainer::m_data, MayaFlux::Kakshya::SoundStreamContainer::m_data_lock, MayaFlux::Kakshya::SoundStreamContainer::m_double_extraction_dirty, m_is_circular, MayaFlux::Kakshya::SoundStreamContainer::m_num_frames, MayaFlux::Kakshya::SoundStreamContainer::m_structure, MayaFlux::Kakshya::ContainerDataStructure::organization, validate_single_channel(), and write_frames().

Referenced by write_frames(), and write_frames().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: