Skip to main content

Overview

Symphonia provides a pure Rust implementation of an Advanced Audio Coding (AAC) decoder. AAC is a lossy audio compression format that offers improved sound quality over MP3 at similar bitrates.

Feature Flag

To enable AAC support, add the aac feature to your Cargo.toml:
[dependencies]
symphonia = { version = "0.5", features = ["aac"] }
Or use the standalone crate:
[dependencies]
symphonia-codec-aac = "0.5"

Status

Status: Good
  • Decoding: Supported
  • Gapless Playback: Yes
  • Container Support: ISO MP4, ADTS streams

Codec Type

use symphonia::core::codecs::CODEC_TYPE_AAC;

Decoder

The AAC decoder is implemented by the AacDecoder struct:
use symphonia_codec_aac::AacDecoder;
use symphonia::core::codecs::{Decoder, DecoderOptions};
use symphonia::core::formats::Packet;

// Create decoder from codec parameters
let mut decoder = AacDecoder::try_new(&codec_params, &DecoderOptions::default())?;

// Decode a packet
let decoded = decoder.decode(&packet)?;

ADTS Stream Reader

For raw ADTS (Audio Data Transport Stream) files, use the AdtsReader:
use symphonia_codec_aac::AdtsReader;
use symphonia::core::formats::{FormatReader, FormatOptions};
use symphonia::core::io::MediaSourceStream;

let mss = MediaSourceStream::new(source, Default::default());
let mut reader = AdtsReader::try_new(mss, &FormatOptions::default())?;

// Read packets
while let Ok(packet) = reader.next_packet() {
    // Decode packet...
}

Supported Profiles

  • AAC Low Complexity (AAC-LC)
  • High Efficiency AAC (HE-AAC, AAC+)
  • HE-AAC v2 (AAC+ v2)

Sample Rates

Supports all standard AAC sample rates from 8 kHz to 96 kHz.

Channel Configurations

  • Mono (1.0)
  • Stereo (2.0)
  • 3.0 (L, R, C)
  • 4.0 (L, R, Ls, Rs)
  • 5.0 (L, R, C, Ls, Rs)
  • 5.1 (L, R, C, LFE, Ls, Rs)
  • 7.1 (L, R, C, LFE, Lb, Rb, Ls, Rs)

Usage Example

use symphonia::core::codecs::{CODEC_TYPE_AAC, DecoderOptions};
use symphonia::core::formats::FormatOptions;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;
use std::fs::File;

fn decode_aac_file(path: &str) -> Result<(), Box<dyn std::error::Error>> {
    // Open the media source
    let file = Box::new(File::open(path)?);
    let mss = MediaSourceStream::new(file, Default::default());

    // Create a hint to help the format registry
    let mut hint = Hint::new();
    hint.with_extension("m4a");

    // Probe the media source
    let probed = symphonia::default::get_probe()
        .format(&hint, mss, &FormatOptions::default(), &MetadataOptions::default())?;

    let mut format = probed.format;

    // Find the AAC track
    let track = format.tracks()
        .iter()
        .find(|t| t.codec_params.codec == CODEC_TYPE_AAC)
        .ok_or("No AAC track found")?;

    // Create the decoder
    let mut decoder = symphonia::default::get_codecs()
        .make(&track.codec_params, &DecoderOptions::default())?;

    // Decode packets
    loop {
        let packet = match format.next_packet() {
            Ok(packet) => packet,
            Err(_) => break,
        };

        if packet.track_id() != track.id {
            continue;
        }

        let decoded = decoder.decode(&packet)?;
        // Process decoded audio...
    }

    Ok(())
}

Limitations

  • Does not support:
    • Scalable Sampling Rate (SSR)
    • Long Term Prediction (LTP)
    • Main profile
    • Some advanced AAC features
  • Error concealment is basic
  • May not handle all malformed streams gracefully

Performance

  • Pure Rust implementation with no unsafe code
  • Optimized for typical AAC-LC streams
  • Memory efficient with minimal allocations

Documentation

See Also

Build docs developers (and LLMs) love