Struct ChannelMut

Source
pub struct ChannelMut<'a, T> { /* private fields */ }
Expand description

The mutable buffer of a single channel.

This doesn’t provide direct access to the underlying buffer, but rather allows us to copy data usinga number of utility functions.

Implementations§

Source§

impl<'a, T> ChannelMut<'a, T>

Source

pub fn linear(buf: &'a mut [T]) -> Self

Construct a mutable linear channel buffer.

The buffer provided as-is constitutes the frames of the channel.

§Examples
use rotary::ChannelMut;

let buf = &mut [1, 3, 5, 7];
let mut channel = ChannelMut::linear(buf);

assert_eq!(channel[1], 3);
assert_eq!(channel[2], 5);

channel[1] *= 4;

assert_eq!(buf, &[1, 12, 5, 7]);
Source

pub fn interleaved(buf: &'a mut [T], channels: usize, channel: usize) -> Self

Construct a mutable interleaved channel buffer.

The provided buffer must be the complete buffer, which includes all other channels. The provided channels argument is the total number of channels in this buffer, and channel indicates which specific channel this buffer belongs to.

Note that this is typically not used directly, but instead through an abstraction which makes sure to provide the correct parameters.

§Examples
use rotary::ChannelMut;

let buf = &mut [1, 2, 3, 4, 5, 6, 7, 8];
let mut channel = ChannelMut::interleaved(buf, 2, 1);

assert_eq!(channel[1], 4);
assert_eq!(channel[2], 6);

channel[1] *= 4;

assert_eq!(buf, &[1, 2, 3, 16, 5, 6, 7, 8]);
Source

pub fn into_ref(self) -> Channel<'a, T>

Convert the current mutable channel into a Channel with the lifetime matching the underlying buffer.

This is required in order to fully convert a ChannelMut into a Channel with the lifetime associated with the buffer, because if we only use as_ref we’ll actually be creating a reference to the mutable buffer instead.

§Examples
use rotary::{Channel, ChannelMut};

struct Foo<'a> {
    channel: ChannelMut<'a, i16>,
}

impl<'a> Foo<'a> {
    fn into_channel(self) -> Channel<'a, i16> {
        self.channel.into_ref()
    }
}

In contrast, this doesn’t compile:

use rotary::{Channel, ChannelMut};

struct Foo<'a> {
    channel: ChannelMut<'a, i16>,
}

impl<'a> Foo<'a> {
    fn into_channel(self) -> Channel<'a, i16> {
        self.channel.as_ref()
    }
}

With the following error:

   error[E0515]: cannot return value referencing local data `self.channel`
   --> test.rs:11:9
    |
 11 |         self.channel.as_ref()
    |         ------------^^^^^^^^^
    |         |
    |         returns a value referencing data owned by the current function
    |         `self.channel` is borrowed here
Source

pub fn as_ref(&self) -> Channel<'_, T>

Construct a new Channel reference with a lifetime associated with the current channel instance instead of the underlying buffer.

§Examples
use rotary::{Channel, ChannelMut};

let buf = &mut [1, 2, 3, 4];
let channel = ChannelMut::linear(buf);

let channel1 = channel.as_ref();
let channel2 = channel1; // Channel is Copy.

assert_eq!(channel1[0], channel2[0]);
Source

pub fn as_mut(&mut self) -> ChannelMut<'_, T>

Construct a new mutable channel reference with a lifetime associated with the current channel instance instead of the underlying buffer.

Reborrowing like this is sometimes necessary, like if you want to pass an instance of ChannelMut directly into another function instead of borrowing it:

use rotary::{BufMut, ChannelMut};

fn takes_channel_mut(mut channel: ChannelMut<'_, i16>) {
    channel[1] = 42;
}

let mut buffer = rotary::interleaved![[0; 4]; 2];
let mut channel = buffer.channel_mut(1);

takes_channel_mut(channel.as_mut());

assert_eq!(channel[1], 42);

Without the reborrow, we would end up moving the channel:

use rotary::{BufMut, ChannelMut};

fn takes_channel_mut(mut channel: ChannelMut<'_, i16>) {
    channel[1] = 42;
}

let mut buffer = rotary::interleaved![[0; 4]; 2];
let mut channel = buffer.channel_mut(1);

takes_channel_mut(channel);

assert_eq!(channel[1], 42);

Causing the following error:

   error[E0382]: borrow of moved value: `channel`
   --> test.rs:10:12
    |
 10 | let mut channel = buffer.channel_mut(1);
    |     ----------- move occurs because `channel` has type `ChannelMut<'_, i16>`,
    |                 which does not implement the `Copy` trait
 11 |
 12 | takes_channel_mut(channel);
    |                   ------- value moved here
 13 |
 14 | assert_eq!(channel[1], 42);
    |            ^^^^^^^ value borrowed here after move
Source

pub fn frames(&self) -> usize

The number of frames in the buffer.

§Examples
use rotary::BufMut;

fn test(buf: &dyn BufMut<f32>) {
    let left = buf.channel(0);
    let right = buf.channel(1);

    assert_eq!(left.frames(), 16);
    assert_eq!(right.frames(), 16);
}

test(&rotary::dynamic![[0.0; 16]; 2]);
test(&rotary::sequential![[0.0; 16]; 2]);
test(&rotary::interleaved![[0.0; 16]; 2]);
Source

pub fn chunks(&self, chunk: usize) -> usize

The number of chunks that can fit with the given size.

§Examples
use rotary::BufMut;

fn test(buf: &dyn BufMut<f32>) {
    let left = buf.channel(0);
    let right = buf.channel(1);

    assert_eq!(left.chunks(4), 4);
    assert_eq!(right.chunks(4), 4);

    assert_eq!(left.chunks(6), 3);
    assert_eq!(right.chunks(6), 3);
}

test(&rotary::dynamic![[0.0; 16]; 2]);
test(&rotary::sequential![[0.0; 16]; 2]);
test(&rotary::interleaved![[0.0; 16]; 2]);
Source

pub fn iter(self) -> Iter<'a, T>

Construct an iterator over the channel.

§Examples
use rotary::{Buf as _, BufMut as _};

let mut left = rotary::interleaved![[0.0f32; 4]; 2];
let mut right = rotary::dynamic![[0.0f32; 4]; 2];

for (l, r) in left.channel_mut(0).iter_mut().zip(right.channel_mut(0)) {
    *l = 1.0;
    *r = 1.0;
}

assert!(left.channel(0).iter().eq(right.channel(0).iter()));

assert_eq!(left.as_slice(), &[1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
assert_eq!(&right[0], &[1.0, 1.0, 1.0, 1.0]);
assert_eq!(&right[1], &[0.0, 0.0, 0.0, 0.0]);
Source

pub fn iter_mut(self) -> IterMut<'a, T>

Construct a mutable iterator over the channel.

§Examples
use rotary::{Buf as _, BufMut as _};

let mut left = rotary::interleaved![[0.0f32; 4]; 2];
let mut right = rotary::dynamic![[0.0f32; 4]; 2];

for (l, r) in left.channel_mut(0).iter_mut().zip(right.channel_mut(0)) {
    *l = 1.0;
    *r = 1.0;
}

assert!(left.channel(0).iter().eq(right.channel(0).iter()));

assert_eq!(left.as_slice(), &[1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
assert_eq!(&right[0], &[1.0, 1.0, 1.0, 1.0]);
assert_eq!(&right[1], &[0.0, 0.0, 0.0, 0.0]);
Source

pub fn skip(self, n: usize) -> Self

Construct a channel buffer where the first n frames are skipped.

§Examples
use rotary::{Buf as _, BufMut as _};

let mut buffer = rotary::Interleaved::with_topology(2, 4);

buffer.channel_mut(0).skip(2).copy_from_slice(&[1.0, 1.0]);

assert_eq!(buffer.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0])
Source

pub fn tail(self, n: usize) -> Self

Construct a channel buffer where the last n frames are included.

§Examples
use rotary::{Buf as _, BufMut as _};

let from = rotary::interleaved![[1.0f32; 4]; 2];
let mut to = rotary::interleaved![[0.0f32; 4]; 2];

to.channel_mut(0).as_mut().tail(2).copy_from(from.channel(0));
assert_eq!(to.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
Source

pub fn limit(self, limit: usize) -> Self

Limit the channel bufferto limit number of frames.

§Examples
use rotary::{Buf as _, BufMut as _};

let from = rotary::interleaved![[1.0f32; 4]; 2];
let mut to = rotary::interleaved![[0.0f32; 4]; 2];

to.channel_mut(0).limit(2).copy_from(from.channel(0));
assert_eq!(to.as_slice(), &[1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
Source

pub fn chunk(self, n: usize, len: usize) -> Self

Construct a range of frames corresponds to the chunk with len and position n.

Which is the range n * len .. n * len + len.

§Examples
use rotary::{Buf as _, BufMut as _};

let from = rotary::interleaved![[1.0f32; 4]; 2];
let mut to = rotary::interleaved![[0.0f32; 4]; 2];

to.channel_mut(0).chunk(1, 2).copy_from(from.channel(0));
assert_eq!(to.as_slice(), &[0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]);
§Examples
use rotary::Buf;

fn test(buf: &dyn Buf<f32>) {
    let channel = buf.channel(0);

    let mut buf = vec![0.0; 4];
    channel.chunk(3, 4).copy_into_slice(&mut buf[..]);

    assert!(buf.iter().all(|f| *f == 1.0));
}

test(&rotary::dynamic![[1.0; 16]; 2]);
test(&rotary::sequential![[1.0; 16]; 2]);
test(&rotary::interleaved![[1.0; 16]; 2]);
Source

pub fn copy_from_slice(&mut self, buf: &[T])
where T: Copy,

Copy from the given slice.

§Examples
use rotary::BufMut;

fn test(buf: &mut dyn BufMut<f32>) {
    buf.channel_mut(0).copy_from_slice(&[1.0; 4][..]);

    let mut out = vec![0.0; 8];
    buf.channel(0).copy_into_slice(&mut out);

    assert_eq!(out, vec![1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]);
}

test(&mut rotary::dynamic![[0.0; 8]; 2]);
test(&mut rotary::sequential![[0.0; 8]; 2]);
test(&mut rotary::interleaved![[0.0; 8]; 2]);
Source

pub fn copy_from_iter<I>(&mut self, iter: I)
where I: IntoIterator<Item = T>,

Copy a chunked destination from an iterator.

§Examples
use rotary::BufMut;

fn test(buf: &mut dyn BufMut<f32>) {
    buf.channel_mut(0).skip(2).copy_from_iter(vec![1.0; 4]);

    let mut out = vec![0.0; 8];
    buf.channel(0).copy_into_slice(&mut out);

    assert_eq!(out, vec![0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0]);
}

test(&mut rotary::dynamic![[0.0; 8]; 2]);
test(&mut rotary::sequential![[0.0; 8]; 2]);
test(&mut rotary::interleaved![[0.0; 8]; 2]);
use rotary::BufMut;

fn test(buf: &mut dyn BufMut<f32>) {
    buf.channel_mut(0).skip(2).chunk(0, 2).copy_from_iter(vec![1.0; 4]);

    let mut out = vec![0.0; 8];
    buf.channel(0).copy_into_slice(&mut out);

    assert_eq!(out, vec![0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]);
}

test(&mut rotary::dynamic![[0.0; 8]; 2]);
test(&mut rotary::sequential![[0.0; 8]; 2]);
test(&mut rotary::interleaved![[0.0; 8]; 2]);
Source

pub fn copy_from(&mut self, from: Channel<'_, T>)
where T: Copy,

Copy this channel from another.

§Examples
use rotary::{Buf as _, BufMut as _};

let from = rotary::dynamic![[1.0f32; 4]; 2];
let mut to = rotary::interleaved![[0.0f32; 4]; 3];

to.channel_mut(0).copy_from(from.channel(1));
assert_eq!(to.as_slice(), &[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]);
Source

pub fn translate_from<U>(&mut self, from: Channel<'_, U>)
where U: Copy, T: Translate<U>,

Translate this channel from another.

This will translate each sample in the channel through the appropriate Translate implementation.

This is used for converting a buffer containing one type of sample into another.

§Examples
use rotary::{Buf as _, BufMut as _};

let from = rotary::dynamic![[u16::MAX; 4]; 2];
let mut to = rotary::interleaved![[0.0f32; 4]; 3];

to.channel_mut(0).translate_from(from.channel(1));
assert_eq!(to.as_slice(), &[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0]);

Trait Implementations§

Source§

impl<'a, T: Debug> Debug for ChannelMut<'a, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Index<usize> for ChannelMut<'_, T>

Source§

type Output = T

The returned type after indexing.
Source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<T> IndexMut<usize> for ChannelMut<'_, T>

Get a mutable reference to the frame at the given index.

§Panics

Panics if the given frame is out of bounds for this channel.

See frames.

§Examples

use rotary::BufMut;

fn test(buf: &mut dyn BufMut<f32>) {
    buf.channel_mut(0)[1] = 1.0;
    buf.channel_mut(0)[7] = 1.0;

    let mut out = vec![0.0; 8];
    buf.channel(0).copy_into_slice(&mut out);

    assert_eq!(out, vec![0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
}

test(&mut rotary::dynamic![[0.0; 8]; 2]);
test(&mut rotary::sequential![[0.0; 8]; 2]);
test(&mut rotary::interleaved![[0.0; 8]; 2]);
Source§

fn index_mut(&mut self, index: usize) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl<'a, T> IntoIterator for &'a mut ChannelMut<'_, T>

Source§

type Item = &'a mut T

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, T> IntoIterator for ChannelMut<'a, T>

Source§

type Item = &'a mut T

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

impl<'a, T> Freeze for ChannelMut<'a, T>

§

impl<'a, T> RefUnwindSafe for ChannelMut<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for ChannelMut<'a, T>
where T: Send,

§

impl<'a, T> Sync for ChannelMut<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for ChannelMut<'a, T>

§

impl<'a, T> !UnwindSafe for ChannelMut<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.