@@ -16,6 +16,7 @@ struct transport_state {
|
||||
std::uint32_t channels{};
|
||||
std::uint64_t duration{};
|
||||
mutable std::uint64_t cursor{};
|
||||
mutable std::size_t first_live_click{};
|
||||
sonus::transport_config config{};
|
||||
std::array<std::vector<std::float32_t>, 2> samples{};
|
||||
mutable std::vector<std::float32_t> scratch{};
|
||||
|
||||
+12
-1
@@ -155,7 +155,18 @@ auto sonus::detail::transport_player::render(std::float32_t *output, std::uint64
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto const &click : state->config.clicks) {
|
||||
// Retain overlapping tails, but never revisit an expired schedule prefix.
|
||||
// The cursor is owned by the render thread and needs no allocation or lock.
|
||||
while (state->first_live_click < state->config.clicks.size()) {
|
||||
auto const &click = state->config.clicks[state->first_live_click];
|
||||
auto length = state->samples[click.downbeat ? 0 : 1].size() / channels;
|
||||
if (click.frame > state->cursor || length > state->cursor - click.frame) {
|
||||
break;
|
||||
}
|
||||
++state->first_live_click;
|
||||
}
|
||||
for (auto index = state->first_live_click; index < state->config.clicks.size(); ++index) {
|
||||
auto const &click = state->config.clicks[index];
|
||||
if (click.frame >= state->cursor + count) {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user