first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# `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`](./wasm-base.md) 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
```ts
import { AacCodec } from "@suaveplan/audio-codecs/codecs/aac";
const decoded = await AacCodec.decode(aacBytes);
```
## Usage: Advanced Example
```ts
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`.