Peek at data without advancing the read position.
Enables lookahead, preview, or non-destructive inspection of stream data.
557{
559 if (interleaved_span.empty() || output.empty())
560 return 0;
561
563 start_frame += offset;
564 uint64_t elements_to_read = std::min<uint64_t>(count, static_cast<uint64_t>(output.size()));
565
568 if (linear_start >= interleaved_span.size()) {
569 std::ranges::fill(output, 0.0);
570 return 0;
571 }
572 auto view = interleaved_span
573 | std::views::drop(linear_start)
574 | std::views::take(elements_to_read);
575
576 auto copied = std::ranges::copy(view, output.begin());
577 std::ranges::fill(output.subspan(copied.out - output.begin()), 0.0);
578 return static_cast<uint64_t>(copied.out - output.begin());
579 }
580
582 std::ranges::fill(output, 0.0);
583 return 0;
584 }
585
588 uint64_t loop_length_frames = loop_end_frame - loop_start_frame + 1;
589
590 std::ranges::for_each(
591 std::views::iota(0UZ, elements_to_read),
592 [&](uint64_t i) {
596
597 uint64_t wrapped_frame = ((frame_pos - loop_start_frame) % loop_length_frames) + loop_start_frame;
598 uint64_t wrapped_element = wrapped_frame *
m_num_channels + channel_offset;
599
600 output[i] = (wrapped_element < interleaved_span.size()) ? interleaved_span[wrapped_element] : 0.0;
601 });
602
603 if (elements_to_read < output.size()) {
604 std::ranges::fill(output.subspan(elements_to_read), 0.0);
605 }
606 return elements_to_read;
607}
std::span< const double > get_data_as_double() const
Get the audio data as a specific type.
std::vector< std::atomic< uint64_t > > m_read_position
std::vector< uint64_t > end_coordinates
Ending frame index (inclusive)
std::vector< uint64_t > start_coordinates
Starting frame index (inclusive)