Peek at data without advancing the read position.
Enables lookahead, preview, or non-destructive inspection of stream data.
559{
561 if (interleaved_span.empty() || output.empty())
562 return 0;
563
565 start_frame += offset;
566 uint64_t elements_to_read = std::min<uint64_t>(count, static_cast<uint64_t>(output.size()));
567
570 if (linear_start >= interleaved_span.size()) {
571 std::ranges::fill(output, 0.0);
572 return 0;
573 }
574 auto view = interleaved_span
575 | std::views::drop(linear_start)
576 | std::views::take(elements_to_read);
577
578 auto copied = std::ranges::copy(view, output.begin());
579 std::ranges::fill(output.subspan(copied.out - output.begin()), 0.0);
580 return static_cast<uint64_t>(copied.out - output.begin());
581 }
582
584 std::ranges::fill(output, 0.0);
585 return 0;
586 }
587
590 uint64_t loop_length_frames = loop_end_frame - loop_start_frame + 1;
591
592 std::ranges::for_each(
593 std::views::iota(0UZ, elements_to_read),
594 [&](uint64_t i) {
598
599 uint64_t wrapped_frame = ((frame_pos - loop_start_frame) % loop_length_frames) + loop_start_frame;
600 uint64_t wrapped_element = wrapped_frame *
m_num_channels + channel_offset;
601
602 output[i] = (wrapped_element < interleaved_span.size()) ? interleaved_span[wrapped_element] : 0.0;
603 });
604
605 if (elements_to_read < output.size()) {
606 std::ranges::fill(output.subspan(elements_to_read), 0.0);
607 }
608 return elements_to_read;
609}
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)