use std::{fmt::Display, mem};
#[cfg(all(
target_arch = "wasm32",
any(target_os = "emscripten", feature = "wasm-bindgen")
))]
use wasm_bindgen::prelude::*;
pub use dasp_sample::{FromSample, Sample};
pub use dasp_sample::I24;
pub use dasp_sample::U24;
#[cfg_attr(
all(
target_arch = "wasm32",
any(target_os = "emscripten", feature = "wasm-bindgen")
),
wasm_bindgen
)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum SampleFormat {
I8,
I16,
I24,
I32,
I64,
U8,
U16,
U24,
U32,
U64,
F32,
F64,
DsdU8,
DsdU16,
DsdU32,
}
impl SampleFormat {
#[inline]
#[must_use]
pub fn sample_size(&self) -> usize {
match *self {
SampleFormat::I8 => mem::size_of::<i8>(),
SampleFormat::U8 => mem::size_of::<u8>(),
SampleFormat::I16 => mem::size_of::<i16>(),
SampleFormat::U16 => mem::size_of::<u16>(),
SampleFormat::I24 => mem::size_of::<i32>(),
SampleFormat::U24 => mem::size_of::<i32>(),
SampleFormat::I32 => mem::size_of::<i32>(),
SampleFormat::U32 => mem::size_of::<u32>(),
SampleFormat::I64 => mem::size_of::<i64>(),
SampleFormat::U64 => mem::size_of::<u64>(),
SampleFormat::F32 => mem::size_of::<f32>(),
SampleFormat::F64 => mem::size_of::<f64>(),
SampleFormat::DsdU8 => mem::size_of::<u8>(),
SampleFormat::DsdU16 => mem::size_of::<u16>(),
SampleFormat::DsdU32 => mem::size_of::<u32>(),
}
}
#[inline]
#[must_use]
pub fn bits_per_sample(&self) -> u32 {
match *self {
SampleFormat::I8 => i8::BITS,
SampleFormat::U8 => u8::BITS,
SampleFormat::I16 => i16::BITS,
SampleFormat::U16 => u16::BITS,
SampleFormat::I24 => 24,
SampleFormat::U24 => 24,
SampleFormat::I32 => i32::BITS,
SampleFormat::U32 => u32::BITS,
SampleFormat::I64 => i64::BITS,
SampleFormat::U64 => u64::BITS,
SampleFormat::F32 => 32,
SampleFormat::F64 => 64,
SampleFormat::DsdU8 | SampleFormat::DsdU16 | SampleFormat::DsdU32 => 1,
}
}
#[inline]
#[must_use]
pub fn is_int(&self) -> bool {
matches!(
*self,
SampleFormat::I8
| SampleFormat::I16
| SampleFormat::I24
| SampleFormat::I32
| SampleFormat::I64
)
}
#[inline]
#[must_use]
pub fn is_uint(&self) -> bool {
matches!(
*self,
SampleFormat::U8
| SampleFormat::U16
| SampleFormat::U24
| SampleFormat::U32
| SampleFormat::U64
)
}
#[inline]
#[must_use]
pub fn is_float(&self) -> bool {
matches!(*self, SampleFormat::F32 | SampleFormat::F64)
}
#[inline]
#[must_use]
pub fn is_dsd(&self) -> bool {
matches!(
*self,
SampleFormat::DsdU8 | SampleFormat::DsdU16 | SampleFormat::DsdU32
)
}
}
impl Display for SampleFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {
SampleFormat::I8 => "i8",
SampleFormat::I16 => "i16",
SampleFormat::I24 => "i24",
SampleFormat::I32 => "i32",
SampleFormat::I64 => "i64",
SampleFormat::U8 => "u8",
SampleFormat::U16 => "u16",
SampleFormat::U24 => "u24",
SampleFormat::U32 => "u32",
SampleFormat::U64 => "u64",
SampleFormat::F32 => "f32",
SampleFormat::F64 => "f64",
SampleFormat::DsdU8 => "dsdu8",
SampleFormat::DsdU16 => "dsdu16",
SampleFormat::DsdU32 => "dsdu32",
}
.fmt(f)
}
}
pub trait SizedSample: Sample {
const FORMAT: SampleFormat;
}
impl SizedSample for i8 {
const FORMAT: SampleFormat = SampleFormat::I8;
}
impl SizedSample for i16 {
const FORMAT: SampleFormat = SampleFormat::I16;
}
impl SizedSample for I24 {
const FORMAT: SampleFormat = SampleFormat::I24;
}
impl SizedSample for i32 {
const FORMAT: SampleFormat = SampleFormat::I32;
}
impl SizedSample for i64 {
const FORMAT: SampleFormat = SampleFormat::I64;
}
impl SizedSample for u8 {
const FORMAT: SampleFormat = SampleFormat::U8;
}
impl SizedSample for u16 {
const FORMAT: SampleFormat = SampleFormat::U16;
}
impl SizedSample for U24 {
const FORMAT: SampleFormat = SampleFormat::U24;
}
impl SizedSample for u32 {
const FORMAT: SampleFormat = SampleFormat::U32;
}
impl SizedSample for u64 {
const FORMAT: SampleFormat = SampleFormat::U64;
}
impl SizedSample for f32 {
const FORMAT: SampleFormat = SampleFormat::F32;
}
impl SizedSample for f64 {
const FORMAT: SampleFormat = SampleFormat::F64;
}