1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! Wrap an external type to implement [Buf] and [BufMut].

use crate::buf::{Buf, BufMut};
use crate::channel::{Channel, ChannelMut};
use crate::sample::Sample;

/// Wrap a `value` as an interleaved buffer with the given number of channels.
pub fn interleaved<T>(value: T, channels: usize) -> Interleaved<T> {
    Interleaved { value, channels }
}

/// Wrap a `value` as a sequential buffer with the given number of frames. The
/// length of the buffer determines the number of channels.
pub fn sequential<T>(value: T, frames: usize) -> Sequential<T> {
    Sequential { value, frames }
}

/// A wrapper for a type that is interleaved.
pub struct Interleaved<T> {
    value: T,
    channels: usize,
}

impl<T, S> Buf<S> for Interleaved<T>
where
    T: AsRef<[S]>,
    S: Sample,
{
    fn frames(&self) -> usize {
        self.value.as_ref().len() / self.channels
    }

    fn channels(&self) -> usize {
        self.channels
    }

    fn channel(&self, channel: usize) -> Channel<'_, S> {
        if self.channels == 1 && channel == 0 {
            Channel::linear(self.value.as_ref())
        } else {
            Channel::interleaved(self.value.as_ref(), self.channels, channel)
        }
    }
}

impl<T, S> BufMut<S> for Interleaved<T>
where
    T: AsRef<[S]> + AsMut<[S]>,
    S: Sample,
{
    fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, S> {
        if self.channels == 1 && channel == 0 {
            ChannelMut::linear(self.value.as_mut())
        } else {
            ChannelMut::interleaved(self.value.as_mut(), self.channels, channel)
        }
    }

    fn resize(&mut self, frames: usize) {
        if self.value.as_ref().len() / self.channels != frames {
            panic!("buffer cannot be resized")
        }
    }

    fn resize_topology(&mut self, channels: usize, frames: usize) {
        if self.channels != channels || self.value.as_ref().len() / self.channels != frames {
            panic!("buffer cannot be resized")
        }
    }
}

/// A wrapper for a type that is interleaved.
pub struct Sequential<T> {
    value: T,
    frames: usize,
}

impl<T, S> Buf<S> for Sequential<T>
where
    T: AsRef<[S]>,
    S: Sample,
{
    fn frames(&self) -> usize {
        self.frames
    }

    fn channels(&self) -> usize {
        self.value.as_ref().len() / self.frames
    }

    fn channel(&self, channel: usize) -> Channel<'_, S> {
        let value = self.value.as_ref();
        let value = &value[channel * self.frames..];
        let value = &value[..self.frames];

        Channel::linear(value)
    }
}

impl<T, S> BufMut<S> for Sequential<T>
where
    T: AsRef<[S]> + AsMut<[S]>,
    S: Sample,
{
    fn channel_mut(&mut self, channel: usize) -> ChannelMut<'_, S> {
        let value = self.value.as_mut();
        let value = &mut value[channel * self.frames..];
        let value = &mut value[..self.frames];

        ChannelMut::linear(value)
    }

    fn resize(&mut self, frames: usize) {
        if self.frames != frames {
            panic!("buffer cannot be resized")
        }
    }

    fn resize_topology(&mut self, channels: usize, frames: usize) {
        if self.frames != frames || self.value.as_ref().len() / self.frames != channels {
            panic!("buffer cannot be resized")
        }
    }
}