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
/// Trait implemented for buffers which are linearly stored in memory.
///
/// This allows us to reason about a specific number of frames, so that the
/// buffer can safely make sure that a given required number of frames are
/// available in the buffer, and it allows us to access the underlying buffer.
///
/// This is usually used in combination with other traits, such as
/// [AsInterleaved][crate::AsInterleaved] to allow for generically accessing a
/// fixed linear buffer with a specific topology.
pub trait InterleavedBuf {
    /// Make sure that the buffer has reserved exactly the given number of
    /// frames.
    ///
    /// # Panics
    ///
    /// Panics if the underlying buffer cannot be grown to accomodate the given
    /// number of frames.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use audio::{Buf, ExactSizeBuf, InterleavedBuf};
    ///
    /// fn test<B>(mut buffer: B) where B: InterleavedBuf {
    ///     buffer.reserve_frames(4);
    ///     buffer.set_topology(2, 2);
    /// }
    ///
    /// // Note: a zero-sized buffer.
    /// let mut buffer = audio::interleaved![[0; 0]; 0];
    /// test(&mut buffer);
    ///
    /// assert_eq!(buffer.channels(), 2);
    /// assert_eq!(buffer.frames(), 2);
    /// assert_eq!(buffer.as_slice(), &[0, 0, 0, 0]);
    ///
    /// let mut buffer = [1, 2, 3, 4, 5, 6, 7, 8];
    /// let mut buffer = audio::wrap::interleaved(&mut buffer[..], 1);
    /// test(&mut buffer);
    ///
    /// assert_eq!(buffer.channels(), 2);
    /// assert_eq!(buffer.frames(), 2);
    /// assert_eq!(buffer.into_inner(), &[1, 2, 3, 4]);
    /// ```
    fn reserve_frames(&mut self, frames: usize);

    /// Set the buffer to have the given topology.
    ///
    /// This function will never reallocate the underlying buffer.
    ///
    /// # Panics
    ///
    /// Calling [set_topology][InterleavedBuf::set_topology] will fail if the
    /// underlying buffer doesn't support the specified topology. Like if it's
    /// too small.
    ///
    /// If you want to use a growable buffer use
    /// [ResizableBuf::resize_topology][crate::ResizableBuf::resize_topology]
    /// instead.
    ///
    /// ```rust,should_panic
    /// use audio::{Channels, ExactSizeBuf, InterleavedBuf};
    ///
    /// fn test<B>(mut buffer: B) where B: InterleavedBuf {
    ///     buffer.set_topology(2, 4); // panics because buffer is zero-sized.
    /// }
    ///
    /// test(audio::interleaved![[0; 0]; 4]);
    /// ```
    ///
    /// # Examples
    ///
    /// ```rust
    /// use audio::{Channels, ExactSizeBuf, InterleavedBuf};
    ///
    /// fn test<B>(mut buffer: B) where B: InterleavedBuf {
    ///     buffer.set_topology(2, 4);
    /// }
    ///
    /// // Note: a zero-sized buffer.
    /// let mut buffer = audio::interleaved![[4; 2]; 4];
    /// assert_eq!(buffer.channels(), 4);
    /// assert_eq!(buffer.frames(), 2);
    ///
    /// test(&mut buffer);
    ///
    /// assert_eq!(buffer.channels(), 2);
    /// assert_eq!(buffer.frames(), 4);
    /// ```
    fn set_topology(&mut self, channels: usize, frames: usize);
}

impl<B> InterleavedBuf for &mut B
where
    B: ?Sized + InterleavedBuf,
{
    fn reserve_frames(&mut self, frames: usize) {
        (**self).reserve_frames(frames);
    }

    fn set_topology(&mut self, channels: usize, frames: usize) {
        (**self).set_topology(channels, frames);
    }
}