Files
skills/docs/media/audio/audio-codecs/src/codecs/aac.md
2026-05-29 08:20:56 +01:00

2.5 KiB

codecs/aac

Lazy AAC codec — decode-only wrapper over @audio/decode-aac WASM module loaded on first use.

Purpose

AAC (Advanced Audio Coding) is the modern lossy audio successor to MP3, used by every major streaming service and as the default audio format in MP4/M4A containers. The codec is decode-only because (a) the AAC encoder is complex and patent-encumbered in many jurisdictions, and (b) the canonical lossy encode target is Opus.

Implementation delegates to createWasmCodec for the lazy-load, error-wrapping, and missing-module behaviour shared by every WASM wrapper.

Features

  • name === "aac", extensions ["aac", "m4a"], MIME types ["audio/aac", "audio/mp4"].
  • canDecode(bytes) — magic-byte sniff for the ADTS sync word (first byte 0xff, second byte top 4 bits 0b1111); rejects buffers shorter than 2 bytes.
  • Decode supported via @audio/decode-aac.
  • supportsEncode: false — encode throws NOT_SUPPORTED short-circuit.
  • Streaming factory absent.

Usage: Basic Example

import { AacCodec } from "@suaveplan/audio-codecs/codecs/aac";

const decoded = await AacCodec.decode(aacBytes);

Usage: Advanced Example

import { CodecRegistry, AacCodec, OpusCodec } from "@suaveplan/audio-codecs";

const registry = new CodecRegistry({ codecs: [AacCodec, OpusCodec] });

// transcode AAC → Opus for downstream storage
const aacDoc = await registry.decode(aacBytes);
const opusBytes = await registry.encode(aacDoc, "opus");

API Reference

  • AacCodec: AudioCodec — frozen constant; decode-only.
  • canDecode(bytes), decode(bytes, opts?) — standard AudioCodec contract.
  • encode() — always throws AUDIO_CODECS.NOT_SUPPORTED.

Implementation Notes

  • The ADTS sync word check (0xff 0xf0) covers raw ADTS-framed AAC. AAC inside an MP4/M4A container starts with ftyp instead; that case is currently NOT handled by canDecode — callers passing M4A files need to either use a separate MP4 demuxer first or call decode with format: "aac" to bypass detection. A future extension may add an MP4-container sniffer.
  • Decode-only by design. suaveplan's preferred lossy encode target is Opus; AAC encoding requires non-trivial licensing in some jurisdictions and is intentionally out of scope.
  • First decode lazily loads @audio/decode-aac; subsequent calls reuse the memoised module.
  • Missing @audio/decode-aac → AUDIO_CODECS.NOT_SUPPORTED.
  • Streaming factory absent — CodecRegistry.decodeStream("aac", …) throws AUDIO_CODECS.STREAM_ERROR.