#[cfg(feature = "alsa")]
use crate::_alsa_raw;
use crate::{_impl_init, impl_trait};
#[doc = crate::_tags!(audio)]
#[doc = crate::_doc_meta!{
location("media/audio"),
test_size_of(PcmSample = 1|8),
}]
#[allow(missing_docs)]
#[must_use]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PcmSample {
I8,
U8,
#[default]
I16,
I24,
I32,
F32,
F64,
}
_impl_init![Self::I16 => PcmSample];
impl_trait![fmt::Display for PcmSample |self, f| f.write_str(self.as_code())];
impl PcmSample {
#[must_use]
pub const fn bits(self) -> u8 {
match self {
Self::I8 => 8,
Self::U8 => 8,
Self::I16 => 16,
Self::I24 => 24,
Self::I32 | Self::F32 => 32,
Self::F64 => 64,
}
}
#[must_use]
pub const fn bytes(self) -> usize {
match self {
Self::I8 => 1,
Self::U8 => 1,
Self::I16 => 2,
Self::I24 => 3,
Self::I32 | Self::F32 => 4,
Self::F64 => 8,
}
}
#[must_use]
pub const fn eq(self, other: Self) -> bool {
self as u8 == other as u8
}
#[must_use]
pub const fn is_int(self) -> bool {
matches!(self, Self::I8 | Self::U8 | Self::I16 | Self::I24 | Self::I32)
}
#[must_use]
pub const fn is_signed_int(self) -> bool {
matches!(self, Self::I8 | Self::I16 | Self::I24 | Self::I32)
}
#[must_use]
pub const fn is_unsigned_int(self) -> bool {
matches!(self, Self::U8)
}
#[must_use]
pub const fn is_float(self) -> bool {
matches!(self, Self::F32 | Self::F64)
}
#[must_use]
pub const fn has_negative(self) -> bool {
matches!(self, Self::I8 | Self::I16 | Self::I24 | Self::I32 | Self::F32 | Self::F64)
}
#[must_use]
pub const fn as_code(self) -> &'static str {
match self {
Self::I8 => "i8",
Self::U8 => "u8",
Self::I16 => "i16",
Self::I24 => "i24",
Self::I32 => "i32",
Self::F32 => "f32",
Self::F64 => "f64",
}
}
#[cfg(feature = "alsa")]
#[cfg_attr(not(ffi_alsa··), allow(dead_code))]
pub(crate) const fn to_alsa(self) -> _alsa_raw::snd_pcm_format_t {
match self {
Self::I8 => _alsa_raw::SND_PCM_FORMAT_S8,
Self::U8 => _alsa_raw::SND_PCM_FORMAT_U8,
Self::I16 => _alsa_raw::SND_PCM_FORMAT_S16_LE,
Self::I24 => _alsa_raw::SND_PCM_FORMAT_S24_3LE,
Self::I32 => _alsa_raw::SND_PCM_FORMAT_S32_LE,
Self::F32 => _alsa_raw::SND_PCM_FORMAT_FLOAT_LE,
Self::F64 => _alsa_raw::SND_PCM_FORMAT_FLOAT64_LE,
}
}
}
#[doc = crate::_tags!(audio)]
#[doc = crate::_doc_meta!{location("media/audio")}]
#[expect(private_bounds, reason = "Sealed")]
pub trait PcmSampleType: Copy + Sealed {
const SAMPLE: PcmSample;
const SILENCE: Self;
}
trait Sealed {}
macro_rules! _pcm_sample_type {
() => {
_pcm_sample_type!(u8,U8,128; i8,I8,0; i16,I16,0; i32,I32,0; f32,F32,0.0; f64,F64,0.0);
};
($($T:ty, $sample:ident, $SI:literal);+ $(;)?) => {
$( _pcm_sample_type!(% $T, $sample, $SI);)+
};
(% $T:ty, $sample:ident, $SI:literal) => {
impl Sealed for $T {}
impl PcmSampleType for $T {
const SAMPLE: PcmSample = PcmSample::$sample;
const SILENCE: Self = $SI;
}
};
}
_pcm_sample_type!();