audio/io/
write.rs

1use audio_core::{Buf, BufMut, Channel, ExactSizeBuf, WriteBuf};
2
3/// Make a mutable buffer into a write adapter that implements [WriteBuf].
4///
5/// # Examples
6///
7/// ```
8/// use audio::{Buf, ReadBuf, WriteBuf};
9/// use audio::io;
10///
11/// let from = audio::interleaved![[1.0f32, 2.0f32, 3.0f32, 4.0f32]; 2];
12/// let mut from = io::Read::new(from.skip(2));
13///
14/// let to = audio::interleaved![[0.0f32; 4]; 2];
15/// let mut to = io::Write::new(to);
16///
17/// assert_eq!(to.remaining_mut(), 4);
18/// io::copy_remaining(from, &mut to);
19/// assert_eq!(to.remaining_mut(), 2);
20///
21/// assert_eq! {
22///     to.as_ref().as_slice(),
23///     &[3.0, 3.0, 4.0, 4.0, 0.0, 0.0, 0.0, 0.0],
24/// };
25/// ```
26pub struct Write<B> {
27    buf: B,
28    available: usize,
29}
30
31impl<B> Write<B> {
32    /// Construct a new writing adapter.
33    ///
34    /// The constructed writer will be initialized so that the number of bytes
35    /// available for writing are equal to what's reported by
36    /// [ExactSizeBuf::frames].
37    ///
38    /// # Examples
39    ///
40    /// ```
41    /// use audio::{WriteBuf, ExactSizeBuf};
42    /// use audio::io;
43    ///
44    /// let buf = audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]];
45    /// assert_eq!(buf.frames(), 4);
46    ///
47    /// let buf = io::Write::new(buf);
48    ///
49    /// assert!(buf.has_remaining_mut());
50    /// assert_eq!(buf.remaining_mut(), 4);
51    /// ```
52    #[inline]
53    pub fn new(buf: B) -> Self
54    where
55        B: ExactSizeBuf,
56    {
57        let available = buf.frames();
58        Self { buf, available }
59    }
60
61    /// Construct a new writing adapter.
62    ///
63    /// The constructed reader will be initialized so that there are no frames
64    /// available to be written.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use audio::{WriteBuf, ExactSizeBuf};
70    /// use audio::io;
71    ///
72    /// let buf = audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]];
73    /// assert_eq!(buf.frames(), 4);
74    ///
75    /// let buf = io::Write::empty(buf);
76    ///
77    /// assert!(!buf.has_remaining_mut());
78    /// assert_eq!(buf.remaining_mut(), 0);
79    /// ```
80    #[inline]
81    pub const fn empty(buf: B) -> Self {
82        Self { buf, available: 0 }
83    }
84
85    /// Access the underlying buffer.
86    ///
87    /// # Examples
88    ///
89    /// ```
90    /// use audio::{io, wrap};
91    ///
92    /// let buf: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
93    /// let mut buf = io::Write::new(buf);
94    ///
95    /// io::copy_remaining(wrap::interleaved(&[0i16; 16][..], 4), &mut buf);
96    ///
97    /// assert_eq!(buf.as_ref().channels(), 4);
98    /// ```
99    #[inline]
100    pub fn as_ref(&self) -> &B {
101        &self.buf
102    }
103
104    /// Access the underlying buffer mutably.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use audio::{io, wrap};
110    /// use audio::Buf;
111    ///
112    /// let buf: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
113    /// let mut buf = io::Write::new(buf);
114    ///
115    /// io::copy_remaining(wrap::interleaved(&[0i16; 16][..], 4), &mut buf);
116    ///
117    /// buf.as_mut().resize_channels(2);
118    ///
119    /// assert_eq!(buf.channels(), 2);
120    /// ```
121    #[inline]
122    pub fn as_mut(&mut self) -> &mut B {
123        &mut self.buf
124    }
125
126    /// Convert into the underlying buffer.
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use audio::Buf;
132    /// use audio::io;
133    ///
134    /// let buf: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
135    /// let mut buf = io::Write::new(buf);
136    ///
137    /// io::copy_remaining(audio::wrap::interleaved(&[0i16; 16][..], 4), &mut buf);
138    ///
139    /// let buf = buf.into_inner();
140    ///
141    /// assert_eq!(buf.channels(), 4);
142    /// ```
143    #[inline]
144    pub fn into_inner(self) -> B {
145        self.buf
146    }
147
148    /// Set the number of frames written.
149    ///
150    /// This can be used to rewind the internal cursor to a previously written
151    /// frame if needed. Or, if the underlying buffer has changed for some
152    /// reason, like if it was read into through a call to [Write::as_mut].
153    ///
154    /// # Examples
155    ///
156    /// ```
157    /// use audio::{BufMut, WriteBuf};
158    /// use audio::io;
159    ///
160    /// fn write_to_buf(mut write: impl BufMut<Sample = i16> + WriteBuf) {
161    ///     let mut from = audio::interleaved![[0; 4]; 2];
162    ///     io::copy_remaining(io::Read::new(&mut from), write);
163    /// }
164    ///
165    /// let mut buf = io::Write::new(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
166    /// write_to_buf(&mut buf);
167    ///
168    /// assert!(!buf.has_remaining_mut());
169    ///
170    /// buf.set_written(0);
171    ///
172    /// assert!(buf.has_remaining_mut());
173    /// ```
174    #[inline]
175    pub fn set_written(&mut self, written: usize)
176    where
177        B: ExactSizeBuf,
178    {
179        self.available = self.buf.frames().saturating_sub(written);
180    }
181}
182
183impl<B> Write<B>
184where
185    B: Buf,
186{
187    /// Construct an iterator over all available channels.
188    #[inline]
189    pub fn iter(&self) -> Iter<'_, B> {
190        Iter {
191            iter: self.buf.iter_channels(),
192            available: self.available,
193        }
194    }
195}
196
197impl<B> Write<B>
198where
199    B: BufMut,
200{
201    /// Construct a mutable iterator over all available channels.
202    #[inline]
203    pub fn iter_mut(&mut self) -> IterMut<'_, B> {
204        IterMut {
205            iter: self.buf.iter_channels_mut(),
206            available: self.available,
207        }
208    }
209}
210
211impl<B> WriteBuf for Write<B> {
212    /// Remaining number of frames available.
213    #[inline]
214    fn remaining_mut(&self) -> usize {
215        self.available
216    }
217
218    #[inline]
219    fn advance_mut(&mut self, n: usize) {
220        self.available = self.available.saturating_sub(n);
221    }
222}
223
224impl<B> ExactSizeBuf for Write<B>
225where
226    B: ExactSizeBuf,
227{
228    #[inline]
229    fn frames(&self) -> usize {
230        self.buf.frames()
231    }
232}
233
234impl<B> Buf for Write<B>
235where
236    B: Buf,
237{
238    type Sample = B::Sample;
239
240    type Channel<'this>
241        = B::Channel<'this>
242    where
243        Self: 'this;
244
245    type IterChannels<'this>
246        = Iter<'this, B>
247    where
248        Self: 'this;
249
250    #[inline]
251    fn frames_hint(&self) -> Option<usize> {
252        self.buf.frames_hint()
253    }
254
255    #[inline]
256    fn channels(&self) -> usize {
257        self.buf.channels()
258    }
259
260    #[inline]
261    fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
262        Some(self.buf.get_channel(channel)?.tail(self.available))
263    }
264
265    #[inline]
266    fn iter_channels(&self) -> Self::IterChannels<'_> {
267        (*self).iter()
268    }
269}
270
271impl<B> BufMut for Write<B>
272where
273    B: BufMut,
274{
275    type ChannelMut<'a>
276        = B::ChannelMut<'a>
277    where
278        Self: 'a;
279
280    type IterChannelsMut<'a>
281        = IterMut<'a, B>
282    where
283        Self: 'a;
284
285    #[inline]
286    fn get_channel_mut(&mut self, channel: usize) -> Option<Self::ChannelMut<'_>> {
287        Some(self.buf.get_channel_mut(channel)?.tail(self.available))
288    }
289
290    #[inline]
291    fn copy_channel(&mut self, from: usize, to: usize)
292    where
293        Self::Sample: Copy,
294    {
295        self.buf.copy_channel(from, to);
296    }
297
298    #[inline]
299    fn iter_channels_mut(&mut self) -> Self::IterChannelsMut<'_> {
300        (*self).iter_mut()
301    }
302}
303
304iter! {
305    available: usize,
306    =>
307    self.tail(available)
308}
309
310iter_mut! {
311    available: usize,
312    =>
313    self.tail(available)
314}