# `codecs/opus` Lazy Opus codec — wrapper over `@audio/decode-opus` WASM module loaded on first use. ## Purpose Opus is the modern open-source lossy audio codec that supersedes both Vorbis (for general-purpose use) and Speex (for voice). It encodes voice and music at low bitrates with quality that frequently beats MP3 and AAC, and is the default target for WebRTC voice traffic. The package treats Opus as the canonical lossy encode target. The codec is implemented as a thin wrapper over `@audio/decode-opus` loaded via dynamic `import()`. Implementation delegates to [`createWasmCodec`](./wasm-base.md) for the lazy-load, error-wrapping, and missing-module behaviour shared by every WASM wrapper. ## Features - `name === "opus"`, extensions `["opus"]`, MIME types `["audio/opus"]`. - `canDecode(bytes)` — magic-byte sniff for `OggS` at byte 0 (Opus payloads are typically Ogg-encapsulated); rejects buffers shorter than 4 bytes. - Decode + encode both supported. - Streaming factory absent — single-pass full-buffer codec. ## Usage: Basic Example ```ts import { OpusCodec } from "@suaveplan/audio-codecs/codecs/opus"; const decoded = await OpusCodec.decode(opusBytes); const reEncoded = await OpusCodec.encode(decoded.channelData); ``` ## Usage: Advanced Example Pipeline: decode WAV → re-encode as Opus for transport: ```ts import { CodecRegistry, OpusCodec, WavCodec } from "@suaveplan/audio-codecs"; const registry = new CodecRegistry({ codecs: [WavCodec, OpusCodec] }); const wavDoc = await registry.decode(wavBytes); const opusBytes = await registry.encode(wavDoc, "opus"); // Send opusBytes over a low-bandwidth transport. ``` ## API Reference - `OpusCodec: AudioCodec` — frozen constant. - `canDecode(bytes)`, `decode(bytes, opts?)`, `encode(channelData, opts?)` — see [`wasm-base.md`](./wasm-base.md). ## Implementation Notes - The `OggS` magic shared with Vorbis and FLAC-in-Ogg means detect-then-dispatch may pick the wrong codec when multiple Ogg-family codecs are registered. Register Opus before Vorbis if you expect Opus content to dominate; otherwise pass `format: "opus"` as a hint to `decode` to bypass detection. - The first decode/encode call lazily loads `@audio/decode-opus`; subsequent calls reuse the memoised module. - Missing `@audio/decode-opus` → `AUDIO_CODECS.NOT_SUPPORTED`. - Streaming Opus (chunked decode at 20 ms frame boundaries) is not exposed by this wrapper — adding it requires a per-frame parser and the `@audio/stream-opus` companion module which is a future extension. - The codec accepts the standard `EncodeOpts` shape but Opus' real encoder tuning (bitrate, complexity, signal type) is module-specific and lives in the `@audio/decode-opus` options surface.