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}