use std::{
iter,
num::{NonZeroU32, NonZeroU8},
};
use crate::{
media_frame::{MemoryPlanes, PlaneInformation},
time,
};
pub const SAMPLE_RATE_TELEPHONE: u32 = 8000;
pub const SAMPLE_RATE_VOIP: u32 = 16000;
pub const SAMPLE_RATE_CD: u32 = 44100;
pub const SAMPLE_RATE_DVD: u32 = 48000;
pub const SAMPLE_RATE_HIGH: u32 = 96000;
pub const SAMPLE_RATE_ULTRA_HIGH: u32 = 192000;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AudioFormat {
U8 = 0, S16, S32, F32, F64, U8P, S16P, S32P, F32P, F64P, MAX,
}
#[derive(Clone, Debug, PartialEq)]
pub struct AudioFrameDescription {
pub format: AudioFormat,
pub channels: NonZeroU8,
pub samples: NonZeroU32,
pub sample_rate: NonZeroU32,
}
impl AudioFrameDescription {
pub fn new(format: AudioFormat, channels: NonZeroU8, samples: NonZeroU32, sample_rate: NonZeroU32) -> Self {
Self {
format,
channels,
samples,
sample_rate,
}
}
pub fn duration_equal(&self, other: &AudioFrameDescription) -> bool {
let duration1 = self.samples.get() as u64 * time::MSEC_PER_SEC / self.sample_rate.get() as u64;
let duration2 = other.samples.get() as u64 * time::MSEC_PER_SEC / other.sample_rate.get() as u64;
duration1 == duration2
}
}
struct AudioFormatInfo {
pub bits: u8,
pub is_planar: bool,
}
static AUDIO_FORMAT_INFO: [AudioFormatInfo; AudioFormat::MAX as usize] = [
AudioFormatInfo {
bits: 8,
is_planar: false,
},
AudioFormatInfo {
bits: 16,
is_planar: false,
},
AudioFormatInfo {
bits: 32,
is_planar: false,
},
AudioFormatInfo {
bits: 32,
is_planar: false,
},
AudioFormatInfo {
bits: 64,
is_planar: false,
},
AudioFormatInfo {
bits: 8,
is_planar: true,
},
AudioFormatInfo {
bits: 16,
is_planar: true,
},
AudioFormatInfo {
bits: 32,
is_planar: true,
},
AudioFormatInfo {
bits: 32,
is_planar: true,
},
AudioFormatInfo {
bits: 64,
is_planar: true,
},
];
impl AudioFormat {
pub fn bits(&self) -> u8 {
AUDIO_FORMAT_INFO[*self as usize].bits
}
pub fn bytes(&self) -> u8 {
self.bits() >> 3
}
pub fn is_planar(&self) -> bool {
AUDIO_FORMAT_INFO[*self as usize].is_planar
}
pub fn stride(&self, channels: u8, samples: u32) -> u32 {
if self.is_planar() {
self.bytes() as u32 * samples
} else {
self.bytes() as u32 * channels as u32 * samples
}
}
pub(super) fn data_calc(&self, channels: u8, samples: u32) -> (u32, MemoryPlanes) {
let mut size = 0;
let mut planes = MemoryPlanes::new();
let stride = self.stride(channels, samples);
if self.is_planar() {
planes.extend(iter::repeat(PlaneInformation::Audio(stride)).take(channels as usize));
size += stride * channels as u32;
} else {
planes.push(PlaneInformation::Audio(stride));
size = stride;
}
(size, planes)
}
}