Skip to main content

symphonia_core/audio/
generic.rs

1// Symphonia
2// Copyright (c) 2019-2026 The Project Symphonia Developers.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8use std::ops::RangeBounds;
9
10use crate::audio::{
11    conv::ConvertibleSample,
12    sample::{SampleBytes, SampleFormat, i24, u24},
13};
14
15use super::{Audio, AudioBuffer, AudioBytes, AudioMut, AudioSlice, AudioSpec};
16
17/// An owning wrapper for an [`AudioBuffer`] of any standard sample format.
18///
19/// Calls on this wrapper are dispatched to the underlying, wrapped, buffer and are semantically
20/// identical.
21pub enum GenericAudioBuffer {
22    /// An unsigned 8-bit integer audio buffer.
23    U8(AudioBuffer<u8>),
24    /// An unsigned 16-bit integer audio buffer.
25    U16(AudioBuffer<u16>),
26    /// An unsigned 24-bit integer audio buffer.
27    U24(AudioBuffer<u24>),
28    /// An unsigned 32-bit integer audio buffer.
29    U32(AudioBuffer<u32>),
30    /// A signed 8-bit integer audio buffer.
31    S8(AudioBuffer<i8>),
32    /// A signed 16-bit integer audio buffer.
33    S16(AudioBuffer<i16>),
34    /// A signed 24-bit integer audio buffer.
35    S24(AudioBuffer<i24>),
36    /// A signed 32-bit integer audio buffer.
37    S32(AudioBuffer<i32>),
38    /// A single precision (32-bit) floating point audio buffer.
39    F32(AudioBuffer<f32>),
40    /// A double precision (64-bit) floating point audio buffer.
41    F64(AudioBuffer<f64>),
42}
43
44macro_rules! impl_generic_func {
45    ($own:expr, $buf:ident, $expr:expr) => {
46        match $own {
47            GenericAudioBuffer::U8($buf) => $expr,
48            GenericAudioBuffer::U16($buf) => $expr,
49            GenericAudioBuffer::U24($buf) => $expr,
50            GenericAudioBuffer::U32($buf) => $expr,
51            GenericAudioBuffer::S8($buf) => $expr,
52            GenericAudioBuffer::S16($buf) => $expr,
53            GenericAudioBuffer::S24($buf) => $expr,
54            GenericAudioBuffer::S32($buf) => $expr,
55            GenericAudioBuffer::F32($buf) => $expr,
56            GenericAudioBuffer::F64($buf) => $expr,
57        }
58    };
59}
60
61impl GenericAudioBuffer {
62    pub fn new(format: SampleFormat, spec: AudioSpec, capacity: usize) -> Self {
63        match format {
64            SampleFormat::U8 => GenericAudioBuffer::U8(AudioBuffer::new(spec, capacity)),
65            SampleFormat::U16 => GenericAudioBuffer::U16(AudioBuffer::new(spec, capacity)),
66            SampleFormat::U24 => GenericAudioBuffer::U24(AudioBuffer::new(spec, capacity)),
67            SampleFormat::U32 => GenericAudioBuffer::U32(AudioBuffer::new(spec, capacity)),
68            SampleFormat::S8 => GenericAudioBuffer::S8(AudioBuffer::new(spec, capacity)),
69            SampleFormat::S16 => GenericAudioBuffer::S16(AudioBuffer::new(spec, capacity)),
70            SampleFormat::S24 => GenericAudioBuffer::S24(AudioBuffer::new(spec, capacity)),
71            SampleFormat::S32 => GenericAudioBuffer::S32(AudioBuffer::new(spec, capacity)),
72            SampleFormat::F32 => GenericAudioBuffer::F32(AudioBuffer::new(spec, capacity)),
73            SampleFormat::F64 => GenericAudioBuffer::F64(AudioBuffer::new(spec, capacity)),
74        }
75    }
76
77    /// Get the audio specification.
78    pub fn spec(&self) -> &AudioSpec {
79        impl_generic_func!(self, buf, buf.spec())
80    }
81
82    /// Get the total number of audio planes.
83    pub fn num_planes(&self) -> usize {
84        impl_generic_func!(self, buf, buf.num_planes())
85    }
86
87    /// Returns `true` if there are no audio frames.
88    pub fn is_empty(&self) -> bool {
89        impl_generic_func!(self, buf, buf.is_empty())
90    }
91
92    /// Gets the number of audio frames in the buffer.
93    pub fn frames(&self) -> usize {
94        impl_generic_func!(self, buf, buf.frames())
95    }
96
97    /// Returns `true` if the `AudioBuffer` is unused.
98    ///
99    /// An unused `AudioBuffer` has either a capacity of 0, or no channels.
100    pub fn is_unused(&self) -> bool {
101        impl_generic_func!(self, buf, buf.is_unused())
102    }
103
104    /// Gets the total capacity of the buffer. The capacity is the maximum number of audio frames
105    /// the buffer can store.
106    pub fn capacity(&self) -> usize {
107        impl_generic_func!(self, buf, buf.capacity())
108    }
109
110    /// Clears all audio frames.
111    pub fn clear(&mut self) {
112        impl_generic_func!(self, buf, buf.clear());
113    }
114
115    /// Grows the capacity of the buffer if the new capacity is larger than the current capacity.
116    ///
117    /// # Realtime Safety
118    ///
119    /// This function will allocate if `new_capacity` exceeds the current capacity.
120    pub fn grow_capacity(&mut self, new_capacity: usize) {
121        impl_generic_func!(self, buf, buf.grow_capacity(new_capacity))
122    }
123
124    /// Resizes the buffer such that the number of frames is `new_len`. New frames are silent.
125    ///
126    /// See [`AudioBuffer::resize_with_silence`] for full details.
127    pub fn resize_with_silence(&mut self, new_len: usize) {
128        impl_generic_func!(self, buf, buf.resize_with_silence(new_len))
129    }
130
131    /// Resizes the buffer such that the number of frames is `new_len`. New frames are left
132    /// uninitialized and may contain stale data that should be overwritten.
133    ///
134    /// See [`AudioBuffer::resize_uninit`] for full details.
135    pub fn resize_uninit(&mut self, new_len: usize) {
136        impl_generic_func!(self, buf, buf.resize_uninit(new_len))
137    }
138
139    /// Renders a number of silent frames.
140    ///
141    /// See [`AudioBuffer::render_silence`] for full details.
142    pub fn render_silence(&mut self, num_frames: Option<usize>) -> usize {
143        impl_generic_func!(self, buf, buf.render_silence(num_frames))
144    }
145
146    /// Renders an uninitialized number of frames.
147    ///
148    /// See [`AudioBuffer::render_uninit`] for full details.
149    pub fn render_uninit(&mut self, num_frames: Option<usize>) -> usize {
150        impl_generic_func!(self, buf, buf.render_uninit(num_frames))
151    }
152
153    /// Shifts the contents of the buffer back by the number of frames specified. The leading frames
154    /// are dropped from the buffer.
155    pub fn shift(&mut self, shift: usize) {
156        impl_generic_func!(self, buf, buf.shift(shift))
157    }
158
159    /// Get an immutable slice of the buffer over `range`.
160    pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> GenericAudioSlice<'_> {
161        match self {
162            GenericAudioBuffer::U8(buf) => GenericAudioSlice::U8(buf.slice(range)),
163            GenericAudioBuffer::U16(buf) => GenericAudioSlice::U16(buf.slice(range)),
164            GenericAudioBuffer::U24(buf) => GenericAudioSlice::U24(buf.slice(range)),
165            GenericAudioBuffer::U32(buf) => GenericAudioSlice::U32(buf.slice(range)),
166            GenericAudioBuffer::S8(buf) => GenericAudioSlice::S8(buf.slice(range)),
167            GenericAudioBuffer::S16(buf) => GenericAudioSlice::S16(buf.slice(range)),
168            GenericAudioBuffer::S24(buf) => GenericAudioSlice::S24(buf.slice(range)),
169            GenericAudioBuffer::S32(buf) => GenericAudioSlice::S32(buf.slice(range)),
170            GenericAudioBuffer::F32(buf) => GenericAudioSlice::F32(buf.slice(range)),
171            GenericAudioBuffer::F64(buf) => GenericAudioSlice::F64(buf.slice(range)),
172        }
173    }
174
175    /// Truncates the buffer to the number of frames specified. If the number of frames in the
176    /// buffer is less-than the number of frames specified, then this function does nothing.
177    pub fn truncate(&mut self, num_frames: usize) {
178        impl_generic_func!(self, buf, buf.truncate(num_frames))
179    }
180
181    /// Trims frames from the start and end of the buffer.
182    pub fn trim(&mut self, start: usize, end: usize) {
183        impl_generic_func!(self, buf, buf.trim(start, end))
184    }
185
186    /// Get the total number of samples contained in all audio planes.
187    pub fn samples_interleaved(&self) -> usize {
188        self.num_planes() * self.frames()
189    }
190
191    /// Get the total number of samples contained in each audio plane.
192    pub fn samples_planar(&self) -> usize {
193        self.frames()
194    }
195
196    /// Copy audio to a mutable audio slice while doing any necessary sample format conversions.
197    pub fn copy_to<Sout, Dst>(&self, dst: &mut Dst)
198    where
199        Sout: ConvertibleSample,
200        Dst: AudioMut<Sout>,
201    {
202        impl_generic_func!(self, buf, dst.copy_from(buf));
203    }
204
205    /// Copy all audio frames to a slice of samples in interleaved order.
206    ///
207    /// See [`AudioBuffer::copy_to_slice_interleaved`] for full details.
208    pub fn copy_to_slice_interleaved<Sout, Dst>(&self, dst: Dst)
209    where
210        Sout: ConvertibleSample,
211        Dst: AsMut<[Sout]>,
212    {
213        impl_generic_func!(self, buf, buf.copy_to_slice_interleaved(dst))
214    }
215
216    /// Copy all audio planes to discrete slices.
217    ///
218    /// See [`AudioBuffer::copy_to_slice_planar`] for full details.
219    pub fn copy_to_slice_planar<Sout, Dst>(&self, dst: &mut [Dst])
220    where
221        Sout: ConvertibleSample,
222        Dst: AsMut<[Sout]>,
223    {
224        impl_generic_func!(self, buf, buf.copy_to_slice_planar(dst))
225    }
226
227    /// Copy all audio frames to a vector of samples in interleaved order.
228    ///
229    /// See [`AudioBuffer::copy_to_vec_interleaved`] for full details.
230    pub fn copy_to_vec_interleaved<Sout>(&self, dst: &mut Vec<Sout>)
231    where
232        Sout: ConvertibleSample,
233    {
234        impl_generic_func!(self, buf, buf.copy_to_vec_interleaved(dst))
235    }
236
237    /// Copy all audio planes to discrete vectors.
238    ///
239    /// See [`AudioBuffer::copy_to_vecs_planar`] for full details.
240    pub fn copy_to_vecs_planar<Sout>(&self, dst: &mut Vec<Vec<Sout>>)
241    where
242        Sout: ConvertibleSample,
243    {
244        impl_generic_func!(self, buf, buf.copy_to_vecs_planar(dst))
245    }
246
247    /// Copy interleaved audio to the destination byte slice after converting to a different sample
248    /// format.
249    ///
250    /// See [`AudioBuffer::copy_bytes_interleaved_as`] for full details.
251    pub fn copy_bytes_interleaved_as<Sout, Dst>(&self, dst: Dst)
252    where
253        Sout: SampleBytes + ConvertibleSample,
254        Dst: AsMut<[u8]>,
255    {
256        impl_generic_func!(self, buf, buf.copy_bytes_interleaved_as::<Sout, _>(dst))
257    }
258
259    /// Copy planar audio as bytes to a destination slice per plane after converting to a different
260    /// sample format.
261    ///
262    /// See [`AudioBuffer::copy_bytes_planar_as`] for full details.
263    pub fn copy_bytes_planar_as<Sout, Dst>(&self, dst: &mut [Dst])
264    where
265        Sout: SampleBytes + ConvertibleSample,
266        Dst: AsMut<[u8]>,
267    {
268        impl_generic_func!(self, buf, buf.copy_bytes_planar_as::<Sout, _>(dst))
269    }
270
271    /// Copy interleaved audio to the destination byte slice.
272    ///
273    /// See [`AudioBuffer::copy_bytes_interleaved`] for full details.
274    pub fn copy_bytes_interleaved<Dst>(&self, dst: Dst)
275    where
276        Dst: AsMut<[u8]>,
277    {
278        impl_generic_func!(self, buf, buf.copy_bytes_interleaved(dst))
279    }
280
281    /// Copy planar audio as bytes to a destination slice per plane.
282    ///
283    /// See [`AudioBuffer::copy_bytes_planar`] for full details.
284    pub fn copy_bytes_planar<Dst>(&self, dst: &mut [Dst])
285    where
286        Dst: AsMut<[u8]>,
287    {
288        impl_generic_func!(self, buf, buf.copy_bytes_planar(dst))
289    }
290
291    /// Copy interleaved audio to the destination byte vector.
292    ///
293    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved`] for full details.
294    pub fn copy_bytes_to_vec_interleaved(&self, dst: &mut Vec<u8>) {
295        impl_generic_func!(self, buf, buf.copy_bytes_to_vec_interleaved(dst))
296    }
297
298    /// Copy interleaved audio to the destination byte vector after converting to a different sample
299    /// format.
300    ///
301    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved_as`] for full details.
302    pub fn copy_bytes_to_vec_interleaved_as<Sout>(&self, dst: &mut Vec<u8>)
303    where
304        Sout: SampleBytes + ConvertibleSample,
305    {
306        impl_generic_func!(self, buf, buf.copy_bytes_to_vec_interleaved_as::<Sout>(dst))
307    }
308
309    /// Copy audio planes as bytes to discrete byte vectors.
310    ///
311    /// See [`AudioBuffer::copy_bytes_to_vecs_planar`] for full details.
312    pub fn copy_bytes_to_vecs_planar(&self, dst: &mut Vec<Vec<u8>>) {
313        impl_generic_func!(self, buf, buf.copy_bytes_to_vecs_planar(dst))
314    }
315
316    /// Copy audio planes as bytes to discrete byte vectors after converting to a different sample
317    /// format.
318    ///
319    /// See [`AudioBuffer::copy_bytes_to_vecs_planar_as`] for full details.
320    pub fn copy_bytes_to_vecs_planar_as<Sout>(&self, dst: &mut Vec<Vec<u8>>)
321    where
322        Sout: SampleBytes + ConvertibleSample,
323    {
324        impl_generic_func!(self, buf, buf.copy_bytes_to_vecs_planar_as::<Sout>(dst))
325    }
326
327    /// Get the length in bytes of all samples if converted to a new sample format.
328    pub fn byte_len_as<Sout>(&self) -> usize
329    where
330        Sout: SampleBytes + ConvertibleSample,
331    {
332        impl_generic_func!(self, buf, buf.byte_len_as::<Sout>())
333    }
334
335    /// Get the length in bytes of all samples in a single plane if converted to a new sample
336    /// format.
337    pub fn byte_len_per_plane_as<Sout>(&self) -> usize
338    where
339        Sout: SampleBytes + ConvertibleSample,
340    {
341        impl_generic_func!(self, buf, buf.byte_len_per_plane_as::<Sout>())
342    }
343
344    /// Get the length of bytes of a single interleaved audio frame if converted to a new sample
345    /// format.
346    pub fn byte_len_per_frame_as<Sout>(&self) -> usize
347    where
348        Sout: SampleBytes + ConvertibleSample,
349    {
350        impl_generic_func!(self, buf, buf.byte_len_per_frame_as::<Sout>())
351    }
352
353    /// Get the length in bytes of all samples.
354    pub fn byte_len(&self) -> usize {
355        impl_generic_func!(self, buf, buf.byte_len())
356    }
357
358    /// Get the length in bytes of all samples in a single plane.
359    pub fn byte_len_per_plane(&self) -> usize {
360        impl_generic_func!(self, buf, buf.byte_len_per_plane())
361    }
362
363    /// Get the length of bytes of a single interleaved audio frame.
364    pub fn byte_len_per_frame(&self) -> usize {
365        impl_generic_func!(self, buf, buf.byte_len_per_frame())
366    }
367}
368
369/// A non-owning immutable reference wrapper for an [`AudioBuffer`] of any standard sample format.
370///
371/// Calls on this wrapper are dispatched to the underlying, wrapped, buffer and are semantically
372/// identical.
373#[derive(Clone)]
374pub enum GenericAudioBufferRef<'a> {
375    /// An immutable unsigned 8-bit integer audio buffer reference.
376    U8(&'a AudioBuffer<u8>),
377    /// An immutable unsigned 16-bit integer audio buffer reference.
378    U16(&'a AudioBuffer<u16>),
379    /// An immutable unsigned 24-bit integer audio buffer reference.
380    U24(&'a AudioBuffer<u24>),
381    /// An immutable unsigned 32-bit integer audio buffer reference.
382    U32(&'a AudioBuffer<u32>),
383    /// An immutable signed 8-bit integer audio buffer reference.
384    S8(&'a AudioBuffer<i8>),
385    /// An immutable signed 16-bit integer audio buffer reference.
386    S16(&'a AudioBuffer<i16>),
387    /// An immutable signed 24-bit integer audio buffer reference.
388    S24(&'a AudioBuffer<i24>),
389    /// An immutable signed 32-bit integer audio buffer reference.
390    S32(&'a AudioBuffer<i32>),
391    /// An immutable single precision (32-bit) floating point audio buffer reference.
392    F32(&'a AudioBuffer<f32>),
393    /// An immutable double precision (64-bit) floating point audio buffer reference.
394    F64(&'a AudioBuffer<f64>),
395}
396
397macro_rules! impl_generic_ref_func {
398    ($var:expr, $buf:ident,$expr:expr) => {
399        match $var {
400            GenericAudioBufferRef::U8($buf) => $expr,
401            GenericAudioBufferRef::U16($buf) => $expr,
402            GenericAudioBufferRef::U24($buf) => $expr,
403            GenericAudioBufferRef::U32($buf) => $expr,
404            GenericAudioBufferRef::S8($buf) => $expr,
405            GenericAudioBufferRef::S16($buf) => $expr,
406            GenericAudioBufferRef::S24($buf) => $expr,
407            GenericAudioBufferRef::S32($buf) => $expr,
408            GenericAudioBufferRef::F32($buf) => $expr,
409            GenericAudioBufferRef::F64($buf) => $expr,
410        }
411    };
412}
413
414impl GenericAudioBufferRef<'_> {
415    /// Get the audio specification.
416    pub fn spec(&self) -> &AudioSpec {
417        impl_generic_ref_func!(self, buf, buf.spec())
418    }
419
420    /// Get the total number of audio planes.
421    pub fn num_planes(&self) -> usize {
422        impl_generic_ref_func!(self, buf, buf.num_planes())
423    }
424
425    /// Returns `true` if there are no audio frames.
426    pub fn is_empty(&self) -> bool {
427        impl_generic_ref_func!(self, buf, buf.is_empty())
428    }
429
430    /// Gets the number of audio frames in the buffer.
431    pub fn frames(&self) -> usize {
432        impl_generic_ref_func!(self, buf, buf.frames())
433    }
434
435    /// Returns `true` if the referenced `AudioBuffer` is unused.
436    ///
437    /// An unused `AudioBuffer` has either a capacity of 0, or no channels.
438    pub fn is_unused(&self) -> bool {
439        impl_generic_ref_func!(self, buf, buf.is_unused())
440    }
441
442    /// Gets the total capacity of the buffer. The capacity is the maximum number of audio frames
443    /// the buffer can store.
444    pub fn capacity(&self) -> usize {
445        impl_generic_ref_func!(self, buf, buf.capacity())
446    }
447
448    /// Get the total number of samples contained in all audio planes.
449    pub fn samples_interleaved(&self) -> usize {
450        self.num_planes() * self.frames()
451    }
452
453    /// Get the total number of samples contained in each audio plane.
454    pub fn samples_planar(&self) -> usize {
455        self.frames()
456    }
457
458    /// Copy audio to a mutable audio slice while doing any necessary sample format conversions.
459    pub fn copy_to<Sout, Dst>(&self, dst: &mut Dst)
460    where
461        Sout: ConvertibleSample,
462        Dst: AudioMut<Sout>,
463    {
464        impl_generic_ref_func!(self, buf, dst.copy_from(*buf));
465    }
466
467    /// Copy all audio frames to a slice of samples in interleaved order.
468    ///
469    /// See [`AudioBuffer::copy_to_slice_interleaved`] for full details.
470    pub fn copy_to_slice_interleaved<Sout, Dst>(&self, dst: Dst)
471    where
472        Sout: ConvertibleSample,
473        Dst: AsMut<[Sout]>,
474    {
475        impl_generic_ref_func!(self, buf, buf.copy_to_slice_interleaved(dst))
476    }
477
478    /// Copy all audio planes to discrete slices.
479    ///
480    /// See [`AudioBuffer::copy_to_slice_planar`] for full details.
481    pub fn copy_to_slice_planar<Sout, Dst>(&self, dst: &mut [Dst])
482    where
483        Sout: ConvertibleSample,
484        Dst: AsMut<[Sout]>,
485    {
486        impl_generic_ref_func!(self, buf, buf.copy_to_slice_planar(dst))
487    }
488
489    /// Copy all audio frames to a vector of samples in interleaved order.
490    ///
491    /// See [`AudioBuffer::copy_to_vec_interleaved`] for full details.
492    pub fn copy_to_vec_interleaved<Sout>(&self, dst: &mut Vec<Sout>)
493    where
494        Sout: ConvertibleSample,
495    {
496        impl_generic_ref_func!(self, buf, buf.copy_to_vec_interleaved(dst))
497    }
498
499    /// Copy all audio planes to discrete vectors.
500    ///
501    /// See [`AudioBuffer::copy_to_vecs_planar`] for full details.
502    pub fn copy_to_vecs_planar<Sout>(&self, dst: &mut Vec<Vec<Sout>>)
503    where
504        Sout: ConvertibleSample,
505    {
506        impl_generic_ref_func!(self, buf, buf.copy_to_vecs_planar(dst))
507    }
508
509    /// Copy interleaved audio to the destination byte slice after converting to a different sample
510    /// format.
511    ///
512    /// See [`AudioBuffer::copy_bytes_interleaved_as`] for full details.
513    pub fn copy_bytes_interleaved_as<Sout, Dst>(&self, dst: Dst)
514    where
515        Sout: SampleBytes + ConvertibleSample,
516        Dst: AsMut<[u8]>,
517    {
518        impl_generic_ref_func!(self, buf, buf.copy_bytes_interleaved_as::<Sout, _>(dst))
519    }
520
521    /// Copy planar audio as bytes to a destination slice per plane after converting to a different
522    /// sample format.
523    ///
524    /// See [`AudioBuffer::copy_bytes_planar_as`] for full details.
525    pub fn copy_bytes_planar_as<Sout, Dst>(&self, dst: &mut [Dst])
526    where
527        Sout: SampleBytes + ConvertibleSample,
528        Dst: AsMut<[u8]>,
529    {
530        impl_generic_ref_func!(self, buf, buf.copy_bytes_planar_as::<Sout, _>(dst))
531    }
532
533    /// Copy interleaved audio to the destination byte slice.
534    ///
535    /// See [`AudioBuffer::copy_bytes_interleaved`] for full details.
536    pub fn copy_bytes_interleaved<Dst>(&self, dst: Dst)
537    where
538        Dst: AsMut<[u8]>,
539    {
540        impl_generic_ref_func!(self, buf, buf.copy_bytes_interleaved(dst))
541    }
542
543    /// Copy planar audio as bytes to a destination slice per plane.
544    ///
545    /// See [`AudioBuffer::copy_bytes_planar`] for full details.
546    pub fn copy_bytes_planar<Dst>(&self, dst: &mut [Dst])
547    where
548        Dst: AsMut<[u8]>,
549    {
550        impl_generic_ref_func!(self, buf, buf.copy_bytes_planar(dst))
551    }
552
553    /// Copy interleaved audio to the destination byte vector.
554    ///
555    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved`] for full details.
556    pub fn copy_bytes_to_vec_interleaved(&self, dst: &mut Vec<u8>) {
557        impl_generic_ref_func!(self, buf, buf.copy_bytes_to_vec_interleaved(dst))
558    }
559
560    /// Copy interleaved audio to the destination byte vector after converting to a different sample
561    /// format.
562    ///
563    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved_as`] for full details.
564    pub fn copy_bytes_to_vec_interleaved_as<Sout>(&self, dst: &mut Vec<u8>)
565    where
566        Sout: SampleBytes + ConvertibleSample,
567    {
568        impl_generic_ref_func!(self, buf, buf.copy_bytes_to_vec_interleaved_as::<Sout>(dst))
569    }
570
571    /// Copy audio planes as bytes to discrete byte vectors.
572    ///
573    /// See [`AudioBuffer::copy_bytes_to_vecs_planar`] for full details.
574    pub fn copy_bytes_to_vecs_planar(&self, dst: &mut Vec<Vec<u8>>) {
575        impl_generic_ref_func!(self, buf, buf.copy_bytes_to_vecs_planar(dst))
576    }
577
578    /// Copy audio planes as bytes to discrete byte vectors after converting to a different sample
579    /// format.
580    ///
581    /// See [`AudioBuffer::copy_bytes_to_vecs_planar_as`] for full details.
582    pub fn copy_bytes_to_vecs_planar_as<Sout>(&self, dst: &mut Vec<Vec<u8>>)
583    where
584        Sout: SampleBytes + ConvertibleSample,
585    {
586        impl_generic_ref_func!(self, buf, buf.copy_bytes_to_vecs_planar_as::<Sout>(dst))
587    }
588
589    /// Get the length in bytes of all samples if converted to a new sample format.
590    pub fn byte_len_as<Sout>(&self) -> usize
591    where
592        Sout: SampleBytes + ConvertibleSample,
593    {
594        impl_generic_ref_func!(self, buf, buf.byte_len_as::<Sout>())
595    }
596
597    /// Get the length in bytes of all samples in a single plane if converted to a new sample
598    /// format.
599    pub fn byte_len_per_plane_as<Sout>(&self) -> usize
600    where
601        Sout: SampleBytes + ConvertibleSample,
602    {
603        impl_generic_ref_func!(self, buf, buf.byte_len_per_plane_as::<Sout>())
604    }
605
606    /// Get the length of bytes of a single interleaved audio frame if converted to a new sample
607    /// format.
608    pub fn byte_len_per_frame_as<Sout>(&self) -> usize
609    where
610        Sout: SampleBytes + ConvertibleSample,
611    {
612        impl_generic_ref_func!(self, buf, buf.byte_len_per_frame_as::<Sout>())
613    }
614
615    /// Get the length in bytes of all samples.
616    pub fn byte_len(&self) -> usize {
617        impl_generic_ref_func!(self, buf, buf.byte_len())
618    }
619
620    /// Get the length in bytes of all samples in a single plane.
621    pub fn byte_len_per_plane(&self) -> usize {
622        impl_generic_ref_func!(self, buf, buf.byte_len_per_plane())
623    }
624
625    /// Get the length of bytes of a single interleaved audio frame.
626    pub fn byte_len_per_frame(&self) -> usize {
627        impl_generic_ref_func!(self, buf, buf.byte_len_per_frame())
628    }
629}
630
631/// A trait for generically borrowing an [`AudioBuffer`] by wrapping it in a
632/// [`GenericAudioBufferRef`].
633pub trait AsGenericAudioBufferRef {
634    /// Get an immutable reference to the audio buffer as a generic audio buffer reference.
635    fn as_generic_audio_buffer_ref(&self) -> GenericAudioBufferRef<'_>;
636}
637
638impl AsGenericAudioBufferRef for GenericAudioBuffer {
639    fn as_generic_audio_buffer_ref(&self) -> GenericAudioBufferRef<'_> {
640        impl_generic_func!(self, buf, buf.as_generic_audio_buffer_ref())
641    }
642}
643
644// Implement AsicGenericAudioBufferRef for all AudioBuffers of standard sample formats.
645macro_rules! impl_as_generic_audio_buffer_ref {
646    ($fmt:ty, $ref:path) => {
647        impl AsGenericAudioBufferRef for AudioBuffer<$fmt> {
648            fn as_generic_audio_buffer_ref(&self) -> GenericAudioBufferRef<'_> {
649                $ref(self)
650            }
651        }
652    };
653}
654
655impl_as_generic_audio_buffer_ref!(u8, GenericAudioBufferRef::U8);
656impl_as_generic_audio_buffer_ref!(u16, GenericAudioBufferRef::U16);
657impl_as_generic_audio_buffer_ref!(u24, GenericAudioBufferRef::U24);
658impl_as_generic_audio_buffer_ref!(u32, GenericAudioBufferRef::U32);
659impl_as_generic_audio_buffer_ref!(i8, GenericAudioBufferRef::S8);
660impl_as_generic_audio_buffer_ref!(i16, GenericAudioBufferRef::S16);
661impl_as_generic_audio_buffer_ref!(i24, GenericAudioBufferRef::S24);
662impl_as_generic_audio_buffer_ref!(i32, GenericAudioBufferRef::S32);
663impl_as_generic_audio_buffer_ref!(f32, GenericAudioBufferRef::F32);
664impl_as_generic_audio_buffer_ref!(f64, GenericAudioBufferRef::F64);
665
666// Implement From for conversions between AudioBuffer and GenericAudioBuffer{Ref} for all
667// standard sample formats.
668macro_rules! impl_from_converions {
669    ($fmt:ty, $own:path, $ref:path) => {
670        // Infalliable conversion from AudioBuffer<S> to GenericAudioBuffer.
671        impl From<AudioBuffer<$fmt>> for GenericAudioBuffer {
672            fn from(value: AudioBuffer<$fmt>) -> Self {
673                $own(value)
674            }
675        }
676
677        // Falliable conversion from GenericAudioBuffer to AudioBuffer<S>.
678        impl TryFrom<GenericAudioBuffer> for AudioBuffer<$fmt> {
679            type Error = ();
680
681            fn try_from(value: GenericAudioBuffer) -> Result<Self, Self::Error> {
682                match value {
683                    $own(buffer) => Ok(buffer),
684                    _ => Err(()),
685                }
686            }
687        }
688
689        // Infalliable conversion from &AudioBuffer<S> to GenericAudioBufferRef.
690        impl<'a> From<&'a AudioBuffer<$fmt>> for GenericAudioBufferRef<'a> {
691            fn from(value: &'a AudioBuffer<$fmt>) -> Self {
692                $ref(value)
693            }
694        }
695
696        // Falliable conversion from GenericAudioBufferRef to &AudioBuffer<S>.
697        impl<'a> TryFrom<GenericAudioBufferRef<'a>> for &'a AudioBuffer<$fmt> {
698            type Error = ();
699
700            fn try_from(value: GenericAudioBufferRef<'a>) -> Result<Self, Self::Error> {
701                match value {
702                    $ref(buffer) => Ok(buffer),
703                    _ => Err(()),
704                }
705            }
706        }
707    };
708}
709
710impl_from_converions!(u8, GenericAudioBuffer::U8, GenericAudioBufferRef::U8);
711impl_from_converions!(u16, GenericAudioBuffer::U16, GenericAudioBufferRef::U16);
712impl_from_converions!(u24, GenericAudioBuffer::U24, GenericAudioBufferRef::U24);
713impl_from_converions!(u32, GenericAudioBuffer::U32, GenericAudioBufferRef::U32);
714impl_from_converions!(i8, GenericAudioBuffer::S8, GenericAudioBufferRef::S8);
715impl_from_converions!(i16, GenericAudioBuffer::S16, GenericAudioBufferRef::S16);
716impl_from_converions!(i24, GenericAudioBuffer::S24, GenericAudioBufferRef::S24);
717impl_from_converions!(i32, GenericAudioBuffer::S32, GenericAudioBufferRef::S32);
718impl_from_converions!(f32, GenericAudioBuffer::F32, GenericAudioBufferRef::F32);
719impl_from_converions!(f64, GenericAudioBuffer::F64, GenericAudioBufferRef::F64);
720
721/// An owning wrapper for an [`AudioSlice`] of any standard sample format.
722///
723/// Calls on this wrapper are dispatched to the underlying, wrapped, slice and are semantically
724/// identical.
725pub enum GenericAudioSlice<'a> {
726    /// An unsigned 8-bit integer audio slice.
727    U8(AudioSlice<'a, u8>),
728    /// An unsigned 16-bit integer audio slice.
729    U16(AudioSlice<'a, u16>),
730    /// An unsigned 24-bit integer audio slice.
731    U24(AudioSlice<'a, u24>),
732    /// An unsigned 32-bit integer audio slice.
733    U32(AudioSlice<'a, u32>),
734    /// A signed 8-bit integer audio slice.
735    S8(AudioSlice<'a, i8>),
736    /// A signed 16-bit integer audio slice.
737    S16(AudioSlice<'a, i16>),
738    /// A signed 24-bit integer audio slice.
739    S24(AudioSlice<'a, i24>),
740    /// A signed 32-bit integer audio slice.
741    S32(AudioSlice<'a, i32>),
742    /// A single precision (32-bit) floating point audio slice.
743    F32(AudioSlice<'a, f32>),
744    /// A double precision (64-bit) floating point audio slice.
745    F64(AudioSlice<'a, f64>),
746}
747
748macro_rules! impl_generic_slice_func {
749    ($own:expr, $buf:ident, $expr:expr) => {
750        match $own {
751            GenericAudioSlice::U8($buf) => $expr,
752            GenericAudioSlice::U16($buf) => $expr,
753            GenericAudioSlice::U24($buf) => $expr,
754            GenericAudioSlice::U32($buf) => $expr,
755            GenericAudioSlice::S8($buf) => $expr,
756            GenericAudioSlice::S16($buf) => $expr,
757            GenericAudioSlice::S24($buf) => $expr,
758            GenericAudioSlice::S32($buf) => $expr,
759            GenericAudioSlice::F32($buf) => $expr,
760            GenericAudioSlice::F64($buf) => $expr,
761        }
762    };
763}
764
765impl<'a> GenericAudioSlice<'a> {
766    /// Get the audio specification.
767    pub fn spec(&self) -> &AudioSpec {
768        impl_generic_slice_func!(self, slice, slice.spec())
769    }
770
771    /// Get the total number of audio planes.
772    pub fn num_planes(&self) -> usize {
773        impl_generic_slice_func!(self, slice, slice.num_planes())
774    }
775
776    /// Returns `true` if there are no audio frames.
777    pub fn is_empty(&self) -> bool {
778        impl_generic_slice_func!(self, slice, slice.is_empty())
779    }
780
781    /// Gets the number of audio frames in the slice.
782    pub fn frames(&self) -> usize {
783        impl_generic_slice_func!(self, slice, slice.frames())
784    }
785
786    /// Get the total number of samples contained in all audio planes.
787    pub fn samples_interleaved(&self) -> usize {
788        self.num_planes() * self.frames()
789    }
790
791    /// Get the total number of samples contained in each audio plane.
792    pub fn samples_planar(&self) -> usize {
793        self.frames()
794    }
795
796    /// Copy audio to a mutable audio slice while doing any necessary sample format conversions.
797    pub fn copy_to<Sout, Dst>(&self, dst: &mut Dst)
798    where
799        Sout: ConvertibleSample,
800        Dst: AudioMut<Sout>,
801    {
802        impl_generic_slice_func!(self, slice, dst.copy_from(slice));
803    }
804
805    /// Copy all audio frames to a slice of samples in interleaved order.
806    ///
807    /// See [`AudioBuffer::copy_to_slice_interleaved`] for full details.
808    pub fn copy_to_slice_interleaved<Sout, Dst>(&self, dst: Dst)
809    where
810        Sout: ConvertibleSample,
811        Dst: AsMut<[Sout]>,
812    {
813        impl_generic_slice_func!(self, slice, slice.copy_to_slice_interleaved(dst))
814    }
815
816    /// Copy all audio planes to discrete slices.
817    ///
818    /// See [`AudioBuffer::copy_to_slice_planar`] for full details.
819    pub fn copy_to_slice_planar<Sout, Dst>(&self, dst: &mut [Dst])
820    where
821        Sout: ConvertibleSample,
822        Dst: AsMut<[Sout]>,
823    {
824        impl_generic_slice_func!(self, slice, slice.copy_to_slice_planar(dst))
825    }
826
827    /// Copy all audio frames to a vector of samples in interleaved order.
828    ///
829    /// See [`AudioBuffer::copy_to_vec_interleaved`] for full details.
830    pub fn copy_to_vec_interleaved<Sout>(&self, dst: &mut Vec<Sout>)
831    where
832        Sout: ConvertibleSample,
833    {
834        impl_generic_slice_func!(self, slice, slice.copy_to_vec_interleaved(dst))
835    }
836
837    /// Copy all audio planes to discrete vectors.
838    ///
839    /// See [`AudioBuffer::copy_to_vecs_planar`] for full details.
840    pub fn copy_to_vecs_planar<Sout>(&self, dst: &mut Vec<Vec<Sout>>)
841    where
842        Sout: ConvertibleSample,
843    {
844        impl_generic_slice_func!(self, slice, slice.copy_to_vecs_planar(dst))
845    }
846
847    /// Copy interleaved audio to the destination byte slice after converting to a different sample
848    /// format.
849    ///
850    /// See [`AudioBuffer::copy_bytes_interleaved_as`] for full details.
851    pub fn copy_bytes_interleaved_as<Sout, Dst>(&self, dst: Dst)
852    where
853        Sout: SampleBytes + ConvertibleSample,
854        Dst: AsMut<[u8]>,
855    {
856        impl_generic_slice_func!(self, slice, slice.copy_bytes_interleaved_as::<Sout, _>(dst))
857    }
858
859    /// Copy planar audio as bytes to a destination slice per plane after converting to a different
860    /// sample format.
861    ///
862    /// See [`AudioBuffer::copy_bytes_planar_as`] for full details.
863    pub fn copy_bytes_planar_as<Sout, Dst>(&self, dst: &mut [Dst])
864    where
865        Sout: SampleBytes + ConvertibleSample,
866        Dst: AsMut<[u8]>,
867    {
868        impl_generic_slice_func!(self, slice, slice.copy_bytes_planar_as::<Sout, _>(dst))
869    }
870
871    /// Copy interleaved audio to the destination byte slice.
872    ///
873    /// See [`AudioBuffer::copy_bytes_interleaved`] for full details.
874    pub fn copy_bytes_interleaved<Dst>(&self, dst: Dst)
875    where
876        Dst: AsMut<[u8]>,
877    {
878        impl_generic_slice_func!(self, slice, slice.copy_bytes_interleaved(dst))
879    }
880
881    /// Copy planar audio as bytes to a destination slice per plane.
882    ///
883    /// See [`AudioBuffer::copy_bytes_planar`] for full details.
884    pub fn copy_bytes_planar<Dst>(&self, dst: &mut [Dst])
885    where
886        Dst: AsMut<[u8]>,
887    {
888        impl_generic_slice_func!(self, slice, slice.copy_bytes_planar(dst))
889    }
890
891    /// Copy interleaved audio to the destination byte vector.
892    ///
893    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved`] for full details.
894    pub fn copy_bytes_to_vec_interleaved(&self, dst: &mut Vec<u8>) {
895        impl_generic_slice_func!(self, slice, slice.copy_bytes_to_vec_interleaved(dst))
896    }
897
898    /// Copy interleaved audio to the destination byte vector after converting to a different sample
899    /// format.
900    ///
901    /// See [`AudioBuffer::copy_bytes_to_vec_interleaved_as`] for full details.
902    pub fn copy_bytes_to_vec_interleaved_as<Sout>(&self, dst: &mut Vec<u8>)
903    where
904        Sout: SampleBytes + ConvertibleSample,
905    {
906        impl_generic_slice_func!(self, slice, slice.copy_bytes_to_vec_interleaved_as::<Sout>(dst))
907    }
908
909    /// Copy audio planes as bytes to discrete byte vectors.
910    ///
911    /// See [`AudioBuffer::copy_bytes_to_vecs_planar`] for full details.
912    pub fn copy_bytes_to_vecs_planar(&self, dst: &mut Vec<Vec<u8>>) {
913        impl_generic_slice_func!(self, slice, slice.copy_bytes_to_vecs_planar(dst))
914    }
915
916    /// Copy audio planes as bytes to discrete byte vectors after converting to a different sample
917    /// format.
918    ///
919    /// See [`AudioBuffer::copy_bytes_to_vecs_planar_as`] for full details.
920    pub fn copy_bytes_to_vecs_planar_as<Sout>(&self, dst: &mut Vec<Vec<u8>>)
921    where
922        Sout: SampleBytes + ConvertibleSample,
923    {
924        impl_generic_slice_func!(self, slice, slice.copy_bytes_to_vecs_planar_as::<Sout>(dst))
925    }
926
927    /// Get the length in bytes of all samples if converted to a new sample format.
928    pub fn byte_len_as<Sout>(&self) -> usize
929    where
930        Sout: SampleBytes + ConvertibleSample,
931    {
932        impl_generic_slice_func!(self, slice, slice.byte_len_as::<Sout>())
933    }
934
935    /// Get the length in bytes of all samples in a single plane if converted to a new sample
936    /// format.
937    pub fn byte_len_per_plane_as<Sout>(&self) -> usize
938    where
939        Sout: SampleBytes + ConvertibleSample,
940    {
941        impl_generic_slice_func!(self, slice, slice.byte_len_per_plane_as::<Sout>())
942    }
943
944    /// Get the length of bytes of a single interleaved audio frame if converted to a new sample
945    /// format.
946    pub fn byte_len_per_frame_as<Sout>(&self) -> usize
947    where
948        Sout: SampleBytes + ConvertibleSample,
949    {
950        impl_generic_slice_func!(self, slice, slice.byte_len_per_frame_as::<Sout>())
951    }
952
953    /// Get the length in bytes of all samples.
954    pub fn byte_len(&self) -> usize {
955        impl_generic_slice_func!(self, slice, slice.byte_len())
956    }
957
958    /// Get the length in bytes of all samples in a single plane.
959    pub fn byte_len_per_plane(&self) -> usize {
960        impl_generic_slice_func!(self, slice, slice.byte_len_per_plane())
961    }
962
963    /// Get the length of bytes of a single interleaved audio frame.
964    pub fn byte_len_per_frame(&self) -> usize {
965        impl_generic_slice_func!(self, slice, slice.byte_len_per_frame())
966    }
967}