81 lines
2.9 KiB
Markdown
81 lines
2.9 KiB
Markdown
# `codecs/flac`
|
||
|
||
Lazy FLAC codec — thin wrapper over `@audio/decode-flac` WASM module
|
||
loaded on first use.
|
||
|
||
## Purpose
|
||
|
||
FLAC (Free Lossless Audio Codec) is the canonical lossless format for
|
||
high-quality audio archival. It compresses raw PCM by 30–60% with no
|
||
quality loss, making it the standard format for music libraries that
|
||
need to preserve every bit of the original signal.
|
||
|
||
The package treats FLAC as a WASM-backed codec to keep the universal
|
||
`audio-codecs` package size-constant — pure-JS FLAC implementations
|
||
are large and slow, and bundling one would punish every consumer who
|
||
never touches FLAC. The actual decode/encode work delegates to
|
||
`@audio/decode-flac` loaded via dynamic `import()` on first call.
|
||
|
||
Implementation delegates to [`createWasmCodec`](./wasm-base.md) which
|
||
documents the shared lazy-load, missing-module, and error-wrapping
|
||
contract.
|
||
|
||
## Features
|
||
|
||
- `name === "flac"`, extensions `["flac"]`, MIME types
|
||
`["audio/flac", "audio/x-flac"]`.
|
||
- `canDecode(bytes)` — magic-byte sniff for `fLaC`
|
||
(`0x66 0x4c 0x61 0x43`) at byte 0; rejects buffers shorter than 4
|
||
bytes.
|
||
- Decode + encode both supported (`supportsEncode: true`).
|
||
- Streaming factory absent — single-pass full-buffer codec.
|
||
|
||
## Usage: Basic Example
|
||
|
||
```ts
|
||
import { FlacCodec } from "@suaveplan/audio-codecs/codecs/flac";
|
||
|
||
const decoded = await FlacCodec.decode(flacBytes);
|
||
const reEncoded = await FlacCodec.encode(decoded.channelData, {
|
||
sampleRate: decoded.sampleRate,
|
||
bitDepth: 24,
|
||
});
|
||
```
|
||
|
||
## Usage: Advanced Example
|
||
|
||
Round-trip FLAC → WAV → FLAC via the shared registry:
|
||
|
||
```ts
|
||
import { CodecRegistry, FlacCodec, WavCodec } from "@suaveplan/audio-codecs";
|
||
|
||
const registry = new CodecRegistry({ codecs: [FlacCodec, WavCodec] });
|
||
|
||
const flacDoc = await registry.decode(flacBytes);
|
||
const intermediate = await registry.encode(flacDoc, "wav", { bitDepth: 24, format: "pcm" });
|
||
const wavDoc = await registry.decode(intermediate);
|
||
const finalFlac = await registry.encode(wavDoc, "flac");
|
||
```
|
||
|
||
## API Reference
|
||
|
||
- `FlacCodec: AudioCodec` — `name === "flac"`, frozen.
|
||
- `canDecode(bytes)`, `decode(bytes, opts?)`, `encode(channelData,
|
||
opts?)` — see [`wasm-base.md`](./wasm-base.md) for the shared
|
||
contract.
|
||
|
||
## Implementation Notes
|
||
|
||
- Magic-byte sniff is cheap — no WASM load required for `canDecode`.
|
||
- The first decode/encode call lazily loads `@audio/decode-flac`;
|
||
subsequent calls reuse the same memoised module instance.
|
||
- Missing `@audio/decode-flac` → `AUDIO_CODECS.NOT_SUPPORTED` with the
|
||
module name in `context.module`.
|
||
- FLAC's native streaming-decode form (`Subset` profile blocks) is
|
||
not exposed by this wrapper — adding it requires a per-block
|
||
callback API which is a future extension.
|
||
- FLAC files commonly carry Vorbis comments and embedded artwork in
|
||
the same container; the codec emits PCM only — metadata extraction
|
||
is `@suaveplan/audio-metadata`'s responsibility via its own FLAC
|
||
parser, separate from this codec.
|