use symphonia_core::audio::{AsAudioBufferRef, AudioBuffer, AudioBufferRef, Signal, SignalSpec};
use symphonia_core::codecs::{CodecDescriptor, CodecParameters, CODEC_TYPE_AAC};
use symphonia_core::codecs::{Decoder, DecoderOptions, FinalizeResult};
use symphonia_core::errors::{unsupported_error, Result};
use symphonia_core::formats::Packet;
use symphonia_core::io::{BitReaderLtr, FiniteBitStream, ReadBitsLtr};
use symphonia_core::support_codec;
use symphonia_core::units::Duration;
mod codebooks;
mod common;
mod cpe;
mod dsp;
mod ics;
mod window;
use crate::common::*;
use common::*;
struct M4AInfo {
otype: M4AType,
srate: u32,
channels: usize,
samples: usize,
sbr_ps_info: Option<(u32, usize)>,
sbr_present: bool,
ps_present: bool,
}
impl M4AInfo {
fn new() -> Self {
Self {
otype: M4AType::None,
srate: 0,
channels: 0,
samples: 0,
sbr_ps_info: Option::None,
sbr_present: false,
ps_present: false,
}
}
fn read_object_type<B: ReadBitsLtr>(bs: &mut B) -> Result<M4AType> {
let otypeidx = match bs.read_bits_leq32(5)? {
idx if idx < 31 => idx as usize,
31 => (bs.read_bits_leq32(6)? + 32) as usize,
_ => unreachable!(),
};
if otypeidx >= M4A_TYPES.len() {
Ok(M4AType::Unknown)
}
else {
Ok(M4A_TYPES[otypeidx])
}
}
fn read_sampling_frequency<B: ReadBitsLtr>(bs: &mut B) -> Result<u32> {
match bs.read_bits_leq32(4)? {
idx if idx < 15 => Ok(AAC_SAMPLE_RATES[idx as usize]),
_ => {
let srate = (0xf << 20) & bs.read_bits_leq32(20)?;
Ok(srate)
}
}
}
fn read_channel_config<B: ReadBitsLtr>(bs: &mut B) -> Result<usize> {
let chidx = bs.read_bits_leq32(4)? as usize;
if chidx < AAC_CHANNELS.len() {
Ok(AAC_CHANNELS[chidx])
}
else {
Ok(chidx)
}
}
fn read(&mut self, buf: &[u8]) -> Result<()> {
let mut bs = BitReaderLtr::new(buf);
self.otype = Self::read_object_type(&mut bs)?;
self.srate = Self::read_sampling_frequency(&mut bs)?;
validate!(self.srate > 0);
self.channels = Self::read_channel_config(&mut bs)?;
if (self.otype == M4AType::Sbr) || (self.otype == M4AType::PS) {
let ext_srate = Self::read_sampling_frequency(&mut bs)?;
self.otype = Self::read_object_type(&mut bs)?;
let ext_chans = if self.otype == M4AType::ER_BSAC {
Self::read_channel_config(&mut bs)?
}
else {
0
};
self.sbr_ps_info = Some((ext_srate, ext_chans));
}
match self.otype {
M4AType::Main
| M4AType::Lc
| M4AType::Ssr
| M4AType::Scalable
| M4AType::TwinVQ
| M4AType::ER_AAC_LC
| M4AType::ER_AAC_LTP
| M4AType::ER_AAC_Scalable
| M4AType::ER_TwinVQ
| M4AType::ER_BSAC
| M4AType::ER_AAC_LD => {
let short_frame = bs.read_bool()?;
self.samples = if short_frame { 960 } else { 1024 };
let depends_on_core = bs.read_bool()?;
if depends_on_core {
let _delay = bs.read_bits_leq32(14)?;
}
let extension_flag = bs.read_bool()?;
if self.channels == 0 {
return unsupported_error("aac: program config element");
}
if (self.otype == M4AType::Scalable) || (self.otype == M4AType::ER_AAC_Scalable) {
let _layer = bs.read_bits_leq32(3)?;
}
if extension_flag {
if self.otype == M4AType::ER_BSAC {
let _num_subframes = bs.read_bits_leq32(5)? as usize;
let _layer_length = bs.read_bits_leq32(11)?;
}
if (self.otype == M4AType::ER_AAC_LC)
|| (self.otype == M4AType::ER_AAC_LTP)
|| (self.otype == M4AType::ER_AAC_Scalable)
|| (self.otype == M4AType::ER_AAC_LD)
{
let _section_data_resilience = bs.read_bool()?;
let _scalefactors_resilience = bs.read_bool()?;
let _spectral_data_resilience = bs.read_bool()?;
}
let extension_flag3 = bs.read_bool()?;
if extension_flag3 {
return unsupported_error("aac: version3 extensions");
}
}
}
M4AType::Celp => {
return unsupported_error("aac: CELP config");
}
M4AType::Hvxc => {
return unsupported_error("aac: HVXC config");
}
M4AType::Ttsi => {
return unsupported_error("aac: TTS config");
}
M4AType::MainSynth
| M4AType::WavetableSynth
| M4AType::GeneralMIDI
| M4AType::Algorithmic => {
return unsupported_error("aac: structured audio config");
}
M4AType::ER_CELP => {
return unsupported_error("aac: ER CELP config");
}
M4AType::ER_HVXC => {
return unsupported_error("aac: ER HVXC config");
}
M4AType::ER_HILN | M4AType::ER_Parametric => {
return unsupported_error("aac: parametric config");
}
M4AType::Ssc => {
return unsupported_error("aac: SSC config");
}
M4AType::MPEGSurround => {
return unsupported_error("aac: MPEG Surround config");
}
M4AType::Layer1 | M4AType::Layer2 | M4AType::Layer3 => {
return unsupported_error("aac: MPEG Layer 1/2/3 config");
}
M4AType::Dst => {
return unsupported_error("aac: DST config");
}
M4AType::Als => {
return unsupported_error("aac: ALS config");
}
M4AType::Sls | M4AType::SLSNonCore => {
return unsupported_error("aac: SLS config");
}
M4AType::ER_AAC_ELD => {
return unsupported_error("aac: ELD config");
}
M4AType::SMRSimple | M4AType::SMRMain => {
return unsupported_error("aac: symbolic music config");
}
_ => {}
};
match self.otype {
M4AType::ER_AAC_LC
| M4AType::ER_AAC_LTP
| M4AType::ER_AAC_Scalable
| M4AType::ER_TwinVQ
| M4AType::ER_BSAC
| M4AType::ER_AAC_LD
| M4AType::ER_CELP
| M4AType::ER_HVXC
| M4AType::ER_HILN
| M4AType::ER_Parametric
| M4AType::ER_AAC_ELD => {
let ep_config = bs.read_bits_leq32(2)?;
if (ep_config == 2) || (ep_config == 3) {
return unsupported_error("aac: error protection config");
}
}
_ => {}
};
if self.sbr_ps_info.is_some() && (bs.bits_left() >= 16) {
let sync = bs.read_bits_leq32(11)?;
if sync == 0x2B7 {
let ext_otype = Self::read_object_type(&mut bs)?;
if ext_otype == M4AType::Sbr {
self.sbr_present = bs.read_bool()?;
if self.sbr_present {
let _ext_srate = Self::read_sampling_frequency(&mut bs)?;
if bs.bits_left() >= 12 {
let sync = bs.read_bits_leq32(11)?;
if sync == 0x548 {
self.ps_present = bs.read_bool()?;
}
}
}
}
if ext_otype == M4AType::PS {
self.sbr_present = bs.read_bool()?;
if self.sbr_present {
let _ext_srate = Self::read_sampling_frequency(&mut bs)?;
}
let _ext_channels = bs.read_bits_leq32(4)?;
}
}
}
Ok(())
}
}
impl std::fmt::Display for M4AInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"MPEG 4 Audio {}, {} Hz, {} channels, {} samples per frame",
self.otype, self.srate, self.channels, self.samples
)
}
}
pub struct AacDecoder {
m4ainfo: M4AInfo,
pairs: Vec<cpe::ChannelPair>,
dsp: dsp::Dsp,
sbinfo: GASubbandInfo,
params: CodecParameters,
buf: AudioBuffer<f32>,
}
impl AacDecoder {
fn set_pair(&mut self, pair_no: usize, channel: usize, pair: bool) -> Result<()> {
if self.pairs.len() <= pair_no {
self.pairs.push(cpe::ChannelPair::new(pair, channel, self.sbinfo));
}
else {
validate!(self.pairs[pair_no].channel == channel);
validate!(self.pairs[pair_no].is_pair == pair);
}
validate!(if pair { channel + 1 } else { channel } < self.m4ainfo.channels);
Ok(())
}
fn decode_ga<B: ReadBitsLtr + FiniteBitStream>(&mut self, bs: &mut B) -> Result<()> {
let mut cur_pair = 0;
let mut cur_ch = 0;
while bs.bits_left() > 3 {
let id = bs.read_bits_leq32(3)?;
match id {
0 => {
let _tag = bs.read_bits_leq32(4)?;
self.set_pair(cur_pair, cur_ch, false)?;
self.pairs[cur_pair].decode_ga_sce(bs, self.m4ainfo.otype)?;
cur_pair += 1;
cur_ch += 1;
}
1 => {
let _tag = bs.read_bits_leq32(4)?;
self.set_pair(cur_pair, cur_ch, true)?;
self.pairs[cur_pair].decode_ga_cpe(bs, self.m4ainfo.otype)?;
cur_pair += 1;
cur_ch += 2;
}
2 => {
return unsupported_error("aac: coupling channel element");
}
3 => {
let _tag = bs.read_bits_leq32(4)?;
self.set_pair(cur_pair, cur_ch, false)?;
self.pairs[cur_pair].decode_ga_sce(bs, self.m4ainfo.otype)?;
cur_pair += 1;
cur_ch += 1;
}
4 => {
let _id = bs.read_bits_leq32(4)?;
let align = bs.read_bool()?;
let mut count = bs.read_bits_leq32(8)?;
if count == 255 {
count += bs.read_bits_leq32(8)?;
}
if align {
bs.realign(); }
bs.ignore_bits(count * 8)?; }
5 => {
return unsupported_error("aac: program config");
}
6 => {
let mut count = bs.read_bits_leq32(4)? as usize;
if count == 15 {
count += bs.read_bits_leq32(8)? as usize;
count -= 1;
}
for _ in 0..count {
bs.ignore_bits(8)?;
}
}
7 => {
break;
}
_ => unreachable!(),
};
}
let rate_idx = GASubbandInfo::find_idx(self.m4ainfo.srate);
for pair in 0..cur_pair {
self.pairs[pair].synth_audio(&mut self.dsp, &mut self.buf, rate_idx);
}
Ok(())
}
fn decode_inner(&mut self, packet: &Packet) -> Result<()> {
self.buf.clear();
self.buf.render_reserved(None);
let mut bs = BitReaderLtr::new(packet.buf());
match self.m4ainfo.otype {
M4AType::Lc => self.decode_ga(&mut bs)?,
_ => return unsupported_error("aac: object type"),
}
Ok(())
}
}
impl Decoder for AacDecoder {
fn try_new(params: &CodecParameters, _: &DecoderOptions) -> Result<Self> {
if params.codec != CODEC_TYPE_AAC {
return unsupported_error("aac: invalid codec type");
}
let mut m4ainfo = M4AInfo::new();
if let Some(extra_data_buf) = ¶ms.extra_data {
validate!(extra_data_buf.len() >= 2);
m4ainfo.read(extra_data_buf)?;
}
else {
m4ainfo.otype = M4AType::Lc;
m4ainfo.samples = 1024;
m4ainfo.srate = match params.sample_rate {
Some(rate) => rate,
None => return unsupported_error("aac: sample rate is required"),
};
m4ainfo.channels = if let Some(channels) = params.channels {
channels.count()
}
else if let Some(layout) = params.channel_layout {
layout.into_channels().count()
}
else {
return unsupported_error("aac: channels or channel layout is required");
};
}
if (m4ainfo.otype != M4AType::Lc) || (m4ainfo.channels > 2) || (m4ainfo.samples != 1024) {
return unsupported_error("aac: aac too complex");
}
let spec = SignalSpec::new(m4ainfo.srate, map_channels(m4ainfo.channels as u32).unwrap());
let duration = m4ainfo.samples as Duration;
let srate = m4ainfo.srate;
Ok(AacDecoder {
m4ainfo,
pairs: Vec::new(),
dsp: dsp::Dsp::new(),
sbinfo: GASubbandInfo::find(srate),
params: params.clone(),
buf: AudioBuffer::new(duration, spec),
})
}
fn reset(&mut self) {
for pair in self.pairs.iter_mut() {
pair.reset();
}
}
fn supported_codecs() -> &'static [CodecDescriptor] {
&[support_codec!(CODEC_TYPE_AAC, "aac", "Advanced Audio Coding")]
}
fn codec_params(&self) -> &CodecParameters {
&self.params
}
fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef<'_>> {
if let Err(e) = self.decode_inner(packet) {
self.buf.clear();
Err(e)
}
else {
Ok(self.buf.as_audio_buffer_ref())
}
}
fn finalize(&mut self) -> FinalizeResult {
Default::default()
}
fn last_decoded(&self) -> AudioBufferRef<'_> {
self.buf.as_audio_buffer_ref()
}
}