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;