1
0
Fork 0

Add a per-sample per-channel iterator for blocks

This commit is contained in:
Robbert van der Helm 2022-03-09 19:27:08 +01:00
parent dfb2407698
commit 5041f959b7

View file

@ -26,12 +26,16 @@ pub struct Buffer<'a> {
// Per-sample per-channel iterators
/// An iterator over all samples in the buffer, yielding iterators over each channel for every
/// sample. This iteration order offers good cache locality for per-sample access.
/// An iterator over all samples in a buffer or block, yielding iterators over each channel for
/// every sample. This iteration order offers good cache locality for per-sample access.
pub struct SamplesIter<'slice, 'sample: 'slice> {
/// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]],
pub(self) current_sample: usize,
/// The last sample index to iterate over plus one. Would be equal to `buffers.len()` when
/// iterating over an entire buffer, but this can also be used to iterate over smaller blocks in
/// a similar fashion.
pub(self) samples_end: usize,
pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>,
}
@ -74,6 +78,7 @@ pub struct Block<'slice, 'sample: 'slice> {
/// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]],
pub(self) current_block_start: usize,
/// The index of the last sample in the block plus one.
pub(self) current_block_end: usize,
pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>,
}
@ -94,7 +99,8 @@ impl<'slice, 'sample> Iterator for SamplesIter<'slice, 'sample> {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.current_sample < unsafe { (*self.buffers)[0].len() } {
// This can iterate over both the entire buffer or over a smaller sample slice of it
if self.current_sample < self.samples_end {
let channels = ChannelSamples {
buffers: self.buffers,
current_sample: self.current_sample,
@ -286,6 +292,7 @@ impl<'a> Buffer<'a> {
SamplesIter {
buffers: self.output_slices.as_mut_slice(),
current_sample: 0,
samples_end: self.len(),
_marker: PhantomData,
}
}
@ -498,6 +505,17 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
}
}
/// Iterate over this block on a per-sample per-channel basis. This is identical to
/// [`Buffer::iter_mut()`] but for a smaller block instead of the entire buffer
pub fn iter_samples(&mut self) -> SamplesIter<'slice, 'sample> {
SamplesIter {
buffers: self.buffers,
current_sample: self.current_block_start,
samples_end: self.current_block_end,
_marker: self._marker,
}
}
/// Access a channel by index. Useful when you would otherwise iterate over this [`Block`]
/// multiple times.
#[inline]