13 : m_frames_per_block(frames_per_block)
19 auto stream = std::dynamic_pointer_cast<DynamicSoundStream>(container);
22 "CursorAccessProcessor requires a DynamicSoundStream");
36 auto stream = std::dynamic_pointer_cast<DynamicSoundStream>(container);
39 "CursorAccessProcessor requires a DynamicSoundStream, slot index can potentially leak");
52 auto stream = std::dynamic_pointer_cast<DynamicSoundStream>(container);
55 "CursorAccessProcessor requires a DynamicSoundStream");
68 pd.resize(num_channels);
88 std::vector<uint64_t> { frame, 0 },
92 auto region_data = container->get_region_data(region);
96 if (!region_data.empty())
99 const uint64_t ch_count = std::min(
100 static_cast<uint64_t
>(region_data.size()),
103 for (
size_t c = 0; c < ch_count; ++c)
108 const auto int_advance =
static_cast<uint64_t
>(raw_advance);
111 const uint64_t next = frame + int_advance;
150 const auto rate =
static_cast<double>(
stream.get_sample_rate());
152 const auto hi =
static_cast<double>(
m_loop_end);
158 double last_position = lo;
161 while (!exited && valid < block) {
163 uint64_t
stop = block;
168 const double seconds = std::max((*
m_repeat)(
static_cast<double>(clock) /
rate), 0.0);
169 m_repeat_length = std::max<uint64_t>(1,
static_cast<uint64_t
>(std::llround(seconds *
rate)));
176 const uint64_t begin = valid;
177 const uint64_t frames =
stop - begin;
178 const auto span =
static_cast<double>(frames);
179 const double p_a = (*m_time_map)(
static_cast<double>(clock - origin) /
rate);
180 const double p_b = (*m_time_map)(
static_cast<double>(clock + frames - origin) /
rate);
183 for (; valid <
stop; ++valid) {
184 const double u = p_a + (p_b - p_a) *
static_cast<double>(valid - begin) / span;
191 const double s =
m_looping ? Kinesis::wrap<double>(u, lo, hi) : u;
192 const double whole = std::floor(s);
193 const uint64_t i = std::min(
static_cast<uint64_t
>(whole),
m_loop_end - 1);
207 const auto blend = [&](uint64_t n, uint64_t c) {
215 auto&
out = std::get<std::vector<double>>(pd[0]);
217 for (uint64_t n = 0; n < valid; ++n) {
218 for (uint64_t c = 0; c <
channels; ++c) {
224 for (uint64_t c = 0; c <
channels; ++c) {
225 auto&
out = std::get<std::vector<double>>(pd[c]);
226 out.assign(block, 0.0);
227 for (uint64_t n = 0; n < valid; ++n) {
228 out[n] = blend(n, c);
244 const double end =
m_looping ? Kinesis::wrap<double>(last_position, lo, hi) : std::clamp(last_position, lo, hi - 1.0);
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
Core::GlobalStreamInfo stream
std::vector< float > * out
std::vector< double > m_gather_weights
std::shared_ptr< const Kinesis::TimeMap > m_time_map
void process(const std::shared_ptr< SignalSourceContainer > &container) override
Extract one block of frames into container processed_data[0].
std::vector< uint64_t > m_cursor
CursorAccessProcessor(uint64_t frames_per_block)
Construct with a fixed output block size.
void on_detach(const std::shared_ptr< SignalSourceContainer > &container) override
Called when this processor is detached from a container.
void set_repeat(const std::shared_ptr< const Kinesis::TimeMap > &length)
Restart the time map over and over, with a length that can change.
void set_loop_count(size_t n)
Set the number of loops to play before stopping.
void stop()
Deactivate without resetting the cursor position.
void set_frames_per_block(uint64_t frames_per_block)
Set the output block size in frames.
void set_speed(double speed)
Set the playback speed relative to nominal rate.
void reset()
Reset cursor to loop start and activate the processor.
void process_mapped(DynamicSoundStream &stream, std::vector< DataVariant > &pd)
std::function< void()> m_on_end
ContainerDataStructure m_structure
uint64_t m_frames_per_block
void set_time_map(const std::shared_ptr< const Kinesis::TimeMap > &map)
Drive the read position from a function of time instead of speed.
void set_loop_region(uint64_t start_frame, uint64_t end_frame)
Set the loop region in frames.
uint64_t loop_end() const
std::vector< double > m_gather_taps
std::atomic< bool > m_is_processing
std::shared_ptr< const Kinesis::TimeMap > m_repeat
void on_attach(const std::shared_ptr< SignalSourceContainer > &container) override
Called when this processor is attached to a container.
std::vector< uint64_t > m_gather_frames
Dynamic capacity streaming audio container with automatic resizing and circular buffering.
@ ContainerProcessing
Container operations (Kakshya - file/stream/region processing)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
void safe_copy_data_variant(const DataVariant &input, DataVariant &output)
Safely copy data from a DataVariant to another DataVariant, handling type conversion.
@ INTERLEAVED
Single DataVariant with interleaved data (LRLRLR for stereo)
static uint64_t get_channel_count(const std::vector< DataDimension > &dimensions)
Extract channel count from dimensions.
OrganizationStrategy organization
static uint64_t get_samples_count_per_channel(const std::vector< DataDimension > &dimensions)
Get samples per channel (time dimension only).
Represents a point or span in N-dimensional space.