audio/io/read_write.rs
1use audio_core::{Buf, BufMut, Channel, ExactSizeBuf, ReadBuf, WriteBuf};
2
3/// Make any mutable buffer into a write adapter that implements
4/// [ReadBuf] and [WriteBuf].
5///
6/// # Examples
7///
8/// ```
9/// use audio::{Buf, ReadBuf, WriteBuf};
10/// use audio::io;
11///
12/// let from = audio::interleaved![[1.0f32, 2.0f32, 3.0f32, 4.0f32]; 2];
13/// let to = audio::interleaved![[0.0f32; 4]; 2];
14///
15/// // Make `to` into a read / write adapter.
16/// let mut to = io::ReadWrite::empty(to);
17///
18/// io::copy_remaining(io::Read::new((&from).skip(2).limit(1)), &mut to);
19/// assert_eq!(to.remaining(), 1);
20///
21/// io::copy_remaining(io::Read::new((&from).limit(1)), &mut to);
22/// assert_eq!(to.remaining(), 2);
23///
24/// assert_eq! {
25/// to.as_ref().as_slice(),
26/// &[3.0, 3.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0],
27/// };
28///
29/// // Note: 4 channels, 2 frames each.
30/// let mut read_out = io::Write::new(audio::buf::Interleaved::with_topology(4, 2));
31///
32/// assert_eq!(read_out.remaining_mut(), 2);
33/// assert!(read_out.has_remaining_mut());
34///
35/// assert_eq!(to.remaining(), 2);
36/// assert!(to.has_remaining());
37///
38/// io::copy_remaining(&mut to, &mut read_out);
39///
40/// assert_eq!(read_out.remaining_mut(), 0);
41/// assert!(!read_out.has_remaining_mut());
42///
43/// assert_eq!(to.remaining(), 0);
44/// assert!(!to.has_remaining());
45///
46/// assert_eq! {
47/// read_out.as_ref().as_slice(),
48/// &[3.0, 3.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0],
49/// }
50/// ```
51pub struct ReadWrite<B> {
52 buf: B,
53 // Number of bytes available for reading. Conversely, the number of bytes
54 // available for writing is the length of the buffer subtracted by this.
55 read: usize,
56 // The position in frames to write at.
57 written: usize,
58}
59
60impl<B> ReadWrite<B> {
61 /// Construct a new adapter that supports both reading and writing.
62 ///
63 /// The constructed reader will be initialized so that the number of bytes
64 /// available for reading are equal to what's reported by
65 /// [ExactSizeBuf::frames].
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// use audio::{ReadBuf, ExactSizeBuf};
71 /// use audio::io;
72 ///
73 /// let buf = audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]];
74 /// assert_eq!(buf.frames(), 4);
75 ///
76 /// let buf = io::ReadWrite::new(buf);
77 ///
78 /// assert!(buf.has_remaining());
79 /// assert_eq!(buf.remaining(), 4);
80 /// ```
81 pub fn new(buf: B) -> Self
82 where
83 B: ExactSizeBuf,
84 {
85 let written = buf.frames();
86
87 Self {
88 buf,
89 read: 0,
90 written,
91 }
92 }
93
94 /// Construct a new adapter that supports both reading and writing.
95 ///
96 /// The constructed reader will be initialized so that there have been no
97 /// frames written to it, so there will not be any frames available for
98 /// reading.
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// use audio::{ReadBuf, ExactSizeBuf};
104 /// use audio::io;
105 ///
106 /// let buf = audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]];
107 /// assert_eq!(buf.frames(), 4);
108 ///
109 /// let buf = io::ReadWrite::empty(buf);
110 ///
111 /// assert!(!buf.has_remaining());
112 /// assert_eq!(buf.remaining(), 0);
113 /// ```
114 pub fn empty(buf: B) -> Self {
115 Self {
116 buf,
117 read: 0,
118 written: 0,
119 }
120 }
121
122 /// Access the underlying buffer.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// use audio::Buf;
128 /// use audio::io;
129 ///
130 /// let buf: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
131 /// let mut buf = io::ReadWrite::new(buf);
132 ///
133 /// let from = audio::wrap::interleaved(&[1i16, 2i16, 3i16, 4i16][..], 2);
134 ///
135 /// io::translate_remaining(from, &mut buf);
136 ///
137 /// assert_eq!(buf.as_ref().channels(), 4);
138 /// ```
139 #[inline]
140 pub fn as_ref(&self) -> &B {
141 &self.buf
142 }
143
144 /// Access the underlying buffer mutably.
145 ///
146 /// # Examples
147 ///
148 /// ```
149 /// use audio::Buf;
150 /// use audio::io;
151 ///
152 /// let to: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
153 /// let mut to = io::ReadWrite::new(to);
154 ///
155 /// let from = audio::wrap::interleaved(&[1i16, 2i16, 3i16, 4i16][..], 2);
156 ///
157 /// io::translate_remaining(from, &mut to);
158 ///
159 /// to.as_mut().resize_channels(2);
160 ///
161 /// assert_eq!(to.channels(), 2);
162 /// ```
163 #[inline]
164 pub fn as_mut(&mut self) -> &mut B {
165 &mut self.buf
166 }
167
168 /// Convert into the underlying buffer.
169 ///
170 /// # Examples
171 ///
172 /// ```
173 /// use audio::Buf;
174 /// use audio::io;
175 ///
176 /// let buf: audio::buf::Interleaved<i16> = audio::interleaved![[1, 2, 3, 4]; 4];
177 /// let mut buf = io::ReadWrite::new(buf);
178 ///
179 /// let from = audio::wrap::interleaved(&[1i16, 2i16, 3i16, 4i16][..], 2);
180 ///
181 /// io::translate_remaining(from, &mut buf);
182 ///
183 /// let buf = buf.into_inner();
184 ///
185 /// assert_eq!(buf.channels(), 4);
186 /// ```
187 #[inline]
188 pub fn into_inner(self) -> B {
189 self.buf
190 }
191
192 /// Clear the state of the read / write adapter, setting both read and
193 /// written to zero.
194 #[inline]
195 pub fn clear(&mut self) {
196 self.read = 0;
197 self.written = 0;
198 }
199
200 /// Set the number of frames read.
201 ///
202 /// This can be used to rewind the internal cursor to a previously written
203 /// frame if needed. Or, if the underlying buffer has changed for some
204 /// reason, like if it was written to through a call to [ReadWrite::as_mut].
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// use audio::{Buf, ReadBuf};
210 /// use audio::io;
211 ///
212 /// fn read_from_buf(mut read: impl Buf<Sample = i16> + ReadBuf) {
213 /// let mut out = audio::interleaved![[0; 4]; 2];
214 /// io::copy_remaining(read, io::Write::new(&mut out));
215 /// }
216 ///
217 /// let mut buf = io::ReadWrite::new(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
218 /// read_from_buf(&mut buf);
219 ///
220 /// assert!(!buf.has_remaining());
221 ///
222 /// buf.set_read(0);
223 ///
224 /// assert!(buf.has_remaining());
225 /// ```
226 #[inline]
227 pub fn set_read(&mut self, read: usize) {
228 self.read = read;
229 }
230
231 /// Set the number of frames written.
232 ///
233 /// This can be used to rewind the internal cursor to a previously written
234 /// frame if needed. Or, if the underlying buffer has changed for some
235 /// reason, like if it was read into through a call to [ReadWrite::as_mut].
236 ///
237 /// # Examples
238 ///
239 /// ```
240 /// use audio::{BufMut, WriteBuf};
241 /// use audio::io;
242 ///
243 /// fn write_to_buf(mut write: impl BufMut<Sample = i16> + WriteBuf) {
244 /// let mut from = audio::interleaved![[0; 4]; 2];
245 /// io::copy_remaining(io::Read::new(&mut from), write);
246 /// }
247 ///
248 /// let mut buf = io::ReadWrite::new(audio::interleaved![[1, 2, 3, 4], [5, 6, 7, 8]]);
249 /// write_to_buf(&mut buf);
250 ///
251 /// assert!(!buf.has_remaining_mut());
252 ///
253 /// buf.set_written(0);
254 ///
255 /// assert!(buf.has_remaining_mut());
256 /// ```
257 #[inline]
258 pub fn set_written(&mut self, written: usize) {
259 self.written = written;
260 }
261}
262
263impl<B> ExactSizeBuf for ReadWrite<B>
264where
265 B: ExactSizeBuf,
266{
267 fn frames(&self) -> usize {
268 self.buf.frames()
269 }
270}
271
272impl<B> ReadWrite<B>
273where
274 B: Buf,
275{
276 /// Construct an iterator over all available channels.
277 pub fn iter(&self) -> Iter<'_, B> {
278 let len = self.remaining();
279
280 Iter {
281 iter: self.buf.iter_channels(),
282 len,
283 read: self.read,
284 }
285 }
286}
287
288impl<B> ReadWrite<B>
289where
290 B: BufMut,
291{
292 /// Construct a mutable iterator over all available channels.
293 pub fn iter_mut(&mut self) -> IterMut<'_, B> {
294 IterMut {
295 iter: self.buf.iter_channels_mut(),
296 written: self.written,
297 }
298 }
299}
300
301impl<B> Buf for ReadWrite<B>
302where
303 B: Buf,
304{
305 type Sample = B::Sample;
306
307 type Channel<'this>
308 = B::Channel<'this>
309 where
310 Self: 'this;
311
312 type IterChannels<'this>
313 = Iter<'this, B>
314 where
315 Self: 'this;
316
317 #[inline]
318 fn frames_hint(&self) -> Option<usize> {
319 self.buf.frames_hint()
320 }
321
322 #[inline]
323 fn channels(&self) -> usize {
324 self.buf.channels()
325 }
326
327 #[inline]
328 fn get_channel(&self, channel: usize) -> Option<Self::Channel<'_>> {
329 let channel = self.buf.get_channel(channel)?;
330 let len = self.remaining();
331 Some(channel.skip(self.read).limit(len))
332 }
333
334 #[inline]
335 fn iter_channels(&self) -> Self::IterChannels<'_> {
336 (*self).iter()
337 }
338}
339
340impl<B> BufMut for ReadWrite<B>
341where
342 B: ExactSizeBuf + BufMut,
343{
344 type ChannelMut<'this>
345 = B::ChannelMut<'this>
346 where
347 Self: 'this;
348
349 type IterChannelsMut<'this>
350 = IterMut<'this, B>
351 where
352 Self: 'this;
353
354 #[inline]
355 fn get_channel_mut(&mut self, channel: usize) -> Option<Self::ChannelMut<'_>> {
356 Some(self.buf.get_channel_mut(channel)?.skip(self.written))
357 }
358
359 #[inline]
360 fn copy_channel(&mut self, from: usize, to: usize)
361 where
362 Self::Sample: Copy,
363 {
364 self.buf.copy_channel(from, to);
365 }
366
367 #[inline]
368 fn iter_channels_mut(&mut self) -> Self::IterChannelsMut<'_> {
369 (*self).iter_mut()
370 }
371}
372
373impl<B> ReadBuf for ReadWrite<B> {
374 #[inline]
375 fn remaining(&self) -> usize {
376 self.written.saturating_sub(self.read)
377 }
378
379 #[inline]
380 fn advance(&mut self, n: usize) {
381 self.read = self.read.saturating_add(n);
382 }
383}
384
385impl<B> WriteBuf for ReadWrite<B>
386where
387 B: ExactSizeBuf,
388{
389 #[inline]
390 fn remaining_mut(&self) -> usize {
391 self.buf.frames().saturating_sub(self.written)
392 }
393
394 #[inline]
395 fn advance_mut(&mut self, n: usize) {
396 self.written = self.written.saturating_add(n);
397 }
398}
399
400iter! {
401 len: usize,
402 read: usize,
403 =>
404 self.skip(read).limit(len)
405}
406
407iter_mut! {
408 written: usize,
409 =>
410 self.skip(written)
411}