12 void apply_slice(
const Kakshya::StreamSlice& slice, Kakshya::CursorAccessProcessor& proc)
14 proc.set_loop_region(
slice.start_frame(),
slice.end_frame());
15 proc.set_looping(
slice.looping);
16 proc.set_speed(
slice.speed);
17 proc.set_time_map(
slice.time_map);
18 proc.set_repeat(
slice.repeat);
20 if (
slice.loop_count != proc.loop_count())
21 proc.set_loop_count(
slice.loop_count);
28 auto audio = std::dynamic_pointer_cast<AudioBuffer>(
buffer);
31 "StreamSliceProcessor requires an AudioBuffer");
39 for (
size_t i = 0; i <
m_slots.size(); ++i)
45 return std::dynamic_pointer_cast<AudioBuffer>(
buffer) !=
nullptr;
51 if (slot.proc && slot.slice.stream)
52 slot.proc->on_detach(slot.slice.stream);
60 "StreamSliceProcessor::load called before attachment to a buffer -- attach first");
69 "StreamSliceProcessor::load index {} exceeds slot count {}; use {} for next available",
82 apply_slice(
slice, *proc);
84 proc->set_on_end([
this,
index] {
117 return std::ranges::any_of(
m_slots, [](
const auto& slot) {
118 return slot.slice.active;
124 auto audio = std::dynamic_pointer_cast<AudioBuffer>(
buffer);
128 const uint32_t ch = audio->get_channel_id();
129 auto&
dst = audio->get_data();
130 std::ranges::fill(
dst, 0.0);
133 if (!slot.slice.active || !slot.slice.stream || !slot.proc)
136 apply_slice(slot.slice, *slot.proc);
137 slot.proc->process(slot.slice.stream);
139 const auto& pd = slot.slice.stream->get_dynamic_data(slot.proc->get_slot_index());
143 const auto structure = slot.slice.stream->get_structure();
144 std::vector<double> tmp(
dst.size(), 0.0);
146 slot.slice.source_channel.value_or(ch), tmp);
148 for (
size_t s = 0; s <
dst.size(); ++s)
149 dst[s] += tmp[s] * slot.slice.scale;
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
void detach_slot(size_t index)
void unbind(size_t index)
Deactivate a slot, stopping its processor without resetting the cursor.
void on_attach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is attached to a buffer.
void bind(size_t index)
Activate a slot, resetting its processor cursor to region start.
std::vector< Slot > m_slots
bool is_compatible_with(const std::shared_ptr< Buffer > &buffer) const override
Checks if this processor can handle the specified buffer type.
void on_detach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is detached from a buffer.
bool any_active() const
Check if any slot is active.
void load(size_t index, Kakshya::StreamSlice slice)
Assign a StreamSlice to a slot.
uint32_t m_frames_per_block
void processing_function(const std::shared_ptr< Buffer > &buffer) override
The core processing function that must be implemented by derived classes.
Kakshya::StreamSlice & slice(size_t index)
std::function< void(size_t)> m_on_end
@ Configuration
Configuration and parameter updates.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
void extract_processed_data(const std::vector< DataVariant > &pd, OrganizationStrategy organization, uint64_t num_channels, uint32_t ch, std::span< double > output)
Extract one channel's samples from a processed dynamic data block.
std::vector< double > slice(std::span< const double > data, double start_ratio, double end_ratio)
Extract a contiguous slice by ratio, returning a new vector.
std::shared_ptr< DynamicSoundStream > stream
A bounded region of a DynamicSoundStream with associated playback parameters.