diff --git a/examples/gain/src/lib.rs b/examples/gain/src/lib.rs index c81f9ad..56835aa 100644 --- a/examples/gain/src/lib.rs +++ b/examples/gain/src/lib.rs @@ -115,7 +115,7 @@ impl Processor for GainProcessor { fn reset(&mut self) {} fn process(&mut self, buffers: Buffers, events: Events) { - let buffer = buffers.collect::().unwrap(); + let mut buffer = buffers.collect::().unwrap(); for (mut buffer, events) in buffer.split_at_events(events) { for event in events { match event.data { diff --git a/src/buffers.rs b/src/buffers.rs index 9aa6cba..6a3d996 100644 --- a/src/buffers.rs +++ b/src/buffers.rs @@ -2,14 +2,12 @@ use std::marker::PhantomData; use std::ops::{Index, IndexMut, Range}; use std::{array, slice}; -mod buffer_view; pub mod collect; pub mod iter; -pub use buffer_view::{BufferView, Offset}; - +use crate::events::Events; use collect::FromBuffers; -use iter::IntoSamples; +use iter::{BlockIterator, IntoBlocks, IntoSamples}; #[derive(Copy, Clone, Eq, PartialEq)] pub enum BufferType { @@ -137,6 +135,14 @@ impl<'a, 'b> Buffers<'a, 'b> { pub fn samples<'c>(&'c mut self) -> iter::SamplesIter<'a, 'c> { self.reborrow().into_samples() } + + #[inline] + pub fn split_at_events<'c, 'e>( + &'c mut self, + events: Events<'e>, + ) -> iter::SplitAtEvents<'e, iter::BlocksIter<'a, 'c>> { + self.reborrow().into_blocks().split_at_events(events) + } } impl<'a, 'b> IntoIterator for Buffers<'a, 'b> { @@ -334,6 +340,14 @@ impl<'a, 'b> Buffer<'a, 'b> { pub fn samples(&self) -> iter::SampleIter<'a, 'b> { self.into_samples() } + + #[inline] + pub fn split_at_events<'e>( + &self, + events: Events<'e>, + ) -> iter::SplitAtEvents<'e, iter::BlockIter<'a, 'b>> { + self.into_blocks().split_at_events(events) + } } impl<'a, 'b> Index for Buffer<'a, 'b> { @@ -501,6 +515,14 @@ impl<'a, 'b> BufferMut<'a, 'b> { pub fn samples<'c>(&'c mut self) -> iter::SampleIterMut<'a, 'c> { self.reborrow().into_samples() } + + #[inline] + pub fn split_at_events<'c, 'e>( + &'c mut self, + events: Events<'e>, + ) -> iter::SplitAtEvents<'e, iter::BlockIterMut<'a, 'c>> { + self.reborrow().into_blocks().split_at_events(events) + } } impl<'a, 'b> Index for BufferMut<'a, 'b> { diff --git a/src/buffers/buffer_view.rs b/src/buffers/buffer_view.rs deleted file mode 100644 index 63e6317..0000000 --- a/src/buffers/buffer_view.rs +++ /dev/null @@ -1,113 +0,0 @@ -use super::iter::SplitAtEvents; -use super::{Buffer, BufferData, BufferMut, Buffers}; -use crate::events::Events; - -pub trait Offset { - unsafe fn offset(self, count: isize) -> Self; -} - -pub trait BufferView: Sized { - type Raw: Copy + Clone + Offset; - - fn into_raw_parts(self) -> (Self::Raw, usize); - unsafe fn from_raw_parts(raw: Self::Raw, len: usize) -> Self; - - #[inline] - fn split_at_events<'e>(self, events: Events<'e>) -> SplitAtEvents<'e, Self> { - SplitAtEvents::new(self, events) - } -} - -#[derive(Copy, Clone)] -pub struct RawBuffers<'a> { - pub buffers: &'a [BufferData], - pub ptrs: &'a [*mut f32], - pub offset: isize, -} - -impl<'a> Offset for RawBuffers<'a> { - #[inline] - unsafe fn offset(self, count: isize) -> Self { - RawBuffers { - offset: self.offset + count, - ..self - } - } -} - -impl<'a, 'b> BufferView for Buffers<'a, 'b> { - type Raw = RawBuffers<'a>; - - #[inline] - fn into_raw_parts(self) -> (Self::Raw, usize) { - ( - RawBuffers { - buffers: self.buffers, - ptrs: self.ptrs, - offset: self.offset, - }, - self.len, - ) - } - - #[inline] - unsafe fn from_raw_parts(raw: Self::Raw, len: usize) -> Self { - Buffers::from_raw_parts(raw.buffers, raw.ptrs, raw.offset, len) - } -} - -#[derive(Copy, Clone)] -pub struct RawBuffer<'a> { - pub ptrs: &'a [*mut f32], - pub offset: isize, -} - -impl<'a> Offset for RawBuffer<'a> { - #[inline] - unsafe fn offset(self, count: isize) -> Self { - RawBuffer { - offset: self.offset + count, - ..self - } - } -} - -impl<'a, 'b> BufferView for Buffer<'a, 'b> { - type Raw = RawBuffer<'a>; - - #[inline] - fn into_raw_parts(self) -> (Self::Raw, usize) { - ( - RawBuffer { - ptrs: self.ptrs, - offset: self.offset, - }, - self.len, - ) - } - - #[inline] - unsafe fn from_raw_parts(raw: Self::Raw, len: usize) -> Self { - Buffer::from_raw_parts(raw.ptrs, raw.offset, len) - } -} - -impl<'a, 'b> BufferView for BufferMut<'a, 'b> { - type Raw = RawBuffer<'a>; - - #[inline] - fn into_raw_parts(self) -> (Self::Raw, usize) { - ( - RawBuffer { - ptrs: self.ptrs, - offset: self.offset, - }, - self.len, - ) - } - - #[inline] - unsafe fn from_raw_parts(raw: Self::Raw, len: usize) -> Self { - BufferMut::from_raw_parts(raw.ptrs, raw.offset, len) - } -} diff --git a/src/buffers/iter.rs b/src/buffers/iter.rs index 9bb00a7..5bac1da 100644 --- a/src/buffers/iter.rs +++ b/src/buffers/iter.rs @@ -1,8 +1,6 @@ use std::marker::PhantomData; -use super::{ - Buffer, BufferData, BufferMut, BufferView, Buffers, Offset, Sample, SampleMut, Samples, -}; +use super::{Buffer, BufferData, BufferMut, Buffers, Sample, SampleMut, Samples}; use crate::events::Events; pub trait IntoSamples { @@ -146,41 +144,204 @@ impl<'a, 'b> Iterator for SampleIterMut<'a, 'b> { } } -pub struct SplitAtEvents<'e, B: BufferView> { - raw: B::Raw, - len: usize, - events: Events<'e>, - time: i64, - _marker: PhantomData, +pub trait IntoBlocks { + type Block; + type BlockIter: BlockIterator; + + fn into_blocks(self) -> Self::BlockIter; } -impl<'e, B: BufferView> SplitAtEvents<'e, B> { +pub trait BlockIterator { + type Block; + + fn len(&self) -> usize; + fn next_block(&mut self, len: usize) -> Self::Block; + #[inline] - pub(crate) fn new(buffer: B, events: Events<'e>) -> SplitAtEvents<'e, B> { - let (raw, len) = buffer.into_raw_parts(); + fn split_at_events<'e>(self, events: Events<'e>) -> SplitAtEvents<'e, Self> + where + Self: Sized, + { + SplitAtEvents::new(self, events) + } +} + +impl<'a, 'b> IntoBlocks for Buffers<'a, 'b> { + type Block = Buffers<'a, 'b>; + type BlockIter = BlocksIter<'a, 'b>; + + #[inline] + fn into_blocks(self) -> Self::BlockIter { + BlocksIter::new(self) + } +} + +pub struct BlocksIter<'a, 'b> { + buffers: &'a [BufferData], + ptrs: &'a [*mut f32], + offset: isize, + end: isize, + _marker: PhantomData<&'b mut f32>, +} +impl<'a, 'b> BlocksIter<'a, 'b> { + fn new(buffers: Buffers<'a, 'b>) -> BlocksIter<'a, 'b> { + BlocksIter { + buffers: buffers.buffers, + ptrs: buffers.ptrs, + offset: buffers.offset, + end: buffers.offset + buffers.len as isize, + _marker: buffers._marker, + } + } +} + +impl<'a, 'b> BlockIterator for BlocksIter<'a, 'b> { + type Block = Buffers<'a, 'b>; + + #[inline] + fn len(&self) -> usize { + (self.end - self.offset) as usize + } + + #[inline] + fn next_block(&mut self, len: usize) -> Self::Block { + let remainder = self.len(); + let len = if len > remainder { remainder } else { len }; + + let offset = self.offset; + self.offset = self.offset + len as isize; + + unsafe { Buffers::from_raw_parts(self.buffers, self.ptrs, offset, len) } + } +} + +impl<'a, 'b> IntoBlocks for Buffer<'a, 'b> { + type Block = Buffer<'a, 'b>; + type BlockIter = BlockIter<'a, 'b>; + + #[inline] + fn into_blocks(self) -> Self::BlockIter { + BlockIter::new(self) + } +} + +pub struct BlockIter<'a, 'b> { + ptrs: &'a [*mut f32], + offset: isize, + end: isize, + _marker: PhantomData<&'b f32>, +} + +impl<'a, 'b> BlockIter<'a, 'b> { + fn new(buffer: Buffer<'a, 'b>) -> BlockIter<'a, 'b> { + BlockIter { + ptrs: buffer.ptrs, + offset: buffer.offset, + end: buffer.offset + buffer.len as isize, + _marker: buffer._marker, + } + } +} + +impl<'a, 'b> BlockIterator for BlockIter<'a, 'b> { + type Block = Buffer<'a, 'b>; + + #[inline] + fn len(&self) -> usize { + (self.end - self.offset) as usize + } + + #[inline] + fn next_block(&mut self, len: usize) -> Self::Block { + let remainder = self.len(); + let len = if len > remainder { remainder } else { len }; + + let offset = self.offset; + self.offset = self.offset + len as isize; + + unsafe { Buffer::from_raw_parts(self.ptrs, offset, len) } + } +} + +impl<'a, 'b> IntoBlocks for BufferMut<'a, 'b> { + type Block = BufferMut<'a, 'b>; + type BlockIter = BlockIterMut<'a, 'b>; + + #[inline] + fn into_blocks(self) -> Self::BlockIter { + BlockIterMut::new(self) + } +} + +pub struct BlockIterMut<'a, 'b> { + ptrs: &'a [*mut f32], + offset: isize, + end: isize, + _marker: PhantomData<&'b mut f32>, +} + +impl<'a, 'b> BlockIterMut<'a, 'b> { + fn new(buffer: BufferMut<'a, 'b>) -> BlockIterMut<'a, 'b> { + BlockIterMut { + ptrs: buffer.ptrs, + offset: buffer.offset, + end: buffer.offset + buffer.len as isize, + _marker: buffer._marker, + } + } +} + +impl<'a, 'b> BlockIterator for BlockIterMut<'a, 'b> { + type Block = BufferMut<'a, 'b>; + + #[inline] + fn len(&self) -> usize { + (self.end - self.offset) as usize + } + + #[inline] + fn next_block(&mut self, len: usize) -> Self::Block { + let remainder = self.len(); + let len = if len > remainder { remainder } else { len }; + + let offset = self.offset; + self.offset = self.offset + len as isize; + + unsafe { BufferMut::from_raw_parts(self.ptrs, offset, len) } + } +} + +pub struct SplitAtEvents<'e, B> { + blocks: B, + events: Events<'e>, + time: i64, +} + +impl<'e, B> SplitAtEvents<'e, B> { + fn new(blocks: B, events: Events<'e>) -> SplitAtEvents<'e, B> { SplitAtEvents { - raw, - len, + blocks, events, time: 0, - _marker: PhantomData, } } } -impl<'e, B: BufferView> Iterator for SplitAtEvents<'e, B> { - type Item = (B, Events<'e>); +impl<'e, B: BlockIterator> Iterator for SplitAtEvents<'e, B> { + type Item = (B::Block, Events<'e>); #[inline] - fn next(&mut self) -> Option<(B, Events<'e>)> { - if self.len == 0 { + fn next(&mut self) -> Option<(B::Block, Events<'e>)> { + let len = self.blocks.len(); + + if len == 0 { if self.events.len() == 0 { return None; } // If we've reached the end of the buffer, yield all remaining events in one go: - let buffers = unsafe { B::from_raw_parts(self.raw, 0) }; + let buffers = self.blocks.next_block(0); let events = self.events; self.events = Events::new(&[]); @@ -190,11 +351,11 @@ impl<'e, B: BufferView> Iterator for SplitAtEvents<'e, B> { // Find the first event with a timestamp greater than the current one: let mut event_count = 0; - let mut split = self.len; + let mut split = len; for event in self.events { if event.time > self.time { let offset = (event.time - self.time) as usize; - if offset < self.len { + if offset < len { split = offset; } @@ -206,9 +367,7 @@ impl<'e, B: BufferView> Iterator for SplitAtEvents<'e, B> { event_count += 1; } - let buffer = unsafe { B::from_raw_parts(self.raw, split) }; - self.raw = unsafe { self.raw.offset(split as isize) }; - self.len -= split; + let buffer = self.blocks.next_block(split); let events = self.events.slice(..event_count).unwrap(); self.events = self.events.slice(event_count..).unwrap();