#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AudioObjectType {
AacMain, AacLc, AacSsr, AacLtp, Sbr, Unknown(u8),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SamplingFrequency {
Hz96000,
Hz88200,
Hz64000,
Hz48000,
Hz44100,
Hz32000,
Hz24000,
Hz22050,
Hz16000,
Hz12000,
Hz11025,
Hz8000,
Hz7350,
Explicit(u32),
}
impl SamplingFrequency {
pub fn as_hz(&self) -> u32 {
match *self {
Self::Hz96000 => 96_000,
Self::Hz88200 => 88_200,
Self::Hz64000 => 64_000,
Self::Hz48000 => 48_000,
Self::Hz44100 => 44_100,
Self::Hz32000 => 32_000,
Self::Hz24000 => 24_000,
Self::Hz22050 => 22_050,
Self::Hz16000 => 16_000,
Self::Hz12000 => 12_000,
Self::Hz11025 => 11_025,
Self::Hz8000 => 8_000,
Self::Hz7350 => 7_350,
Self::Explicit(v) => v,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChannelConfiguration {
Mono,
Stereo,
Three,
Four,
Five,
FiveOne,
SevenOne,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AudioSpecificConfig {
pub audio_object_type: AudioObjectType,
pub sampling_frequency: SamplingFrequency,
pub channel_configuration: ChannelConfiguration,
pub extension_bits: u8,
pub extension_bytes: Vec<u8>,
}
pub(crate) mod serializer {
use crate::atom::util::serializer::{be_u24, bits::Packer};
use super::{AudioObjectType, AudioSpecificConfig, ChannelConfiguration, SamplingFrequency};
pub fn serialize_audio_specific_config(cfg: AudioSpecificConfig) -> Vec<u8> {
let mut packer = Packer::new();
packer.push_n::<5>(audio_object_type(cfg.audio_object_type));
let explicit = match cfg.sampling_frequency {
SamplingFrequency::Explicit(hz) => Some(hz),
_ => None,
};
packer.push_n::<4>(sampling_frequency_index(cfg.sampling_frequency));
if let Some(hz) = explicit {
packer.push_bytes(be_u24(hz).to_vec());
}
packer.push_n::<4>(channel_configuration(cfg.channel_configuration));
packer.push_n::<3>(cfg.extension_bits);
packer.push_bytes(cfg.extension_bytes);
Vec::from(packer)
}
fn audio_object_type(aot: AudioObjectType) -> u8 {
use AudioObjectType::*;
match aot {
AacMain => 1,
AacLc => 2,
AacSsr => 3,
AacLtp => 4,
Sbr => 5,
Unknown(v) => v.min(31),
}
}
fn sampling_frequency_index(sf: SamplingFrequency) -> u8 {
use SamplingFrequency::*;
match sf {
Hz96000 => 0,
Hz88200 => 1,
Hz64000 => 2,
Hz48000 => 3,
Hz44100 => 4,
Hz32000 => 5,
Hz24000 => 6,
Hz22050 => 7,
Hz16000 => 8,
Hz12000 => 9,
Hz11025 => 10,
Hz8000 => 11,
Hz7350 => 12,
Explicit(_) => 15,
}
}
fn channel_configuration(ch: ChannelConfiguration) -> u8 {
use ChannelConfiguration::*;
match ch {
Mono => 1,
Stereo => 2,
Three => 3,
Four => 4,
Five => 5,
FiveOne => 6,
SevenOne => 7,
}
}
}
pub(crate) mod parser {
use winnow::{
binary::{be_u24, bits},
combinator::{alt, backtrack_err, dispatch, empty, fail, seq},
error::{StrContext, StrContextValue},
ModalResult, Parser,
};
use crate::atom::util::parser::{rest_vec, Stream};
use super::{AudioObjectType, AudioSpecificConfig, ChannelConfiguration, SamplingFrequency};
pub fn parse_audio_specific_config(input: &mut Stream<'_>) -> ModalResult<AudioSpecificConfig> {
bits::bits(
move |input: &mut (Stream<'_>, usize)| -> ModalResult<AudioSpecificConfig> {
seq!(AudioSpecificConfig {
audio_object_type: audio_object_type .context(StrContext::Label("audio_object_type")),
sampling_frequency: sampling_frequency .context(StrContext::Label("sampling_frequency")),
channel_configuration: channel_configuration .context(StrContext::Label("channel_configuration")),
extension_bits: bits::take(3usize).context(StrContext::Label("extension_bits")),
extension_bytes: bits::bytes(rest_vec).context(StrContext::Label("extension_bytes")),
})
.parse_next(input)
},
)
.parse_next(input)
}
fn audio_object_type(input: &mut (Stream<'_>, usize)) -> ModalResult<AudioObjectType> {
use AudioObjectType::*;
alt((
dispatch! {bits::take(5usize);
1 => empty.value(AacMain),
2 => empty.value(AacLc),
3 => empty.value(AacSsr),
4 => empty.value(Sbr),
5 => empty.value(Sbr),
_ => backtrack_err(fail),
},
bits::take(5usize)
.verify(|v: &u8| (6..=31).contains(v))
.map(Unknown),
fail.context(StrContext::Expected(StrContextValue::Description(
"0x01..0x1F",
))),
))
.parse_next(input)
}
fn sampling_frequency(input: &mut (Stream<'_>, usize)) -> ModalResult<SamplingFrequency> {
use SamplingFrequency::*;
dispatch! {bits::take(4usize);
0 => empty.value(Hz96000),
1 => empty.value(Hz88200),
2 => empty.value(Hz64000),
3 => empty.value(Hz48000),
4 => empty.value(Hz44100),
5 => empty.value(Hz32000),
6 => empty.value(Hz24000),
7 => empty.value(Hz22050),
8 => empty.value(Hz16000),
9 => empty.value(Hz12000),
10 => empty.value(Hz11025),
11 => empty.value(Hz8000),
12 => empty.value(Hz7350),
15 => bits::bytes(move |input: &mut Stream<'_>| -> ModalResult<u32> {
be_u24.parse_next(input) }).map(Explicit)
.context(StrContext::Label("sampling_frequency"))
.context(StrContext::Expected(StrContextValue::Description(
"explicit frequency (be_u24)",
))),
_ => fail.context(StrContext::Expected(StrContextValue::Description(
"0x00..0x0C, 0x0F",
))),
}
.parse_next(input)
}
fn channel_configuration(input: &mut (Stream<'_>, usize)) -> ModalResult<ChannelConfiguration> {
use ChannelConfiguration::*;
dispatch! {bits::take(4usize);
1 => empty.value(Mono),
2 => empty.value(Stereo),
3 => empty.value(Three),
4 => empty.value(Four),
5 => empty.value(Five),
6 => empty.value(FiveOne),
7 => empty.value(SevenOne),
_ =>
fail.context(StrContext::Expected(StrContextValue::Description(
"0x01..0x07",
))),
}
.parse_next(input)
}
}