@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 — Lazy AAC codec — decode-only wrapper over
@audio/decode-aacWASM module loaded on first use. - aiff — Native pure-JS AIFF (Audio Interchange File Format) decoder, decode-only.
- caf — Native pure-JS CAF (Apple Core Audio Format) decoder, decode-only.
- flac — Lazy FLAC codec — thin wrapper over
@audio/decode-flacWASM module loaded on first use. - mp3 — Lazy MP3 codec — thin wrapper that defers decode/encode to the
@audio/decode-mp3WASM module loaded via dynamic `impo… - ogg-vorbis — Lazy Ogg Vorbis codec — decode-only wrapper over
@audio/decode-ogg-vorbisWASM module loaded on first use. - opus — Lazy Opus codec — wrapper over
@audio/decode-opusWASM module loaded on first use. - qoa — Lazy QOA (Quite OK Audio) codec — wrapper over
@audio/decode-qoaWASM module loaded on first use. - wasm-base — Shared factory for the seven lazy WASM-backed codec wrappers.
- wav — Native pure-JS WAV codec implementing the full
AudioCodeccontract — decode, encode, and both streaming factories — w… - webm — Lazy WebM-audio codec — decode-only wrapper over
@audio/decode-webmWASM module loaded on first use. - decode — Universal decode entry point — the single function callers use to turn any
Sourceinto a decodedAudioDocument.- decode-source — Universal decode entry point — the single function callers use to turn any
Sourceinto a decodedAudioDocument.
- decode-source — Universal decode entry point — the single function callers use to turn any
- detect — Format detection and source-resolution helpers — the runtime-gated entry point that turns any
Source(string path, UR…- detect-format — Format detection and source-resolution helpers — the runtime-gated entry point that turns any
Source(string path, UR…
- detect-format — Format detection and source-resolution helpers — the runtime-gated entry point that turns any
- encode — Universal encode entry point — encode an
AudioDocumentto bytes and write them to anyDestination(file path, Writa…- encode-to — Universal encode entry point — encode an
AudioDocumentto bytes and write them to anyDestination(file path, Writa…
- encode-to — Universal encode entry point — encode an
- error-codes — Stable error-code registry for
@suaveplan/audio-codecs. Every fault raised by the package is anAudioCodecsErrorca…- error-codes — Stable error-code registry for
@suaveplan/audio-codecs. Every fault raised by the package is anAudioCodecsErrorca…
- error-codes — Stable error-code registry for
- registry — In-memory plugin registry that owns audio-codec lookup and dispatch for the whole package.
- registry — In-memory plugin registry that owns audio-codec lookup and dispatch for the whole package.
- stream-decoder —
TransformStream<Uint8Array, AudioPage>factory — composes a chunked byte stream into anAudioPagestream by driving… - stream-encoder —
TransformStream<readonly Float32Array[], Uint8Array>factory — composes a PCM-block stream into encoded bytes by driv…
Install
bun add @suaveplan/audio-codecs @suaveplan/audio-core
WASM codecs are optionalDependencies — install only the ones you
need:
bun add @audio/decode-mp3 @audio/decode-flac @audio/decode-opus
Quick start
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<Uint8Array, AudioPage> |
./stream/stream-encoder |
createEncodeTransform — TransformStream<Float32Array[], Uint8Array> |
./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), orhttp(s):/data:/blob:string (any runtime:fetch).URLinstance — resolved viafetch.ArrayBuffer/Uint8Array— consumed directly.ReadableStream<Uint8Array>— drained on demand.
Destination variants accepted
encodeTo accepts any of:
stringfile path — written via runtime-gatednode:fs/promises.writeFile.WritableStream<Uint8Array>— one chunk write then close.(chunk: Uint8Array) => voidcallback — 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) oroptionalDependencynot 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
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