mod convert;
pub use convert::{ConvertFrom, ConvertTo};
mod frame;
pub use frame::Frame;
mod container;
pub use container::{Container, MutableContainer};
mod storage;
pub use storage::{Channels, Interleaved, Mono};
use storage::{Storage, StorageMut};
extern crate alloc;
use core::ops::{
AddAssign, DivAssign, Index, IndexMut, MulAssign, Neg, RemAssign, ShlAssign, ShrAssign,
SubAssign,
};
use alloc::boxed::Box;
use num_traits::MulAddAssign;
#[derive(Debug)]
pub struct Buffer<S> {
storage: S,
}
pub type MonoBuffer<T> = Buffer<Mono<Box<[T]>>>;
pub type BufferByChannel<T> = Buffer<Channels<Box<[T]>>>;
pub type InterleavedBuffer<T> = Buffer<Interleaved<Box<[T]>>>;
pub type MonoBufferRef<'a, T> = Buffer<Mono<&'a [T]>>;
pub type BufferByChannelRef<'a, T> = Buffer<Channels<&'a [T]>>;
pub type InterleavedBufferRef<'a, T> = Buffer<Interleaved<&'a [T]>>;
pub type MonoBufferMut<'a, T> = Buffer<Mono<&'a mut [T]>>;
pub type BufferByChannelMut<'a, T> = Buffer<Channels<&'a mut [T]>>;
pub type InterleavedBufferMut<'a, T> = Buffer<Interleaved<&'a mut [T]>>;
impl<T: Default + Clone> MonoBuffer<T> {
pub fn new(blocksize: usize) -> Self {
Self {
storage: Mono::new(blocksize),
}
}
}
impl<T: Default + Clone> Buffer<Interleaved<Box<[T]>>> {
pub fn new(nchannels: usize, blocksize: usize) -> Self {
Self {
storage: Interleaved::new(nchannels, blocksize),
}
}
}
impl<T: Default + Clone> Buffer<Channels<Box<[T]>>> {
pub fn new(nchannels: usize, blocksize: usize) -> Self {
Self {
storage: Channels::new(nchannels, blocksize),
}
}
}
impl<'a, T> Buffer<Mono<&'a [T]>> {
pub fn new(samples: &'a [T]) -> Self {
Self {
storage: samples.into(),
}
}
}
impl<'a, T> Buffer<Channels<&'a [T]>> {
pub fn new(samples: &'a [T], nchannels: usize) -> Self {
Self {
storage: Channels::new_ref(samples, nchannels),
}
}
}
impl<'a, T> Buffer<Interleaved<&'a [T]>> {
pub fn new(samples: &'a [T], nchannels: usize) -> Self {
Self {
storage: Interleaved::new_ref(samples, nchannels),
}
}
}
impl<'a, T> Buffer<Mono<&'a mut [T]>> {
pub fn new(samples: &'a mut [T]) -> Self {
Self {
storage: samples.into(),
}
}
}
impl<'a, T> Buffer<Channels<&'a mut [T]>> {
pub fn new(samples: &'a mut [T], nchannels: usize) -> Self {
Self {
storage: Channels::new_mut(samples, nchannels),
}
}
}
impl<'a, T> Buffer<Interleaved<&'a mut [T]>> {
pub fn new(samples: &'a mut [T], nchannels: usize) -> Self {
Self {
storage: Interleaved::new_mut(samples, nchannels),
}
}
pub fn into_ref(self) -> Buffer<Interleaved<&'a [T]>> {
Buffer {storage: self.storage.into_ref()}
}
}
impl<'a, T> Buffer<Mono<&'a [T]>> {
pub fn mono_ref(samples: &'a [T]) -> Self {
Self::new(samples)
}
}
impl<'a, T> Buffer<Mono<&'a mut [T]>> {
pub fn mono_mut(samples: &'a mut [T]) -> Self {
Self::new(samples)
}
}
impl<C: Container> Buffer<Mono<C>> {
pub fn len(&self) -> usize {
self.storage.len()
}
pub fn is_empty(&self) -> bool {
self.storage.is_empty()
}
pub fn as_slice(&self) -> &[C::Item] {
self.storage.as_slice()
}
}
impl<C: MutableContainer> Buffer<Mono<C>> {
pub fn as_slice_mut(&mut self) -> &mut [C::Item] {
self.storage.as_slice_mut()
}
}
impl<C: MutableContainer> Buffer<Mono<C>>
where
C::Item: Clone,
{
pub fn fill(&mut self, value: C::Item) {
self.storage.fill(value);
}
}
impl<C: Container> Buffer<Interleaved<C>> {
pub fn frames(&self) -> impl ExactSizeIterator<Item = Frame<&[<C as Container>::Item]>> {
self.storage.frames()
}
}
impl<C: MutableContainer> Buffer<Interleaved<C>> {
pub fn frames_mut(&mut self) -> impl ExactSizeIterator<Item = Frame<&mut [<C as Container>::Item]>> {
self.storage.frames_mut()
}
}
impl<C: Container> Buffer<Channels<C>> {
pub fn channels(&self) -> impl ExactSizeIterator<Item = &Buffer<Mono<C>>> {
self.storage.channels()
}
pub fn get(&self, index: usize) -> Option<&Buffer<Mono<C>>> {
self.storage.get(index)
}
pub fn left(&self) -> Option<&Buffer<Mono<C>>> {
self.get(0)
}
pub fn right(&self) -> Option<&Buffer<Mono<C>>> {
self.get(1)
}
}
impl<C: MutableContainer> Buffer<Channels<C>> {
pub fn channels_mut(&mut self) -> impl ExactSizeIterator<Item = &mut Buffer<Mono<C>>> {
self.storage.channels_mut()
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut Buffer<Mono<C>>> {
self.storage.get_mut(index)
}
pub fn left_mut(&mut self) -> Option<&mut Buffer<Mono<C>>> {
self.get_mut(0)
}
pub fn right_mut(&mut self) -> Option<&mut Buffer<Mono<C>>> {
self.get_mut(1)
}
}
impl<S: Storage> Buffer<S> {
pub fn samples(&self) -> impl Iterator<Item = &S::Item> {
self.storage.samples()
}
}
impl<S: StorageMut> Buffer<S> {
pub fn samples_mut(&mut self) -> impl Iterator<Item = &mut S::Item> {
self.storage.samples_mut()
}
}
impl<S: StorageMut> Buffer<S>
where S::Item: Clone {
pub fn copy_from(&mut self, other: &Self) {
for (a, b) in self.samples_mut().zip(other.samples()) {
*a = b.clone();
}
}
}
impl<S: Storage> Index<usize> for Buffer<S>
where
S: Index<usize>,
{
type Output = S::Output;
fn index(&self, index: usize) -> &Self::Output {
self.storage.index(index)
}
}
impl<S: StorageMut> IndexMut<usize> for Buffer<S>
where
S: IndexMut<usize>,
{
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.storage.index_mut(index)
}
}
impl<S> Clone for Buffer<S>
where
S: Clone,
{
fn clone(&self) -> Self {
Self {
storage: self.storage.clone(),
}
}
}
impl<S1, S2> ConvertFrom<&Buffer<S2>> for Buffer<S1>
where
S1: StorageMut,
S2: Storage,
S1: for<'a> ConvertFrom<&'a S2>,
{
fn convert_from(&mut self, other: &Buffer<S2>) {
self.storage.convert_from(&other.storage);
}
}
impl<F2, S> ConvertFrom<&[F2]> for Buffer<S>
where
S: StorageMut,
S::Item: ConvertFrom<F2>,
F2: Copy,
{
fn convert_from(&mut self, other: &[F2]) {
for (o, i) in self.storage.samples_mut().zip(other.iter()) {
o.convert_from(*i);
}
}
}
impl<F, S> ConvertFrom<&Buffer<S>> for &mut [F]
where
S: Storage,
S::Item: Copy,
F: ConvertFrom<S::Item>,
{
fn convert_from(&mut self, other: &Buffer<S>) {
for (o, i) in self.iter_mut().zip(other.storage.samples()) {
o.convert_from(*i);
}
}
}
macro_rules! impl_op {
($assign_trait:ident, $assign_method:ident) => {
impl<F, S> $assign_trait<F> for Buffer<S>
where
F: $assign_trait<F> + Copy + Default,
S: StorageMut<Item = F>,
{
fn $assign_method(&mut self, rhs: F) {
for s in self.samples_mut() {
(*s).$assign_method(rhs);
}
}
}
impl<F, S> $assign_trait<F> for &mut Buffer<S>
where
F: $assign_trait<F> + Copy + Default,
S: StorageMut<Item = F>,
{
fn $assign_method(&mut self, rhs: F) {
for s in self.samples_mut() {
(*s).$assign_method(rhs);
}
}
}
impl<F, S> $assign_trait<&Buffer<S>> for Buffer<S>
where
F: $assign_trait<F> + Copy + Default,
S: StorageMut<Item = F>,
{
fn $assign_method(&mut self, rhs: &Buffer<S>) {
for (s, o) in self.samples_mut().zip(rhs.storage.samples()) {
(*s).$assign_method(*o);
}
}
}
};
}
impl_op!(AddAssign, add_assign);
impl_op!(SubAssign, sub_assign);
impl_op!(MulAssign, mul_assign);
impl_op!(DivAssign, div_assign);
impl_op!(RemAssign, rem_assign);
impl_op!(ShlAssign, shl_assign);
impl_op!(ShrAssign, shr_assign);
impl<F, S> MulAddAssign<F, F> for Buffer<S>
where
F: Copy + Default + MulAddAssign<F>,
S: StorageMut<Item = F>,
{
fn mul_add_assign(&mut self, a: F, b: F) {
for s in self.storage.samples_mut() {
s.mul_add_assign(a, b);
}
}
}
impl<F, S> MulAddAssign<&Buffer<S>, F> for Buffer<S>
where
Self: for<'a> MulAssign<&'a Buffer<S>> + AddAssign<F>,
F: Copy + Default,
S: StorageMut<Item = F>,
{
fn mul_add_assign(&mut self, a: &Buffer<S>, b: F) {
self.mul_assign(a);
self.add_assign(b);
}
}
impl<F, S> MulAddAssign<F, &Buffer<S>> for Buffer<S>
where
Self: MulAssign<F> + for<'a> AddAssign<&'a Buffer<S>>,
F: Copy + Default,
S: StorageMut<Item = F>,
{
fn mul_add_assign(&mut self, a: F, b: &Buffer<S>) {
self.mul_assign(a);
self.add_assign(b);
}
}
impl<F, S> MulAddAssign<&Buffer<S>, &Buffer<S>> for Buffer<S>
where
Self: for<'a> MulAssign<&'a Buffer<S>> + for<'a> AddAssign<&'a Buffer<S>>,
F: Copy + Default + MulAddAssign<F, F>,
S: StorageMut<Item = F>,
{
#[inline(never)]
fn mul_add_assign(&mut self, a: &Buffer<S>, b: &Buffer<S>) {
self.mul_assign(a);
self.add_assign(b);
}
}
impl<F, S> Neg for Buffer<S>
where
F: Neg<Output = F> + Copy + Default,
S: StorageMut<Item = F>,
{
type Output = Self;
fn neg(mut self) -> Self::Output {
for s in self.storage.samples_mut() {
*s = s.neg();
}
self
}
}