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
/// Trait used to govern sequential reading of an audio buffer.
///
/// This is the "in" part of "buffered I/O". It allows for buffers to govern
/// which slice of frames in them has been read so that operations can be
/// performed in multiple stages.
///
/// This can be accomplished manually using available buffer combinators such as
/// [Buf::tail][crate::Buf::tail]. But buffered I/O allows us to do this in a
/// much more structured fashion.
///
/// # Examples
///
/// ```
/// use audio::ReadBuf;
/// use audio::{io, wrap};
/// # fn send_data(buf: &mut [i16]) {}
///
/// // A simple mutable buffer we want to write to. Fits 2 channels with 64
/// // frames each.
/// let mut to = [0i16; 128];
///
/// // A buffer we want to read from. 2 channels with 512 frames each.
/// let from = audio::interleaved![[0i16; 512]; 2];
/// let mut from = io::Read::new(from);
///
/// let mut steps = 0;
///
/// while from.has_remaining() {
///     // Wrap the output buffer according to format so it can be written to
///     // correctly.
///     io::copy_remaining(&mut from, wrap::interleaved(&mut to[..], 2));
///
///     send_data(&mut to[..]);
///
///     steps += 1;
/// }
///
/// // We needed to write 8 times to copy our entire buffer.
/// assert_eq!(steps, 8);
/// ```
pub trait ReadBuf {
    /// Test if there are any remaining frames to read.
    ///
    /// # Examples
    ///
    /// ```
    /// use audio::ReadBuf;
    ///
    /// let mut buf = audio::wrap::interleaved(&[0, 1, 2, 3, 4, 5, 6, 7][..], 2);
    ///
    /// assert!(buf.has_remaining());
    /// assert_eq!(buf.remaining(), 4);
    /// buf.advance(4);
    /// assert_eq!(buf.remaining(), 0);
    /// ```
    fn has_remaining(&self) -> bool {
        self.remaining() > 0
    }

    /// Get the number of frames remaining that can be read from the buffer.
    ///
    /// # Examples
    ///
    /// ```
    /// use audio::ReadBuf;
    ///
    /// let buf = audio::wrap::interleaved(&[0, 1, 2, 3, 4, 5, 6, 7][..], 2);
    /// assert_eq!(buf.remaining(), 4);
    /// ```
    fn remaining(&self) -> usize;

    /// Advance the read number of frames by `n`.
    ///
    /// # Examples
    ///
    /// ```
    /// use audio::ReadBuf;
    ///
    /// let mut buf = audio::wrap::interleaved(&[0, 1, 2, 3, 4, 5, 6, 7][..], 2);
    ///
    /// assert_eq!(buf.remaining(), 4);
    /// buf.advance(2);
    /// assert_eq!(buf.remaining(), 2);
    /// ```
    fn advance(&mut self, n: usize);
}

impl<B> ReadBuf for &mut B
where
    B: ReadBuf,
{
    #[inline]
    fn has_remaining(&self) -> bool {
        (**self).has_remaining()
    }

    #[inline]
    fn remaining(&self) -> usize {
        (**self).remaining()
    }

    #[inline]
    fn advance(&mut self, n: usize) {
        (**self).advance(n);
    }
}