symphonia_core/
audio.rs

1// Symphonia
2// Copyright (c) 2019-2022 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
8//! The `audio` module provides primitives for working with multi-channel audio buffers of varying
9//! sample formats.
10
11use std::borrow::Cow;
12use std::fmt;
13use std::marker::PhantomData;
14use std::mem;
15use std::vec::Vec;
16
17use arrayvec::ArrayVec;
18use bitflags::bitflags;
19
20use crate::conv::{ConvertibleSample, FromSample, IntoSample};
21use crate::errors::Result;
22use crate::sample::{i24, u24, Sample};
23use crate::units::Duration;
24
25/// The maximum number of audio plane slices `AudioPlanes` or `AudioPlanesMut` will store on the
26/// stack before storing the slices on the heap.
27const AUDIO_PLANES_STORAGE_STACK_LIMIT: usize = 8;
28
29bitflags! {
30    /// A bitmask representing the audio channels in an audio buffer or signal.
31    ///
32    /// The first 18 defined channels are guaranteed to be identical to those specified by
33    /// Microsoft's WAVEFORMATEXTENSIBLE structure. Channels after 18 are defined by Symphonia and
34    /// no order is guaranteed.
35    #[derive(Default)]
36    pub struct Channels: u32 {
37        /// Front-left (left) or the Mono channel.
38        const FRONT_LEFT         = 0x0000_0001;
39        /// Front-right (right) channel.
40        const FRONT_RIGHT        = 0x0000_0002;
41        /// Front-centre (centre) channel.
42        const FRONT_CENTRE       = 0x0000_0004;
43        /// Low frequency channel 1.
44        const LFE1               = 0x0000_0008;
45        /// Rear-left (surround rear left) channel.
46        const REAR_LEFT          = 0x0000_0010;
47        /// Rear-right (surround rear right) channel.
48        const REAR_RIGHT         = 0x0000_0020;
49        /// Front left-of-centre (left center) channel.
50        const FRONT_LEFT_CENTRE  = 0x0000_0040;
51        /// Front right-of-centre (right center) channel.
52        const FRONT_RIGHT_CENTRE = 0x0000_0080;
53        /// Rear-centre (surround rear centre) channel.
54        const REAR_CENTRE        = 0x0000_0100;
55        /// Side left (surround left) channel.
56        const SIDE_LEFT          = 0x0000_0200;
57        /// Side right (surround right) channel.
58        const SIDE_RIGHT         = 0x0000_0400;
59        /// Top centre channel.
60        const TOP_CENTRE         = 0x0000_0800;
61        /// Top front-left channel.
62        const TOP_FRONT_LEFT     = 0x0000_1000;
63        /// Top centre channel.
64        const TOP_FRONT_CENTRE   = 0x0000_2000;
65        /// Top front-right channel.
66        const TOP_FRONT_RIGHT    = 0x0000_4000;
67        /// Top rear-left channel.
68        const TOP_REAR_LEFT      = 0x0000_8000;
69        /// Top rear-centre channel.
70        const TOP_REAR_CENTRE    = 0x0001_0000;
71        /// Top rear-right channel.
72        const TOP_REAR_RIGHT     = 0x0002_0000;
73        /// Rear left-of-centre channel.
74        const REAR_LEFT_CENTRE   = 0x0004_0000;
75        /// Rear right-of-centre channel.
76        const REAR_RIGHT_CENTRE  = 0x0008_0000;
77        /// Front left-wide channel.
78        const FRONT_LEFT_WIDE    = 0x0010_0000;
79        /// Front right-wide channel.
80        const FRONT_RIGHT_WIDE   = 0x0020_0000;
81        /// Front left-high channel.
82        const FRONT_LEFT_HIGH    = 0x0040_0000;
83        /// Front centre-high channel.
84        const FRONT_CENTRE_HIGH  = 0x0080_0000;
85        /// Front right-high channel.
86        const FRONT_RIGHT_HIGH   = 0x0100_0000;
87        /// Low frequency channel 2.
88        const LFE2               = 0x0200_0000;
89    }
90}
91
92/// An iterator over individual channels within a `Channels` bitmask.
93pub struct ChannelsIter {
94    channels: Channels,
95}
96
97impl Iterator for ChannelsIter {
98    type Item = Channels;
99
100    fn next(&mut self) -> Option<Self::Item> {
101        if !self.channels.is_empty() {
102            let channel = Channels::from_bits_truncate(1 << self.channels.bits.trailing_zeros());
103            self.channels ^= channel;
104            Some(channel)
105        }
106        else {
107            None
108        }
109    }
110}
111
112impl Channels {
113    /// Gets the number of channels.
114    pub fn count(self) -> usize {
115        self.bits.count_ones() as usize
116    }
117
118    /// Gets an iterator over individual channels.
119    pub fn iter(&self) -> ChannelsIter {
120        ChannelsIter { channels: *self }
121    }
122}
123
124impl fmt::Display for Channels {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126        write!(f, "{:#032b}", self.bits)
127    }
128}
129
130/// `Layout` describes common audio channel configurations.
131#[derive(Copy, Clone, Debug)]
132pub enum Layout {
133    /// Single centre channel.
134    Mono,
135    /// Left and Right channels.
136    Stereo,
137    /// Left and Right channels with a single low-frequency channel.
138    TwoPointOne,
139    /// Front Left and Right, Rear Left and Right, and a single low-frequency channel.
140    FivePointOne,
141}
142
143impl Layout {
144    /// Converts a channel `Layout` into a `Channels` bit mask.
145    pub fn into_channels(self) -> Channels {
146        match self {
147            Layout::Mono => Channels::FRONT_LEFT,
148            Layout::Stereo => Channels::FRONT_LEFT | Channels::FRONT_RIGHT,
149            Layout::TwoPointOne => Channels::FRONT_LEFT | Channels::FRONT_RIGHT | Channels::LFE1,
150            Layout::FivePointOne => {
151                Channels::FRONT_LEFT
152                    | Channels::FRONT_RIGHT
153                    | Channels::FRONT_CENTRE
154                    | Channels::REAR_LEFT
155                    | Channels::REAR_RIGHT
156                    | Channels::LFE1
157            }
158        }
159    }
160}
161
162/// `SignalSpec` describes the characteristics of a Signal.
163#[derive(Copy, Clone, Debug, PartialEq, Eq)]
164pub struct SignalSpec {
165    /// The signal sampling rate in hertz (Hz).
166    pub rate: u32,
167
168    /// The channel assignments of the signal. The order of the channels in the vector is the order
169    /// in which each channel sample is stored in a frame.
170    pub channels: Channels,
171}
172
173impl SignalSpec {
174    pub fn new(rate: u32, channels: Channels) -> Self {
175        SignalSpec { rate, channels }
176    }
177
178    pub fn new_with_layout(rate: u32, layout: Layout) -> Self {
179        SignalSpec { rate, channels: layout.into_channels() }
180    }
181}
182
183/// Small-storage optimization capable storage of immutable slices of `AudioBuffer` audio planes.
184enum AudioPlaneStorage<'a, S, const N: usize> {
185    Stack(ArrayVec<&'a [S], N>),
186    Heap(Vec<&'a [S]>),
187}
188
189/// `AudioPlanes` provides immutable slices to each audio channel (plane) contained in a signal.
190pub struct AudioPlanes<'a, S: 'a + Sample> {
191    planes: AudioPlaneStorage<'a, S, AUDIO_PLANES_STORAGE_STACK_LIMIT>,
192}
193
194impl<'a, S: Sample> AudioPlanes<'a, S> {
195    /// Instantiate `AudioPlanes` for the given channel configuration.
196    fn new(channels: Channels) -> Self {
197        let n_planes = channels.count();
198
199        if n_planes <= AUDIO_PLANES_STORAGE_STACK_LIMIT {
200            AudioPlanes { planes: AudioPlaneStorage::Stack(ArrayVec::new()) }
201        }
202        else {
203            AudioPlanes { planes: AudioPlaneStorage::Heap(Vec::with_capacity(n_planes)) }
204        }
205    }
206
207    /// Push an immutable reference to an audio plane. This function may panic if the number of
208    /// pushed planes exceeds the number specified at instantiation.
209    fn push(&mut self, plane: &'a [S]) {
210        match &mut self.planes {
211            AudioPlaneStorage::Stack(planes) => {
212                debug_assert!(!planes.is_full());
213                planes.push(plane);
214            }
215            AudioPlaneStorage::Heap(planes) => {
216                planes.push(plane);
217            }
218        }
219    }
220
221    /// Gets immutable slices of all the audio planes.
222    pub fn planes(&self) -> &[&'a [S]] {
223        match &self.planes {
224            AudioPlaneStorage::Stack(planes) => planes,
225            AudioPlaneStorage::Heap(planes) => planes,
226        }
227    }
228}
229
230/// Small-storage optimization capable storage of mutable slices of `AudioBuffer` audio planes.
231enum AudioPlaneStorageMut<'a, S, const N: usize> {
232    Stack(ArrayVec<&'a mut [S], N>),
233    Heap(Vec<&'a mut [S]>),
234}
235
236/// `AudioPlanesMut` provides mutable slices to each audio channel (plane) contained in a signal.
237pub struct AudioPlanesMut<'a, S: 'a + Sample> {
238    planes: AudioPlaneStorageMut<'a, S, AUDIO_PLANES_STORAGE_STACK_LIMIT>,
239}
240
241impl<'a, S: Sample> AudioPlanesMut<'a, S> {
242    /// Instantiate `AudioPlanesMut` for the given channel configuration.
243    fn new(channels: Channels) -> Self {
244        let n_planes = channels.count();
245
246        if n_planes <= AUDIO_PLANES_STORAGE_STACK_LIMIT {
247            AudioPlanesMut { planes: AudioPlaneStorageMut::Stack(ArrayVec::new()) }
248        }
249        else {
250            AudioPlanesMut { planes: AudioPlaneStorageMut::Heap(Vec::with_capacity(n_planes)) }
251        }
252    }
253
254    /// Push a mutable reference to an audio plane. This function may panic if the number of
255    /// pushed planes exceeds the number specified at instantiation.
256    fn push(&mut self, plane: &'a mut [S]) {
257        match &mut self.planes {
258            AudioPlaneStorageMut::Stack(planes) => {
259                debug_assert!(!planes.is_full());
260                planes.push(plane);
261            }
262            AudioPlaneStorageMut::Heap(storage) => {
263                storage.push(plane);
264            }
265        }
266    }
267
268    /// Gets mutable slices of all the audio planes.
269    pub fn planes(&mut self) -> &mut [&'a mut [S]] {
270        match &mut self.planes {
271            AudioPlaneStorageMut::Stack(planes) => planes,
272            AudioPlaneStorageMut::Heap(planes) => planes,
273        }
274    }
275}
276
277/// `AudioBuffer` is a container for multi-channel planar audio sample data. An `AudioBuffer` is
278/// characterized by the duration (capacity), and audio specification (channels and sample rate).
279/// The capacity of an `AudioBuffer` is the maximum number of samples the buffer may store per
280/// channel. Manipulation of samples is accomplished through the Signal trait or direct buffer
281/// manipulation.
282#[derive(Clone)]
283pub struct AudioBuffer<S: Sample> {
284    buf: Vec<S>,
285    spec: SignalSpec,
286    n_frames: usize,
287    n_capacity: usize,
288}
289
290impl<S: Sample> AudioBuffer<S> {
291    /// Instantiate a new `AudioBuffer` using the specified signal specification and of the given
292    /// duration.
293    pub fn new(duration: Duration, spec: SignalSpec) -> Self {
294        // The number of channels * duration cannot exceed u64::MAX.
295        assert!(duration <= u64::MAX / spec.channels.count() as u64, "duration too large");
296
297        // The total number of samples the buffer will store.
298        let n_samples = duration * spec.channels.count() as u64;
299
300        // Practically speaking, it is not possible to allocate more than usize::MAX bytes of
301        // samples. This assertion ensures the potential downcast of n_samples to usize below is
302        // safe.
303        assert!(n_samples <= (usize::MAX / mem::size_of::<S>()) as u64, "duration too large");
304
305        // Allocate sample buffer and default initialize all samples to silence.
306        let buf = vec![S::MID; n_samples as usize];
307
308        AudioBuffer { buf, spec, n_frames: 0, n_capacity: duration as usize }
309    }
310
311    /// Instantiates an unused `AudioBuffer`. An unused `AudioBuffer` will not allocate any memory,
312    /// has a sample rate of 0, and no audio channels.
313    pub fn unused() -> Self {
314        AudioBuffer {
315            buf: Vec::with_capacity(0),
316            spec: SignalSpec::new(0, Channels::empty()),
317            n_frames: 0,
318            n_capacity: 0,
319        }
320    }
321
322    /// Returns `true` if the `AudioBuffer` is unused.
323    pub fn is_unused(&self) -> bool {
324        self.n_capacity == 0
325    }
326
327    /// Gets the signal specification for the buffer.
328    pub fn spec(&self) -> &SignalSpec {
329        &self.spec
330    }
331
332    /// Gets the total capacity of the buffer. The capacity is the maximum number of audio frames
333    /// a buffer can store.
334    pub fn capacity(&self) -> usize {
335        self.n_capacity
336    }
337
338    /// Gets immutable references to all audio planes (channels) within the audio buffer.
339    ///
340    /// Note: This is not a cheap operation for audio buffers with > 8 channels. It is advisable
341    /// that this call is only used when operating on large batches of frames. Generally speaking,
342    /// it is almost always better to use `chan()` to selectively choose the plane to read instead.
343    pub fn planes(&self) -> AudioPlanes<S> {
344        // Fill the audio planes structure with references to the written portion of each audio
345        // plane.
346        let mut planes = AudioPlanes::new(self.spec.channels);
347
348        for channel in self.buf.chunks_exact(self.n_capacity) {
349            planes.push(&channel[..self.n_frames]);
350        }
351
352        planes
353    }
354
355    /// Gets mutable references to all audio planes (channels) within the buffer.
356    ///
357    /// Note: This is not a cheap operation for audio buffers with > 8 channels. It is advisable
358    /// that this call is only used when modifying large batches of frames. Generally speaking,
359    /// it is almost always better to use `render()`, `fill()`, `chan_mut()`, and `chan_pair_mut()`
360    /// to modify the buffer instead.
361    pub fn planes_mut(&mut self) -> AudioPlanesMut<S> {
362        // Fill the audio planes structure with references to the written portion of each audio
363        // plane.
364        let mut planes = AudioPlanesMut::new(self.spec.channels);
365
366        for channel in self.buf.chunks_exact_mut(self.n_capacity) {
367            planes.push(&mut channel[..self.n_frames]);
368        }
369
370        planes
371    }
372
373    /// Converts the contents of an AudioBuffer into an equivalent destination AudioBuffer of a
374    /// different type. If the types are the same then this is a copy operation.
375    pub fn convert<T: Sample>(&self, dest: &mut AudioBuffer<T>)
376    where
377        S: IntoSample<T>,
378    {
379        assert!(dest.n_capacity >= self.n_capacity);
380        assert!(dest.spec == self.spec);
381
382        for c in 0..self.spec.channels.count() {
383            let begin = c * self.n_capacity;
384            let end = begin + self.n_frames;
385
386            for (d, s) in dest.buf[begin..end].iter_mut().zip(&self.buf[begin..end]) {
387                *d = (*s).into_sample();
388            }
389        }
390
391        dest.n_frames = self.n_frames;
392    }
393
394    /// Makes an equivalent AudioBuffer of a different type.
395    pub fn make_equivalent<E: Sample>(&self) -> AudioBuffer<E> {
396        AudioBuffer::<E>::new(self.n_capacity as Duration, self.spec)
397    }
398}
399
400macro_rules! impl_audio_buffer_ref_func {
401    ($var:expr, $buf:ident,$expr:expr) => {
402        match $var {
403            AudioBufferRef::U8($buf) => $expr,
404            AudioBufferRef::U16($buf) => $expr,
405            AudioBufferRef::U24($buf) => $expr,
406            AudioBufferRef::U32($buf) => $expr,
407            AudioBufferRef::S8($buf) => $expr,
408            AudioBufferRef::S16($buf) => $expr,
409            AudioBufferRef::S24($buf) => $expr,
410            AudioBufferRef::S32($buf) => $expr,
411            AudioBufferRef::F32($buf) => $expr,
412            AudioBufferRef::F64($buf) => $expr,
413        }
414    };
415}
416
417/// `AudioBufferRef` is a copy-on-write reference to an `AudioBuffer` of any type.
418#[derive(Clone)]
419pub enum AudioBufferRef<'a> {
420    U8(Cow<'a, AudioBuffer<u8>>),
421    U16(Cow<'a, AudioBuffer<u16>>),
422    U24(Cow<'a, AudioBuffer<u24>>),
423    U32(Cow<'a, AudioBuffer<u32>>),
424    S8(Cow<'a, AudioBuffer<i8>>),
425    S16(Cow<'a, AudioBuffer<i16>>),
426    S24(Cow<'a, AudioBuffer<i24>>),
427    S32(Cow<'a, AudioBuffer<i32>>),
428    F32(Cow<'a, AudioBuffer<f32>>),
429    F64(Cow<'a, AudioBuffer<f64>>),
430}
431
432impl<'a> AudioBufferRef<'a> {
433    /// Gets the signal specification for the buffer.
434    pub fn spec(&self) -> &SignalSpec {
435        impl_audio_buffer_ref_func!(self, buf, buf.spec())
436    }
437
438    /// Gets the total capacity of the buffer. The capacity is the maximum number of audio frames
439    /// a buffer can store.
440    pub fn capacity(&self) -> usize {
441        impl_audio_buffer_ref_func!(self, buf, buf.capacity())
442    }
443
444    /// Gets the number of frames in the buffer.
445    pub fn frames(&self) -> usize {
446        impl_audio_buffer_ref_func!(self, buf, buf.frames())
447    }
448
449    pub fn convert<T>(&self, dest: &mut AudioBuffer<T>)
450    where
451        T: Sample
452            + FromSample<u8>
453            + FromSample<u16>
454            + FromSample<u24>
455            + FromSample<u32>
456            + FromSample<i8>
457            + FromSample<i16>
458            + FromSample<i24>
459            + FromSample<i32>
460            + FromSample<f32>
461            + FromSample<f64>,
462    {
463        impl_audio_buffer_ref_func!(self, buf, buf.convert(dest))
464    }
465
466    pub fn make_equivalent<E: Sample>(&self) -> AudioBuffer<E> {
467        impl_audio_buffer_ref_func!(self, buf, buf.make_equivalent::<E>())
468    }
469}
470
471/// `AsAudioBufferRef` is a trait implemented for `AudioBuffer`s that may be referenced in an
472/// `AudioBufferRef`.
473pub trait AsAudioBufferRef {
474    /// Get an `AudioBufferRef` reference.
475    fn as_audio_buffer_ref(&self) -> AudioBufferRef;
476}
477
478macro_rules! impl_as_audio_buffer_ref {
479    ($fmt:ty, $ref:path) => {
480        impl AsAudioBufferRef for AudioBuffer<$fmt> {
481            fn as_audio_buffer_ref(&self) -> AudioBufferRef {
482                $ref(Cow::Borrowed(self))
483            }
484        }
485    };
486}
487
488impl_as_audio_buffer_ref!(u8, AudioBufferRef::U8);
489impl_as_audio_buffer_ref!(u16, AudioBufferRef::U16);
490impl_as_audio_buffer_ref!(u24, AudioBufferRef::U24);
491impl_as_audio_buffer_ref!(u32, AudioBufferRef::U32);
492impl_as_audio_buffer_ref!(i8, AudioBufferRef::S8);
493impl_as_audio_buffer_ref!(i16, AudioBufferRef::S16);
494impl_as_audio_buffer_ref!(i24, AudioBufferRef::S24);
495impl_as_audio_buffer_ref!(i32, AudioBufferRef::S32);
496impl_as_audio_buffer_ref!(f32, AudioBufferRef::F32);
497impl_as_audio_buffer_ref!(f64, AudioBufferRef::F64);
498
499/// The `Signal` trait provides methods for rendering and transforming contiguous buffers of audio
500/// data.
501pub trait Signal<S: Sample> {
502    /// Gets the number of actual frames written to the buffer. Conversely, this also is the number
503    /// of written samples in any one channel.
504    fn frames(&self) -> usize;
505
506    /// Clears all written frames from the buffer. This is a cheap operation and does not zero the
507    /// underlying audio data.
508    fn clear(&mut self);
509
510    /// Gets an immutable reference to all the written samples in the specified channel.
511    fn chan(&self, channel: usize) -> &[S];
512
513    /// Gets a mutable reference to all the written samples in the specified channel.
514    fn chan_mut(&mut self, channel: usize) -> &mut [S];
515
516    /// Gets two mutable references to two different channels.
517    fn chan_pair_mut(&mut self, first: usize, second: usize) -> (&mut [S], &mut [S]);
518
519    /// Renders a number of silent frames.
520    ///
521    /// If `n_frames` is `None`, the remaining number of frames will be used.
522    fn render_silence(&mut self, n_frames: Option<usize>);
523
524    /// Renders a reserved number of frames. This is a cheap operation and simply advances the frame
525    /// counter. The underlying audio data is not modified and should be overwritten through other
526    /// means.
527    ///
528    /// If `n_frames` is `None`, the remaining number of frames will be used. If `n_frames` is too
529    /// large, this function will assert.
530    fn render_reserved(&mut self, n_frames: Option<usize>);
531
532    /// Renders a number of frames using the provided render function. The number of frames to
533    /// render is specified by `n_frames`. If `n_frames` is `None`, the remaining number of frames
534    /// in the buffer will be rendered. If the render function returns an error, the render
535    /// operation is terminated prematurely.
536    fn render<'a, F>(&'a mut self, n_frames: Option<usize>, render: F) -> Result<()>
537    where
538        F: FnMut(&mut AudioPlanesMut<'a, S>, usize) -> Result<()>;
539
540    /// Clears, and then renders the entire buffer using the fill function. This is a convenience
541    /// wrapper around `render` and exhibits the same behaviour as `render` in regards to the fill
542    /// function.
543    #[inline]
544    fn fill<'a, F>(&'a mut self, fill: F) -> Result<()>
545    where
546        F: FnMut(&mut AudioPlanesMut<'a, S>, usize) -> Result<()>,
547    {
548        self.clear();
549        self.render(None, fill)
550    }
551
552    /// Transforms every written sample in the signal using the transformation function provided.
553    /// This function does not guarantee an order in which the samples are transformed.
554    fn transform<F>(&mut self, f: F)
555    where
556        F: Fn(S) -> S;
557
558    /// Truncates the buffer to the number of frames specified. If the number of frames in the
559    /// buffer is less-than the number of frames specified, then this function does nothing.
560    fn truncate(&mut self, n_frames: usize);
561
562    /// Shifts the contents of the buffer back by the number of frames specified. The leading frames
563    /// are dropped from the buffer.
564    fn shift(&mut self, shift: usize);
565
566    /// Trims samples from the start and end of the buffer.
567    fn trim(&mut self, start: usize, end: usize) {
568        // First, trim the end to reduce the number of frames have to be shifted when the front is
569        // trimmed.
570        self.truncate(self.frames().saturating_sub(end));
571
572        // Second, trim the start.
573        self.shift(start);
574    }
575}
576
577impl<S: Sample> Signal<S> for AudioBuffer<S> {
578    fn clear(&mut self) {
579        self.n_frames = 0;
580    }
581
582    fn frames(&self) -> usize {
583        self.n_frames
584    }
585
586    fn chan(&self, channel: usize) -> &[S] {
587        let start = channel * self.n_capacity;
588
589        // If the channel index is invalid the slice will be out-of-bounds.
590        assert!(start + self.n_capacity <= self.buf.len(), "invalid channel index");
591
592        &self.buf[start..start + self.n_frames]
593    }
594
595    fn chan_mut(&mut self, channel: usize) -> &mut [S] {
596        let start = channel * self.n_capacity;
597
598        // If the channel index is invalid the slice will be out-of-bounds.
599        assert!(start + self.n_capacity <= self.buf.len(), "invalid channel index");
600
601        &mut self.buf[start..start + self.n_frames]
602    }
603
604    fn chan_pair_mut(&mut self, first: usize, second: usize) -> (&mut [S], &mut [S]) {
605        // Both channels in the pair must be unique.
606        assert!(first != second, "channel indicies cannot be the same");
607
608        let first_idx = self.n_capacity * first;
609        let second_idx = self.n_capacity * second;
610
611        // If a channel index is invalid the slice will be out-of-bounds.
612        assert!(first_idx + self.n_capacity <= self.buf.len(), "invalid channel index");
613        assert!(second_idx + self.n_capacity <= self.buf.len(), "invalid channel index");
614
615        if first_idx < second_idx {
616            let (a, b) = self.buf.split_at_mut(second_idx);
617
618            (&mut a[first_idx..first_idx + self.n_frames], &mut b[..self.n_frames])
619        }
620        else {
621            let (a, b) = self.buf.split_at_mut(first_idx);
622
623            (&mut b[..self.n_frames], &mut a[second_idx..second_idx + self.n_frames])
624        }
625    }
626
627    fn render_silence(&mut self, n_frames: Option<usize>) {
628        let n_silent_frames = n_frames.unwrap_or(self.n_capacity - self.n_frames);
629
630        // Do not render past the end of the audio buffer.
631        assert!(self.n_frames + n_silent_frames <= self.capacity(), "capacity will be exceeded");
632
633        for channel in self.buf.chunks_exact_mut(self.n_capacity) {
634            for sample in &mut channel[self.n_frames..self.n_frames + n_silent_frames] {
635                *sample = S::MID;
636            }
637        }
638
639        self.n_frames += n_silent_frames;
640    }
641
642    fn render_reserved(&mut self, n_frames: Option<usize>) {
643        let n_reserved_frames = n_frames.unwrap_or(self.n_capacity - self.n_frames);
644        // Do not render past the end of the audio buffer.
645        assert!(self.n_frames + n_reserved_frames <= self.n_capacity, "capacity will be exceeded");
646        self.n_frames += n_reserved_frames;
647    }
648
649    fn render<'a, F>(&'a mut self, n_frames: Option<usize>, mut render: F) -> Result<()>
650    where
651        F: FnMut(&mut AudioPlanesMut<'a, S>, usize) -> Result<()>,
652    {
653        // The number of frames to be rendered is the amount requested, if specified, or the
654        // remainder of the audio buffer.
655        let n_render_frames = n_frames.unwrap_or(self.n_capacity - self.n_frames);
656
657        // Do not render past the end of the audio buffer.
658        let end = self.n_frames + n_render_frames;
659        assert!(end <= self.n_capacity, "capacity will be exceeded");
660
661        // At this point, n_render_frames can be considered "reserved". Create an audio plane
662        // structure and fill each plane entry with a reference to the "reserved" samples in each
663        // channel respectively.
664        let mut planes = AudioPlanesMut::new(self.spec.channels);
665
666        for channel in self.buf.chunks_exact_mut(self.n_capacity) {
667            planes.push(&mut channel[self.n_frames..end]);
668        }
669
670        // Attempt to render the into the reserved frames, one-by-one, exiting only if there is an
671        // error in the render function.
672        while self.n_frames < end {
673            render(&mut planes, self.n_frames)?;
674            self.n_frames += 1;
675        }
676
677        Ok(())
678    }
679
680    fn transform<F>(&mut self, f: F)
681    where
682        F: Fn(S) -> S,
683    {
684        debug_assert!(self.n_frames <= self.n_capacity);
685
686        // Apply the transformation function over each sample in each plane.
687        for plane in self.buf.chunks_mut(self.n_capacity) {
688            for sample in &mut plane[0..self.n_frames] {
689                *sample = f(*sample);
690            }
691        }
692    }
693
694    fn truncate(&mut self, n_frames: usize) {
695        if n_frames < self.n_frames {
696            self.n_frames = n_frames;
697        }
698    }
699
700    fn shift(&mut self, shift: usize) {
701        if shift >= self.n_frames {
702            self.clear();
703        }
704        else if shift > 0 {
705            // Shift the samples down in each plane.
706            for plane in self.buf.chunks_mut(self.n_capacity) {
707                plane.copy_within(shift..self.n_frames, 0);
708            }
709            self.n_frames -= shift;
710        }
711    }
712}
713
714/// A `SampleBuffer`, is a sample oriented buffer. It is agnostic to the ordering/layout of samples
715/// within the buffer. `SampleBuffer` is mean't for safely importing and exporting sample data to
716/// and from Symphonia using the sample's in-memory data-type.
717pub struct SampleBuffer<S: Sample> {
718    buf: Box<[S]>,
719    n_written: usize,
720}
721
722impl<S: Sample> SampleBuffer<S> {
723    /// Instantiate a new `SampleBuffer` using the specified signal specification and of the given
724    /// duration.
725    pub fn new(duration: Duration, spec: SignalSpec) -> SampleBuffer<S> {
726        // The number of channels * duration cannot exceed u64::MAX.
727        assert!(duration <= u64::MAX / spec.channels.count() as u64, "duration too large");
728
729        // The total number of samples the buffer will store.
730        let n_samples = duration * spec.channels.count() as u64;
731
732        // Practically speaking, it is not possible to allocate more than usize::MAX bytes of
733        // samples. This assertion ensures the potential downcast of n_samples to usize below is
734        // safe.
735        assert!(n_samples <= (usize::MAX / mem::size_of::<S>()) as u64, "duration too large");
736
737        // Allocate enough memory for all the samples and fill the buffer with silence.
738        let buf = vec![S::MID; n_samples as usize].into_boxed_slice();
739
740        SampleBuffer { buf, n_written: 0 }
741    }
742
743    /// Gets the number of written samples.
744    pub fn len(&self) -> usize {
745        self.n_written
746    }
747
748    /// Returns `true` if the buffer contains no written samples.
749    pub fn is_empty(&self) -> bool {
750        self.n_written == 0
751    }
752
753    /// Gets an immutable slice of all written samples.
754    pub fn samples(&self) -> &[S] {
755        &self.buf[..self.n_written]
756    }
757
758    /// Gets a mutable slice of all written samples.
759    pub fn samples_mut(&mut self) -> &mut [S] {
760        &mut self.buf[..self.n_written]
761    }
762
763    /// Gets the maximum number of samples the `SampleBuffer` may store.
764    pub fn capacity(&self) -> usize {
765        self.buf.len()
766    }
767
768    /// Clears all written samples.
769    pub fn clear(&mut self) {
770        self.n_written = 0;
771    }
772
773    /// Copies all audio data from the source `AudioBufferRef` in planar channel order into the
774    /// `SampleBuffer`. The two buffers must be equivalent.
775    pub fn copy_planar_ref(&mut self, src: AudioBufferRef)
776    where
777        S: ConvertibleSample,
778    {
779        match src {
780            AudioBufferRef::U8(buf) => self.copy_planar_typed(&buf),
781            AudioBufferRef::U16(buf) => self.copy_planar_typed(&buf),
782            AudioBufferRef::U24(buf) => self.copy_planar_typed(&buf),
783            AudioBufferRef::U32(buf) => self.copy_planar_typed(&buf),
784            AudioBufferRef::S8(buf) => self.copy_planar_typed(&buf),
785            AudioBufferRef::S16(buf) => self.copy_planar_typed(&buf),
786            AudioBufferRef::S24(buf) => self.copy_planar_typed(&buf),
787            AudioBufferRef::S32(buf) => self.copy_planar_typed(&buf),
788            AudioBufferRef::F32(buf) => self.copy_planar_typed(&buf),
789            AudioBufferRef::F64(buf) => self.copy_planar_typed(&buf),
790        }
791    }
792
793    /// Copies all audio data from a source `AudioBuffer` into the `SampleBuffer` in planar
794    /// channel order. The two buffers must be equivalent.
795    pub fn copy_planar_typed<F>(&mut self, src: &AudioBuffer<F>)
796    where
797        F: Sample + IntoSample<S>,
798    {
799        let n_frames = src.frames();
800        let n_channels = src.spec.channels.count();
801        let n_samples = n_frames * n_channels;
802
803        // Ensure that the capacity of the sample buffer is greater than or equal to the number
804        // of samples that will be copied from the source buffer.
805        assert!(self.capacity() >= n_samples);
806
807        for ch in 0..n_channels {
808            let ch_slice = src.chan(ch);
809
810            for (dst, src) in self.buf[ch * n_frames..].iter_mut().zip(ch_slice) {
811                *dst = (*src).into_sample();
812            }
813        }
814
815        // Commit the written samples.
816        self.n_written = n_samples;
817    }
818
819    /// Copies all audio data from the source `AudioBufferRef` in interleaved channel order into the
820    /// `SampleBuffer`. The two buffers must be equivalent.
821    pub fn copy_interleaved_ref(&mut self, src: AudioBufferRef)
822    where
823        S: ConvertibleSample,
824    {
825        match src {
826            AudioBufferRef::U8(buf) => self.copy_interleaved_typed(&buf),
827            AudioBufferRef::U16(buf) => self.copy_interleaved_typed(&buf),
828            AudioBufferRef::U24(buf) => self.copy_interleaved_typed(&buf),
829            AudioBufferRef::U32(buf) => self.copy_interleaved_typed(&buf),
830            AudioBufferRef::S8(buf) => self.copy_interleaved_typed(&buf),
831            AudioBufferRef::S16(buf) => self.copy_interleaved_typed(&buf),
832            AudioBufferRef::S24(buf) => self.copy_interleaved_typed(&buf),
833            AudioBufferRef::S32(buf) => self.copy_interleaved_typed(&buf),
834            AudioBufferRef::F32(buf) => self.copy_interleaved_typed(&buf),
835            AudioBufferRef::F64(buf) => self.copy_interleaved_typed(&buf),
836        }
837    }
838
839    /// Copies all audio samples from a source `AudioBuffer` into the `SampleBuffer` in interleaved
840    /// channel order. The two buffers must be equivalent.
841    pub fn copy_interleaved_typed<F>(&mut self, src: &AudioBuffer<F>)
842    where
843        F: Sample + IntoSample<S>,
844    {
845        let n_channels = src.spec.channels.count();
846        let n_samples = src.frames() * n_channels;
847
848        // Ensure that the capacity of the sample buffer is greater than or equal to the number
849        // of samples that will be copied from the source buffer.
850        assert!(self.capacity() >= n_samples);
851
852        // Interleave the source buffer channels into the sample buffer.
853        for ch in 0..n_channels {
854            let ch_slice = src.chan(ch);
855
856            for (dst, src) in self.buf[ch..].iter_mut().step_by(n_channels).zip(ch_slice) {
857                *dst = (*src).into_sample();
858            }
859        }
860
861        // Commit the written samples.
862        self.n_written = n_samples;
863    }
864}
865
866/// This non-public module contains the trait `Sealed` which is used to constrain
867/// `RawSample::RawType` with `bytemuck::Pod`. This is a trade-off to hide `bytemuck` from the public
868/// interface. The downside is that `RawSample::RawType` is locked to the types we implement
869/// `Sealed` on. To compensate, we implement `Sealed` on all primitive numeric data types, and byte
870/// arrays up to 8 bytes long.
871mod sealed {
872    pub trait Sealed: bytemuck::Pod {}
873}
874
875impl sealed::Sealed for u8 {}
876impl sealed::Sealed for i8 {}
877impl sealed::Sealed for u16 {}
878impl sealed::Sealed for i16 {}
879impl sealed::Sealed for u32 {}
880impl sealed::Sealed for i32 {}
881impl sealed::Sealed for u64 {}
882impl sealed::Sealed for i64 {}
883impl sealed::Sealed for f32 {}
884impl sealed::Sealed for f64 {}
885impl sealed::Sealed for [u8; 1] {}
886impl sealed::Sealed for [u8; 2] {}
887impl sealed::Sealed for [u8; 3] {}
888impl sealed::Sealed for [u8; 4] {}
889impl sealed::Sealed for [u8; 5] {}
890impl sealed::Sealed for [u8; 6] {}
891impl sealed::Sealed for [u8; 7] {}
892impl sealed::Sealed for [u8; 8] {}
893
894/// `RawSample` provides a typed interface for converting a `Sample` from it's in-memory data type
895/// to actual binary type.
896pub trait RawSample: Sample {
897    /// The `RawType` is a primitive data type, or fixed-size byte array, that is the final binary
898    /// representation of the sample when written out to a byte-buffer.
899    type RawType: Copy + Default + sealed::Sealed;
900
901    fn into_raw_sample(self) -> Self::RawType;
902}
903
904impl RawSample for u8 {
905    type RawType = u8;
906
907    #[inline(always)]
908    fn into_raw_sample(self) -> Self::RawType {
909        self
910    }
911}
912
913impl RawSample for i8 {
914    type RawType = i8;
915
916    #[inline(always)]
917    fn into_raw_sample(self) -> Self::RawType {
918        self
919    }
920}
921
922impl RawSample for u16 {
923    type RawType = u16;
924
925    #[inline(always)]
926    fn into_raw_sample(self) -> Self::RawType {
927        self
928    }
929}
930
931impl RawSample for i16 {
932    type RawType = i16;
933
934    #[inline(always)]
935    fn into_raw_sample(self) -> Self::RawType {
936        self
937    }
938}
939
940impl RawSample for u24 {
941    type RawType = [u8; 3];
942
943    #[inline(always)]
944    fn into_raw_sample(self) -> Self::RawType {
945        self.to_ne_bytes()
946    }
947}
948
949impl RawSample for i24 {
950    type RawType = [u8; 3];
951
952    #[inline(always)]
953    fn into_raw_sample(self) -> Self::RawType {
954        self.to_ne_bytes()
955    }
956}
957
958impl RawSample for u32 {
959    type RawType = u32;
960
961    #[inline(always)]
962    fn into_raw_sample(self) -> Self::RawType {
963        self
964    }
965}
966
967impl RawSample for i32 {
968    type RawType = i32;
969
970    #[inline(always)]
971    fn into_raw_sample(self) -> Self::RawType {
972        self
973    }
974}
975
976impl RawSample for f32 {
977    type RawType = f32;
978
979    #[inline(always)]
980    fn into_raw_sample(self) -> Self::RawType {
981        self
982    }
983}
984
985impl RawSample for f64 {
986    type RawType = f64;
987
988    #[inline(always)]
989    fn into_raw_sample(self) -> Self::RawType {
990        self
991    }
992}
993
994/// A `RawSampleBuffer`, is a byte-oriented sample buffer. All samples copied to this buffer are
995/// converted into their packed data-type and stored as a stream of bytes. `RawSampleBuffer` is
996/// mean't for safely importing and exporting sample data to and from Symphonia as raw bytes.
997pub struct RawSampleBuffer<S: Sample + RawSample> {
998    buf: Box<[S::RawType]>,
999    n_written: usize,
1000    // Might take your heart.
1001    sample_format: PhantomData<S>,
1002}
1003
1004impl<S: Sample + RawSample> RawSampleBuffer<S> {
1005    /// Instantiate a new `RawSampleBuffer` using the specified signal specification and of the given
1006    /// duration.
1007    pub fn new(duration: Duration, spec: SignalSpec) -> RawSampleBuffer<S> {
1008        // The number of channels * duration cannot exceed u64::MAX.
1009        assert!(duration <= u64::MAX / spec.channels.count() as u64, "duration too large");
1010
1011        // The total number of samples the buffer will store.
1012        let n_samples = duration * spec.channels.count() as u64;
1013
1014        // Practically speaking, it is not possible to allocate more than usize::MAX bytes of raw
1015        // samples. This assertion ensures the potential downcast of n_samples to usize below is
1016        // safe.
1017        assert!(
1018            n_samples <= (usize::MAX / mem::size_of::<S::RawType>()) as u64,
1019            "duration too large"
1020        );
1021
1022        // Allocate enough memory for all the samples and fill the buffer with silence.
1023        let buf = vec![S::MID.into_raw_sample(); n_samples as usize].into_boxed_slice();
1024
1025        RawSampleBuffer { buf, n_written: 0, sample_format: PhantomData }
1026    }
1027
1028    /// Gets the number of written samples.
1029    pub fn len(&self) -> usize {
1030        self.n_written
1031    }
1032
1033    /// Returns `true` if the buffer contains no written samples.
1034    pub fn is_empty(&self) -> bool {
1035        self.n_written == 0
1036    }
1037
1038    /// Gets the maximum number of samples the `RawSampleBuffer` may store.
1039    pub fn capacity(&self) -> usize {
1040        self.buf.len()
1041    }
1042
1043    /// Clears all written samples.
1044    pub fn clear(&mut self) {
1045        self.n_written = 0;
1046    }
1047
1048    /// Gets an immutable slice to the bytes of the sample's written in the `RawSampleBuffer`.
1049    pub fn as_bytes(&self) -> &[u8] {
1050        // Get a slice to the written raw samples in the buffer, and convert from &[RawType] to
1051        // &[u8]. Since &[u8] has the least strict alignment requirements, this should always be
1052        // safe and therefore cast_slice should never panic.
1053        bytemuck::cast_slice(&self.buf[..self.n_written])
1054    }
1055
1056    /// Copies all audio data from the source `AudioBufferRef` in planar channel order into the
1057    /// `RawSampleBuffer`. The two buffers must be equivalent.
1058    pub fn copy_planar_ref(&mut self, src: AudioBufferRef)
1059    where
1060        S: ConvertibleSample,
1061    {
1062        match src {
1063            AudioBufferRef::U8(buf) => self.copy_planar_typed(&buf),
1064            AudioBufferRef::U16(buf) => self.copy_planar_typed(&buf),
1065            AudioBufferRef::U24(buf) => self.copy_planar_typed(&buf),
1066            AudioBufferRef::U32(buf) => self.copy_planar_typed(&buf),
1067            AudioBufferRef::S8(buf) => self.copy_planar_typed(&buf),
1068            AudioBufferRef::S16(buf) => self.copy_planar_typed(&buf),
1069            AudioBufferRef::S24(buf) => self.copy_planar_typed(&buf),
1070            AudioBufferRef::S32(buf) => self.copy_planar_typed(&buf),
1071            AudioBufferRef::F32(buf) => self.copy_planar_typed(&buf),
1072            AudioBufferRef::F64(buf) => self.copy_planar_typed(&buf),
1073        }
1074    }
1075
1076    /// Copies all audio data from a source `AudioBuffer` that is of a different sample format type
1077    /// than that of the `RawSampleBuffer` in planar channel order. The two buffers must be
1078    /// equivalent.
1079    pub fn copy_planar_typed<F>(&mut self, src: &AudioBuffer<F>)
1080    where
1081        F: Sample + IntoSample<S>,
1082    {
1083        let n_channels = src.spec.channels.count();
1084        let n_samples = n_channels * src.n_frames;
1085
1086        // Ensure that the capacity of the sample buffer is greater than or equal to the number
1087        // of samples that will be copied from the source buffer.
1088        assert!(self.capacity() >= n_samples);
1089
1090        let dst_buf = &mut self.buf[..n_samples];
1091
1092        for (ch, dst_ch) in dst_buf.chunks_exact_mut(src.n_frames).enumerate() {
1093            let src_ch = src.chan(ch);
1094
1095            for (&s, d) in src_ch.iter().zip(dst_ch) {
1096                *d = s.into_sample().into_raw_sample();
1097            }
1098        }
1099
1100        self.n_written = n_samples;
1101    }
1102
1103    /// Copies all audio data from the source `AudioBuffer` to the `RawSampleBuffer` in planar order.
1104    /// The two buffers must be equivalent.
1105    pub fn copy_planar(&mut self, src: &AudioBuffer<S>) {
1106        let n_channels = src.spec.channels.count();
1107        let n_samples = src.n_frames * n_channels;
1108
1109        // Ensure that the capacity of the sample buffer is greater than or equal to the number
1110        // of samples that will be copied from the source buffer.
1111        assert!(self.capacity() >= n_samples);
1112
1113        let dst_buf = &mut self.buf[..n_samples];
1114
1115        for (ch, dst_ch) in dst_buf.chunks_exact_mut(src.n_frames).enumerate() {
1116            let src_ch = src.chan(ch);
1117
1118            for (&s, d) in src_ch.iter().zip(dst_ch) {
1119                *d = s.into_raw_sample();
1120            }
1121        }
1122
1123        self.n_written = n_samples;
1124    }
1125
1126    /// Copies all audio data from the source `AudioBufferRef` in interleaved channel order into the
1127    /// `RawSampleBuffer`. The two buffers must be equivalent.
1128    pub fn copy_interleaved_ref(&mut self, src: AudioBufferRef)
1129    where
1130        S: ConvertibleSample,
1131    {
1132        match src {
1133            AudioBufferRef::U8(buf) => self.copy_interleaved_typed(&buf),
1134            AudioBufferRef::U16(buf) => self.copy_interleaved_typed(&buf),
1135            AudioBufferRef::U24(buf) => self.copy_interleaved_typed(&buf),
1136            AudioBufferRef::U32(buf) => self.copy_interleaved_typed(&buf),
1137            AudioBufferRef::S8(buf) => self.copy_interleaved_typed(&buf),
1138            AudioBufferRef::S16(buf) => self.copy_interleaved_typed(&buf),
1139            AudioBufferRef::S24(buf) => self.copy_interleaved_typed(&buf),
1140            AudioBufferRef::S32(buf) => self.copy_interleaved_typed(&buf),
1141            AudioBufferRef::F32(buf) => self.copy_interleaved_typed(&buf),
1142            AudioBufferRef::F64(buf) => self.copy_interleaved_typed(&buf),
1143        }
1144    }
1145
1146    /// Copies all audio data from a source `AudioBuffer` that is of a different sample format type
1147    /// than that of the `RawSampleBuffer` in interleaved channel order. The two buffers must be
1148    /// equivalent.
1149    pub fn copy_interleaved_typed<F>(&mut self, src: &AudioBuffer<F>)
1150    where
1151        F: Sample + IntoSample<S>,
1152    {
1153        let n_frames = src.n_frames;
1154        let n_channels = src.spec.channels.count();
1155        let n_samples = n_frames * n_channels;
1156
1157        // Ensure that the capacity of the sample buffer is greater than or equal to the number
1158        // of samples that will be copied from the source buffer.
1159        assert!(self.capacity() >= n_samples);
1160
1161        // The destination buffer slice.
1162        let dst_buf = &mut self.buf[..n_samples];
1163
1164        // Provide slightly optimized interleave algorithms for Mono and Stereo buffers.
1165        match n_channels {
1166            // No channels, do nothing.
1167            0 => (),
1168            // Mono
1169            1 => {
1170                for (&s, d) in src.chan(0).iter().zip(dst_buf) {
1171                    *d = s.into_sample().into_raw_sample();
1172                }
1173            }
1174            // Stereo
1175            2 => {
1176                let l_buf = src.chan(0);
1177                let r_buf = src.chan(1);
1178
1179                for ((&l, &r), d) in l_buf.iter().zip(r_buf).zip(dst_buf.chunks_exact_mut(2)) {
1180                    d[0] = l.into_sample().into_raw_sample();
1181                    d[1] = r.into_sample().into_raw_sample();
1182                }
1183            }
1184            // 3+ channels
1185            _ => {
1186                for ch in 0..n_channels {
1187                    let src_ch = src.chan(ch);
1188                    let dst_ch_iter = dst_buf[ch..].iter_mut().step_by(n_channels);
1189
1190                    for (&s, d) in src_ch.iter().zip(dst_ch_iter) {
1191                        *d = s.into_sample().into_raw_sample();
1192                    }
1193                }
1194            }
1195        }
1196
1197        self.n_written = n_samples;
1198    }
1199
1200    /// Copies all audio data from the source `AudioBuffer` to the `RawSampleBuffer` in interleaved
1201    /// channel order. The two buffers must be equivalent.
1202    pub fn copy_interleaved(&mut self, src: &AudioBuffer<S>) {
1203        let n_frames = src.n_frames;
1204        let n_channels = src.spec.channels.count();
1205        let n_samples = n_frames * n_channels;
1206
1207        // Ensure that the capacity of the sample buffer is greater than or equal to the number
1208        // of samples that will be copied from the source buffer.
1209        assert!(self.capacity() >= n_samples);
1210
1211        // The destination buffer slice.
1212        let dst_buf = &mut self.buf[..n_samples];
1213
1214        // Provide slightly optimized interleave algorithms for Mono and Stereo buffers.
1215        match n_channels {
1216            // No channels, do nothing.
1217            0 => (),
1218            // Mono
1219            1 => {
1220                for (&s, d) in src.chan(0).iter().zip(dst_buf) {
1221                    *d = s.into_raw_sample();
1222                }
1223            }
1224            // Stereo
1225            2 => {
1226                let l_buf = src.chan(0);
1227                let r_buf = src.chan(1);
1228
1229                for ((&l, &r), d) in l_buf.iter().zip(r_buf).zip(dst_buf.chunks_exact_mut(2)) {
1230                    d[0] = l.into_raw_sample();
1231                    d[1] = r.into_raw_sample();
1232                }
1233            }
1234            // 3+ channels
1235            _ => {
1236                for ch in 0..n_channels {
1237                    let src_ch = src.chan(ch);
1238                    let dst_ch_iter = dst_buf[ch..].iter_mut().step_by(n_channels);
1239
1240                    for (&s, d) in src_ch.iter().zip(dst_ch_iter) {
1241                        *d = s.into_raw_sample();
1242                    }
1243                }
1244            }
1245        }
1246
1247        self.n_written = n_samples;
1248    }
1249}