# @suaveplan/audio-codecs - Universal audio codec registry: decode/encode plugin loader with format detection, progressive streaming decode, native WAV/AIFF/CAF codecs, and lazy-loaded WASM codecs for MP3/FLAC/Ogg/Opus/AAC/WebM/QOA. Universal with runtime-gated node:fs access. Universal audio codec registry: decode/encode plugin loader with magic-byte format detection, progressive streaming decode, native WAV/AIFF/CAF codecs, and lazy-loaded WASM codecs for MP3/FLAC/Ogg/Opus/AAC/WebM/QOA. Universal — no browser-only or Node-only APIs at module scope; `node:fs/promises` is reached only via runtime-gated dynamic `import()`. ## Documentation tree - [aac](./src/codecs/aac.md) — Lazy AAC codec — decode-only wrapper over `@audio/decode-aac` WASM module loaded on first use. - [aiff](./src/codecs/aiff.md) — Native pure-JS AIFF (Audio Interchange File Format) decoder, decode-only. - [caf](./src/codecs/caf.md) — Native pure-JS CAF (Apple Core Audio Format) decoder, decode-only. - [flac](./src/codecs/flac.md) — Lazy FLAC codec — thin wrapper over `@audio/decode-flac` WASM module loaded on first use. - [mp3](./src/codecs/mp3.md) — Lazy MP3 codec — thin wrapper that defers decode/encode to the `@audio/decode-mp3` WASM module loaded via dynamic `impo… - [ogg-vorbis](./src/codecs/ogg-vorbis.md) — Lazy Ogg Vorbis codec — decode-only wrapper over `@audio/decode-ogg-vorbis` WASM module loaded on first use. - [opus](./src/codecs/opus.md) — Lazy Opus codec — wrapper over `@audio/decode-opus` WASM module loaded on first use. - [qoa](./src/codecs/qoa.md) — Lazy QOA (Quite OK Audio) codec — wrapper over `@audio/decode-qoa` WASM module loaded on first use. - [wasm-base](./src/codecs/wasm-base.md) — Shared factory for the seven lazy WASM-backed codec wrappers. - [wav](./src/codecs/wav.md) — Native pure-JS WAV codec implementing the full `AudioCodec` contract — decode, encode, and both streaming factories — w… - [webm](./src/codecs/webm.md) — Lazy WebM-audio codec — decode-only wrapper over `@audio/decode-webm` WASM module loaded on first use. - [decode](./src/decode/decode-source.md) — Universal decode entry point — the single function callers use to turn any `Source` into a decoded `AudioDocument`. - [decode-source](./src/decode/decode-source.md) — Universal decode entry point — the single function callers use to turn any `Source` into a decoded `AudioDocument`. - [detect](./src/detect/detect-format.md) — Format detection and source-resolution helpers — the runtime-gated entry point that turns any `Source` (string path, UR… - [detect-format](./src/detect/detect-format.md) — Format detection and source-resolution helpers — the runtime-gated entry point that turns any `Source` (string path, UR… - [encode](./src/encode/encode-to.md) — Universal encode entry point — encode an `AudioDocument` to bytes and write them to any `Destination` (file path, Writa… - [encode-to](./src/encode/encode-to.md) — Universal encode entry point — encode an `AudioDocument` to bytes and write them to any `Destination` (file path, Writa… - [error-codes](./src/error-codes/error-codes.md) — Stable error-code registry for `@suaveplan/audio-codecs`. Every fault raised by the package is an `AudioCodecsError` ca… - [error-codes](./src/error-codes/error-codes.md) — Stable error-code registry for `@suaveplan/audio-codecs`. Every fault raised by the package is an `AudioCodecsError` ca… - [registry](./src/registry/registry.md) — In-memory plugin registry that owns audio-codec lookup and dispatch for the whole package. - [registry](./src/registry/registry.md) — In-memory plugin registry that owns audio-codec lookup and dispatch for the whole package. - [stream-decoder](./src/stream/stream-decoder.md) — `TransformStream` factory — composes a chunked byte stream into an `AudioPage` stream by driving… - [stream-encoder](./src/stream/stream-encoder.md) — `TransformStream` factory — composes a PCM-block stream into encoded bytes by driv… ## Install ```sh bun add @suaveplan/audio-codecs @suaveplan/audio-core ``` WASM codecs are `optionalDependencies` — install only the ones you need: ```sh bun add @audio/decode-mp3 @audio/decode-flac @audio/decode-opus ``` ## Quick start ```ts import { decodeSource, encodeTo } from "@suaveplan/audio-codecs"; // Decode any source const doc = await decodeSource(wavBytes); // Encode any document to any registered format await encodeTo(doc, "/tmp/out.wav", "wav", { bitDepth: 16, format: "pcm" }); ``` ## Modules | Subpath | Purpose | | ------------------------------------------------- | ---------------------------------------------------------------------------------- | | `./registry/registry` | `CodecRegistry` — plugin lookup + dispatch + OTel instrumentation | | `./decode/decode-source` | `decodeSource`, `progressiveDecode` — universal decode entry | | `./encode/encode-to` | `encodeTo` — universal encode entry, writes to path/stream/callback | | `./detect/detect-format` | `detectSource`, `resolveSource` — runtime-gated source resolution | | `./stream/stream-decoder` | `createDecodeTransform` — `TransformStream` | | `./stream/stream-encoder` | `createEncodeTransform` — `TransformStream` | | `./codecs/wav` | Native WAV codec — decode + encode + streaming | | `./codecs/aiff` | Native AIFF/AIFC decoder (decode-only) | | `./codecs/caf` | Native CAF (Core Audio Format) decoder (decode-only) | | `./codecs/mp3`, `flac`, `ogg-vorbis`, `opus`, `aac`, `webm`, `qoa` | Lazy WASM codec wrappers — `optionalDependency` loaded on first use | | `./codecs/wasm-base` | `createWasmCodec` factory shared by every WASM wrapper | | `./error-codes` | `AudioCodecsError`, `AUDIO_CODECS_CODES` registry (7 stable codes) | ## Codecs at a glance | Codec | Native | Decode | Encode | Streaming | Magic | | ------------ | :----: | :----: | :----: | :-------: | ---------------------- | | WAV | ✅ | ✅ | ✅ | ✅ | `RIFF` … `WAVE` | | AIFF/AIFC | ✅ | ✅ | ❌ | ❌ | `FORM` … `AIFF`/`AIFC` | | CAF | ✅ | ✅ | ❌ | ❌ | `caff` | | MP3 | WASM | ✅ | ✅ | ❌ | ID3v2 / MPEG sync | | FLAC | WASM | ✅ | ✅ | ❌ | `fLaC` | | Ogg Vorbis | WASM | ✅ | ❌ | ❌ | `OggS` | | Opus | WASM | ✅ | ✅ | ❌ | `OggS` | | AAC | WASM | ✅ | ❌ | ❌ | ADTS sync | | WebM (audio) | WASM | ✅ | ❌ | ❌ | EBML header | | QOA | WASM | ✅ | ✅ | ❌ | `qoaf` | ## Source variants accepted `decodeSource`, `progressiveDecode`, and `detectSource` all accept any of: - `string` — bare path (server: `fs.readFile`; browser: `fetch`), `file://` URI (server only), or `http(s):` / `data:` / `blob:` string (any runtime: `fetch`). - `URL` instance — resolved via `fetch`. - `ArrayBuffer` / `Uint8Array` — consumed directly. - `ReadableStream` — drained on demand. ## Destination variants accepted `encodeTo` accepts any of: - `string` file path — written via runtime-gated `node:fs/promises.writeFile`. - `WritableStream` — one chunk write then close. - `(chunk: Uint8Array) => void` callback — single invocation with the full encoded payload. ## Error model Every fault is an `AudioCodecsError` carrying one of seven stable codes: - `AUDIO_CODECS.UNKNOWN_FORMAT` — detection found no codec. - `AUDIO_CODECS.DECODE_FAILED` — codec rejected input. - `AUDIO_CODECS.ENCODE_FAILED` — codec rejected document. - `AUDIO_CODECS.STREAM_ERROR` — abort or stream-only failure. - `AUDIO_CODECS.NOT_SUPPORTED` — operation unavailable for codec (e.g. encode for AIFF) or `optionalDependency` not installed. - `AUDIO_CODECS.INVALID_SOURCE` — unrecognised source / destination or Zod boundary validation failure. - `AUDIO_CODECS.BUDGET_EXCEEDED` — projected memory > caller's budget. Original errors are preserved on `error.cause`; additional triage data lives on `error.context`. ## Verification ```sh bunx turbo lint typecheck test --filter=@suaveplan/audio-codecs bunx turbo test:coverage --filter=@suaveplan/audio-codecs ``` ## Spec & change history - Design change: `enterprise-audio-codecs/` - Canonical spec (after archive): `audio-codecs/spec.md`