audioadapter_sample/readwrite.rs
1use crate::sample::*;
2use num_traits::Float;
3use std::io;
4
5/// A trait that extends [std::io::Read] with methods for reading samples directly.
6pub trait ReadSamples: io::Read {
7 /// Read a single sample from the underlying reader.
8 ///
9 /// This method reads a chunk of bytes from the underlying reader,
10 /// and interprets it as a sample of type `T`.
11 ///
12 /// # Type Parameters
13 ///
14 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the sample to read.
15 ///
16 /// # Returns
17 ///
18 /// * `io::Result<T>`: The read sample, or an error if reading failed.
19 ///
20 /// # Errors
21 ///
22 /// This function will return an error if:
23 ///
24 /// * The underlying reader returns an error.
25 /// * The number of bytes read is not sufficient to represent a complete sample.
26 fn read_sample<T: BytesSample>(&mut self) -> io::Result<T> {
27 let mut sample: T = unsafe { std::mem::zeroed() };
28 self.read_exact(sample.as_mut_slice())?;
29 Ok(sample)
30 }
31
32 /// Read a single sample and return it as a numeric type.
33 ///
34 /// This method reads a chunk of bytes from the underlying reader,
35 /// interprets it as a sample of type `T`, and returns the sample
36 /// converted to its associated `NumericType`.
37 ///
38 /// # Type Parameters
39 ///
40 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the sample to read.
41 ///
42 /// # Returns
43 ///
44 /// * `io::Result<T::NumericType>`: The sample as a number, or an error if reading failed.
45 ///
46 /// # Errors
47 ///
48 /// This function will return an error if:
49 ///
50 /// * The underlying reader returns an error.
51 /// * The number of bytes read is not sufficient to represent a complete sample.
52 fn read_number<T: BytesSample>(&mut self) -> io::Result<T::NumericType> {
53 let sample = self.read_sample::<T>()?;
54 Ok(sample.to_number())
55 }
56
57 /// Read a single sample and convert it to a floating-point number.
58 ///
59 /// This method reads a chunk of bytes from the underlying reader,
60 /// interprets it as a sample of type `T`, and returns the sample
61 /// converted to a floating-point number of type `U`. The conversion
62 /// uses the `to_scaled_float` method from the `RawSample` trait,
63 /// ensuring that the float is scaled between -1.0 and 1.0.
64 ///
65 /// # Type Parameters
66 ///
67 /// * `T`: A type implementing both `RawSample` and `BytesSample`, defining the format of the sample to read.
68 /// * `U`: A floating-point type implementing `Float`, representing the desired output format.
69 ///
70 /// # Returns
71 ///
72 /// * `io::Result<U>`: The converted sample as a float, or an error if reading failed.
73 ///
74 /// # Errors
75 ///
76 /// This function will return an error if:
77 ///
78 /// * The underlying reader returns an error.
79 /// * The number of bytes read is not sufficient to represent a complete sample.
80 fn read_converted<T: RawSample + BytesSample, U: Float>(&mut self) -> io::Result<U> {
81 let sample = self.read_sample::<T>()?;
82 Ok(sample.to_scaled_float::<U>())
83 }
84
85 /// Read multiple samples into a slice.
86 ///
87 /// This method attempts to read enough bytes from the underlying reader to
88 /// fill the buffer `buf` with samples of type `T`. It reads samples one at a time,
89 /// populating the buffer in order.
90 ///
91 /// # Type Parameters
92 ///
93 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to read.
94 ///
95 /// # Arguments
96 ///
97 /// * `buf`: A mutable slice where the samples will be stored.
98 ///
99 /// # Errors
100 ///
101 /// This function will return an error if:
102 ///
103 /// * The underlying reader returns an error.
104 /// * The number of bytes read is not sufficient to represent a complete sample.
105 /// * The end of the reader is reached before all samples have been read.
106 fn read_samples_exact<T: BytesSample>(&mut self, buf: &mut [T]) -> io::Result<()> {
107 for sample in buf.iter_mut() {
108 *sample = self.read_sample()?;
109 }
110 Ok(())
111 }
112
113 /// Read multiple samples and store them as numeric types in a provided buffer.
114 ///
115 /// This method reads a sequence of samples from the underlying reader and
116 /// stores them in the provided buffer `buf`. Each sample is read and
117 /// interpreted as a type `T`, then converted to its associated `NumericType`
118 /// before being stored in the buffer.
119 ///
120 /// # Type Parameters
121 ///
122 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to read.
123 ///
124 /// # Arguments
125 ///
126 /// * `buf`: A mutable slice where the samples will be stored. The length of the slice determines how many samples are read.
127 ///
128 /// # Returns
129 ///
130 /// * `io::Result<()>`: Ok(()) if all samples were read successfully.
131 ///
132 /// # Errors
133 ///
134 /// This function will return an error if:
135 ///
136 /// * The underlying reader returns an error.
137 /// * The number of bytes read is not sufficient to represent a complete sample.
138 /// * The end of the reader is reached before all samples have been read.
139 fn read_numbers_exact<T: BytesSample>(&mut self, buf: &mut [T::NumericType]) -> io::Result<()> {
140 for sample in buf.iter_mut() {
141 *sample = self.read_number::<T>()?;
142 }
143 Ok(())
144 }
145
146 /// Read multiple samples, convert them to floats, and store them in a provided buffer.
147 ///
148 /// This method reads a sequence of samples from the underlying reader,
149 /// converts each sample to a floating-point number of type `U`, and
150 /// stores the results in the provided buffer `buf`.
151 ///
152 /// # Type Parameters
153 ///
154 /// * `T`: A type implementing both `RawSample` and `BytesSample`, defining the format of the samples to read.
155 /// * `U`: A floating-point type implementing `Float`, representing the desired output format.
156 ///
157 /// # Arguments
158 ///
159 /// * `buf`: A mutable slice where the converted samples will be stored. The length of the slice determines how many samples are read.
160 ///
161 /// # Returns
162 ///
163 /// * `io::Result<()>`: Ok(()) if all samples were read and converted successfully.
164 ///
165 /// # Errors
166 ///
167 /// This function will return an error if:
168 ///
169 /// * The underlying reader returns an error.
170 /// * The number of bytes read is not sufficient to represent a complete sample.
171 /// * The end of the reader is reached before all samples have been read.
172 fn read_converted_exact<T: RawSample + BytesSample, U: Float>(
173 &mut self,
174 buf: &mut [U],
175 ) -> io::Result<()> {
176 for sample in buf.iter_mut() {
177 *sample = self.read_converted::<T, U>()?;
178 }
179 Ok(())
180 }
181
182 /// Read samples until the end of the stream, storing them in a vector.
183 ///
184 /// This method reads samples from the underlying reader until reaching
185 /// the end of the stream, the optional limit, or encountering an error.
186 /// Each sample is read and interpreted as a type `T`
187 /// before being appended to the provided vector `buf`.
188 ///
189 /// Only complete samples are read. If the last bytes at the end of the stream
190 /// are too few to make up a complete sample, then they are ignored.
191 ///
192 /// # Type Parameters
193 ///
194 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to read.
195 ///
196 /// # Arguments
197 ///
198 /// * `buf`: A mutable vector where the samples will be appended.
199 /// * `limit`: An optional limit for how many samples to read.
200 ///
201 /// # Returns
202 /// The number of samples read.
203 ///
204 /// # Errors
205 ///
206 /// * The underlying reader returns an error (except for EOF).
207 fn read_samples_to_limit_or_end<T: BytesSample>(
208 &mut self,
209 buf: &mut Vec<T>,
210 limit: Option<usize>,
211 ) -> io::Result<usize> {
212 let mut count = 0;
213 loop {
214 match self.read_sample::<T>() {
215 Ok(sample) => {
216 buf.push(sample);
217 count += 1;
218 }
219 Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof => {
220 break;
221 }
222 Err(e) => return Err(e),
223 }
224 if let Some(limit) = limit {
225 if count >= limit {
226 break;
227 }
228 }
229 }
230 Ok(count)
231 }
232
233 /// Read samples until the end of the stream, storing them as numeric types in a vector.
234 ///
235 /// This method reads samples from the underlying reader until reaching
236 /// the end of the stream, the optional limit, or encountering an error.
237 /// Each sample is read and interpreted as
238 /// a type `T`, then converted to its associated `NumericType` before being
239 /// appended to the provided vector `buf`.
240 ///
241 /// Only complete samples are read. If the last bytes at the end of the stream
242 /// are too few to make up a complete sample, then they are ignored.
243 ///
244 /// # Type Parameters
245 ///
246 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to read.
247 ///
248 /// # Arguments
249 ///
250 /// * `buf`: A mutable vector where the samples will be appended.
251 /// * `limit`: An optional limit for how many samples to read.
252 ///
253 /// # Returns
254 ///
255 /// * `io::Result<usize>`: The number of samples read, or an error if reading failed.
256 ///
257 /// # Errors
258 ///
259 /// This function will return an error if:
260 ///
261 /// * The underlying reader returns an error (except for EOF).
262 fn read_numbers_to_limit_or_end<T: BytesSample>(
263 &mut self,
264 buf: &mut Vec<T::NumericType>,
265 limit: Option<usize>,
266 ) -> io::Result<usize> {
267 let mut count = 0;
268 loop {
269 match self.read_number::<T>() {
270 Ok(sample) => {
271 buf.push(sample);
272 count += 1;
273 }
274 Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof => {
275 break;
276 }
277 Err(e) => return Err(e),
278 }
279 if let Some(limit) = limit {
280 if count >= limit {
281 break;
282 }
283 }
284 }
285 Ok(count)
286 }
287
288 /// Read samples until the end of the stream, converting them to floats, and store in a vector.
289 ///
290 /// This method reads samples from the underlying reader until reaching
291 /// the end of the stream, the optional limit, or encountering an error.
292 /// Each sample is read, converted to a
293 /// floating-point number of type `U`, and appended to the provided vector `buf`.
294 ///
295 /// Only complete samples are read. If the last bytes at the end of the stream
296 /// are too few to make up a complete sample, then they are ignored.
297 ///
298 /// # Type Parameters
299 ///
300 /// * `T`: A type implementing both `RawSample` and `BytesSample`, defining the format of the samples to read.
301 /// * `U`: A floating-point type implementing `Float`, representing the desired output format.
302 ///
303 /// # Arguments
304 ///
305 /// * `buf`: A mutable vector where the converted samples will be appended.
306 /// * `limit`: An optional limit for how many samples to read.
307 ///
308 /// # Returns
309 ///
310 /// * `io::Result<usize>`: The number of samples read and converted, or an error if reading failed.
311 ///
312 /// # Errors
313 ///
314 /// This function will return an error if:
315 ///
316 /// * The underlying reader returns an error (except for EOF).
317 fn read_converted_to_limit_or_end<T: RawSample + BytesSample, U: Float>(
318 &mut self,
319 buf: &mut Vec<U>,
320 limit: Option<usize>,
321 ) -> io::Result<usize> {
322 let mut count = 0;
323 loop {
324 match self.read_converted::<T, U>() {
325 Ok(sample) => {
326 buf.push(sample);
327 count += 1;
328 }
329 Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof => {
330 break;
331 }
332 Err(e) => return Err(e),
333 }
334 if let Some(limit) = limit {
335 if count >= limit {
336 break;
337 }
338 }
339 }
340 Ok(count)
341 }
342}
343
344impl<R: io::Read + ?Sized> ReadSamples for R {}
345
346/// A trait that extends [std::io::Write] with methods for writing samples directly.
347pub trait WriteSamples: io::Write {
348 /// Write a single sample to the underlying writer.
349 ///
350 /// This method takes a reference to a sample of type `T`,
351 /// gets its raw byte representation using the `as_slice` method,
352 /// and writes it to the underlying writer.
353 ///
354 /// # Type Parameters
355 ///
356 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the sample to write.
357 /// # Returns
358 ///
359 /// * `io::Result<()>`: Ok(()) if the sample was written successfully.
360 /// # Errors
361 ///
362 /// This function will return an error if:
363 ///
364 /// * The underlying writer returns an error.
365 fn write_sample<T: BytesSample>(&mut self, sample: &T) -> io::Result<()> {
366 self.write_all(sample.as_slice())
367 }
368
369 /// Write a single sample from a numeric type to the underlying writer.
370 ///
371 /// This method takes a sample represented by its `NumericType`,
372 /// converts it to a raw byte representation using the provided `T`,
373 /// and writes it to the underlying writer.
374 ///
375 /// # Type Parameters
376 ///
377 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the sample to write.
378 ///
379 /// # Arguments
380 ///
381 /// * `value`: The sample to write.
382 ///
383 /// # Returns
384 ///
385 /// * `io::Result<()>`: Ok(()) if the sample was written successfully.
386 ///
387 /// # Errors
388 ///
389 /// This function will return an error if:
390 ///
391 /// * The underlying writer returns an error.
392 fn write_number<T: BytesSample>(&mut self, value: T::NumericType) -> io::Result<()> {
393 self.write_all(T::from_number(value).as_slice())
394 }
395
396 /// Write a single converted sample to the underlying writer.
397 ///
398 /// This method takes a floating-point sample of type `U`, converts it to
399 /// the raw byte representation of type `T` and then writes it to the underlying writer.
400 ///
401 /// # Type Parameters
402 ///
403 /// * `T`: A type implementing both `RawSample` and `BytesSample`, defining the format of the sample to write.
404 /// * `U`: A floating-point type implementing `Float`, representing the sample to write.
405 ///
406 /// # Arguments
407 ///
408 /// * `value`: The sample to write.
409 ///
410 /// # Returns
411 ///
412 /// * `io::Result<bool>`: Ok(true) if the value was clipped during conversion, Ok(false) otherwise.
413 ///
414 /// # Errors
415 ///
416 /// This function will return an error if:
417 ///
418 /// * The underlying writer returns an error.
419 fn write_converted<T: RawSample + BytesSample, U: Float>(
420 &mut self,
421 value: U,
422 ) -> io::Result<bool> {
423 let converted = T::from_scaled_float(value);
424 self.write_all(converted.value.as_slice())?;
425 Ok(converted.clipped)
426 }
427
428 /// Write multiple samples to the underlying writer.
429 ///
430 /// This method takes a slice of samples, gets the raw byte representation of each sample,
431 /// and then writes it to the underlying writer.
432 ///
433 /// # Type Parameters
434 ///
435 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to write.
436 /// # Arguments
437 ///
438 /// * `samples`: The samples to write.
439 /// # Returns
440 ///
441 /// * `io::Result<()>`: Ok(()) if all samples were written successfully.
442 /// # Errors
443 ///
444 /// This function will return an error if:
445 ///
446 /// * The underlying writer returns an error.
447 fn write_all_samples<T: BytesSample>(&mut self, samples: &[T]) -> io::Result<()> {
448 for sample in samples {
449 self.write_sample::<T>(sample)?;
450 }
451 Ok(())
452 }
453
454 /// Write multiple samples from a numeric slice to the underlying writer.
455 ///
456 /// This method takes a slice of samples represented by their `NumericType`,
457 /// converts each sample to its raw byte representation using the provided `T`,
458 /// and writes them to the underlying writer.
459 ///
460 /// # Type Parameters
461 ///
462 /// * `T`: A type implementing the `BytesSample` trait, defining the format of the samples to write.
463 ///
464 /// # Arguments
465 ///
466 /// * `values`: The samples to write.
467 ///
468 /// # Returns
469 ///
470 /// * `io::Result<()>`: Ok(()) if all samples were written successfully.
471 ///
472 /// # Errors
473 ///
474 /// This function will return an error if:
475 ///
476 /// * The underlying writer returns an error.
477 fn write_all_numbers<T: BytesSample>(&mut self, values: &[T::NumericType]) -> io::Result<()> {
478 for value in values {
479 self.write_number::<T>(*value)?;
480 }
481 Ok(())
482 }
483
484 /// Write multiple converted samples from a float slice to the underlying writer.
485 ///
486 /// This method takes a slice of floating-point samples of type `U`, converts each sample
487 /// to its raw byte representation of type `T`, and then writes them to the underlying writer.
488 ///
489 /// # Type Parameters
490 ///
491 /// * `T`: A type implementing both `RawSample` and `BytesSample`, defining the format of the samples to write.
492 /// * `U`: A floating-point type implementing `Float`, representing the samples to write.
493 ///
494 /// # Arguments
495 ///
496 /// * `values`: The samples to write.
497 ///
498 /// # Returns
499 ///
500 /// * `io::Result<usize>`: The number of samples that were clipped during conversion.
501 ///
502 /// # Errors
503 ///
504 /// This function will return an error if:
505 ///
506 /// * The underlying writer returns an error.
507 fn write_all_converted<T: RawSample + BytesSample, U: Float>(
508 &mut self,
509 values: &[U],
510 ) -> io::Result<usize> {
511 let mut nbr_clipped = 0;
512 for value in values {
513 let clipped = self.write_converted::<T, U>(*value)?;
514 if clipped {
515 nbr_clipped += 1;
516 }
517 }
518 Ok(nbr_clipped)
519 }
520}
521
522impl<W: io::Write + ?Sized> WriteSamples for W {}
523
524#[cfg(test)]
525mod tests {
526 use super::*;
527 use crate::readwrite::ReadSamples;
528 use crate::readwrite::WriteSamples;
529
530 #[test]
531 fn test_read_number_i16() {
532 let data: Vec<u8> = vec![0, 1, 2, 3];
533 let mut slice = &data[..];
534 assert_eq!(slice.read_number::<I16LE>().unwrap(), 256);
535 assert_eq!(slice.read_number::<I16LE>().unwrap(), 3 * 256 + 2);
536 assert!(slice.read_number::<I16LE>().is_err());
537 }
538
539 #[test]
540 fn test_read_converted_i16() {
541 let data: Vec<u8> = vec![0, 64, 0, 32];
542 let mut slice = &data[..];
543 assert_eq!(slice.read_converted::<I16LE, f32>().unwrap(), 0.5);
544 assert_eq!(slice.read_converted::<I16LE, f32>().unwrap(), 0.25);
545 assert!(slice.read_converted::<I16LE, f32>().is_err());
546 }
547
548 #[test]
549 fn test_read_number_exact_i16() {
550 let data: Vec<u8> = vec![0, 1, 2, 3];
551 let mut slice = &data[..];
552 let mut buf = [0; 2];
553 slice.read_numbers_exact::<I16LE>(&mut buf).unwrap();
554 assert_eq!(buf, [256, 3 * 256 + 2]);
555 assert!(slice.read_numbers_exact::<I16LE>(&mut buf).is_err());
556 }
557
558 #[test]
559 fn test_read_converted_exact_i16() {
560 let data: Vec<u8> = vec![0, 64, 0, 32];
561 let mut slice = &data[..];
562 let mut buf = [0.0; 2];
563 slice.read_converted_exact::<I16LE, f32>(&mut buf).unwrap();
564 assert_eq!(buf, [0.5, 0.25]);
565 assert!(slice.read_converted_exact::<I16LE, f32>(&mut buf).is_err());
566 }
567
568 #[test]
569 fn test_read_numbers_to_end_i16() {
570 // four complete samples, and one extra byte at the end
571 let data: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
572 let mut slice = &data[..];
573 let mut buf = Vec::new();
574 slice
575 .read_numbers_to_limit_or_end::<I16LE>(&mut buf, None)
576 .unwrap();
577 assert_eq!(buf, [256, 3 * 256 + 2, 5 * 256 + 4, 7 * 256 + 6]);
578 let mut slice2 = &data[..];
579 let mut buf2 = Vec::new();
580 slice2
581 .read_numbers_to_limit_or_end::<I16LE>(&mut buf2, Some(2))
582 .unwrap();
583 assert_eq!(buf2, [256, 3 * 256 + 2]);
584 }
585
586 #[test]
587 fn test_read_converted_to_end_i16() {
588 // four complete samples, and one extra byte at the end
589 let data: Vec<u8> = vec![0, 64, 0, 32, 0, 16, 0, 8, 0];
590 let mut slice = &data[..];
591 let mut buf = Vec::new();
592 slice
593 .read_converted_to_limit_or_end::<I16LE, f32>(&mut buf, None)
594 .unwrap();
595 assert_eq!(buf, [0.5, 0.25, 0.125, 0.0625]);
596 let mut slice2 = &data[..];
597 let mut buf2 = Vec::new();
598 slice2
599 .read_converted_to_limit_or_end::<I16LE, f32>(&mut buf2, Some(2))
600 .unwrap();
601 assert_eq!(buf2, [0.5, 0.25]);
602 }
603
604 #[test]
605 fn test_write_number_i16() {
606 let mut buf = Vec::new();
607 buf.write_number::<I16LE>(256).unwrap();
608 buf.write_number::<I16LE>(3 * 256 + 2).unwrap();
609 assert_eq!(buf, [0, 1, 2, 3]);
610 }
611
612 #[test]
613 fn test_write_converted_i16() {
614 let mut buf = Vec::new();
615 buf.write_converted::<I16LE, f32>(0.5).unwrap();
616 buf.write_converted::<I16LE, f32>(0.25).unwrap();
617 assert_eq!(buf, [0, 64, 0, 32]);
618 }
619
620 #[test]
621 fn test_write_all_numbers_i16() {
622 let mut buf = Vec::new();
623 buf.write_all_numbers::<I16LE>(&[256, 3 * 256 + 2]).unwrap();
624 assert_eq!(buf, [0, 1, 2, 3]);
625 }
626
627 #[test]
628 fn test_write_all_converted_i16() {
629 let mut buf = Vec::new();
630 buf.write_all_converted::<I16LE, f32>(&[0.5, 0.25]).unwrap();
631 assert_eq!(buf, [0, 64, 0, 32]);
632 }
633}