aede_audio/
format.rs

1//! Shared processing format and original-precision integer source metadata.
2//!
3//! Local and remote playback use one rate/channel type, including when they
4//! pass decoded blocks to processing, meters, or an output sink. The separate
5//! integer source format retains valid precision before any such conversion.
6
7pub use aede_dsp::{DspError as FormatError, PcmFormat as PcmStreamFormat};
8
9/// Original signed integer PCM in the initial exact-decoding profile.
10///
11/// Samples use an `i32` storage container but are canonical, unscaled source
12/// integers: 24-bit `1` remains `1`, not a left-aligned 32-bit value. Valid bit
13/// depth is therefore distinct from the container width. This format carries
14/// no output-device negotiation or bit-perfect device guarantee.
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub struct IntegerPcmFormat {
17    pcm: PcmStreamFormat,
18    bits_per_sample: u32,
19}
20
21impl IntegerPcmFormat {
22    /// Validate the initial 16/24-bit mono/stereo source profile.
23    pub fn new(
24        sample_rate: u32,
25        layout: aede_dsp::ChannelLayout,
26        bits_per_sample: u32,
27    ) -> Result<Self, FormatError> {
28        if !matches!(bits_per_sample, 16 | 24)
29            || !matches!(
30                layout,
31                aede_dsp::ChannelLayout::MONO | aede_dsp::ChannelLayout::STEREO
32            )
33        {
34            return Err(FormatError::InvalidFormat);
35        }
36        Ok(Self {
37            pcm: PcmStreamFormat::with_layout(sample_rate, layout)?,
38            bits_per_sample,
39        })
40    }
41
42    /// Source frames per second, without rate conversion.
43    pub fn sample_rate(self) -> u32 {
44        self.pcm.sample_rate()
45    }
46
47    /// Number of original interleaved samples in a frame.
48    pub fn channels(self) -> u16 {
49        self.pcm.channels()
50    }
51
52    /// Valid source precision, independent of the `i32` storage width.
53    pub fn bits_per_sample(self) -> u32 {
54        self.bits_per_sample
55    }
56
57    /// Original mono or front-left/front-right stereo association.
58    pub fn layout(self) -> aede_dsp::ChannelLayout {
59        self.pcm.layout()
60    }
61}
62
63#[cfg(test)]
64#[path = "format_tests.rs"]
65mod tests;