145{
149
150 const auto rate =
static_cast<double>(
stream.get_sample_rate());
152 const auto hi =
static_cast<double>(
m_loop_end);
155
158 double last_position = lo;
159 uint64_t valid = 0;
160
161 while (!exited && valid < block) {
163 uint64_t
stop = block;
164
165 if (repeating) {
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)));
170 }
171
173 }
174
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);
181 last_position = p_b;
182
183 for (; valid <
stop; ++valid) {
184 const double u = p_a + (p_b - p_a) * static_cast<double>(valid - begin) / span;
185
187 exited = true;
188 break;
189 }
190
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);
195
199 }
200 }
201
206
207 const auto blend = [&](uint64_t n, uint64_t c) {
211 };
212
213 if (interleaved) {
214 pd.resize(1);
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) {
220 }
221 }
222 } else {
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);
229 }
230 }
231 }
232
234
235 if (exited) {
241 return;
242 }
243
244 const double end =
m_looping ? Kinesis::wrap<double>(last_position, lo, hi) :
std::
clamp(last_position, lo, hi - 1.0);
246}
Core::GlobalStreamInfo stream
std::vector< float > * out
std::vector< double > m_gather_weights
std::vector< uint64_t > m_cursor
void stop()
Deactivate without resetting the cursor position.
std::function< void()> m_on_end
ContainerDataStructure m_structure
uint64_t m_frames_per_block
std::vector< double > m_gather_taps
std::shared_ptr< const Kinesis::TimeMap > m_repeat
std::vector< uint64_t > m_gather_frames
@ INTERLEAVED
Single DataVariant with interleaved data (LRLRLR for stereo)
void clamp(std::span< double > data, double lo, double hi) noexcept
Clamp values to [lo, hi] in-place.
static uint64_t get_channel_count(const std::vector< DataDimension > &dimensions)
Extract channel count from dimensions.
OrganizationStrategy organization