# NullAudioAdapter _(no submodules)_ ## Purpose `NullAudioAdapter` is a deterministic, test-only implementation of the `AudioAdapter` interface. It produces predictable fixture data without touching real audio codecs, file systems, or browser APIs, making it ideal for unit tests, property-based tests, and CI pipelines. ## Features - **Zero external dependencies** — No `AudioContext`, no `ffmpeg`, no file I/O. - **Deterministic output** — `decode` returns zero-filled `Float32Array` sized by fixture config. - **Configurable dimensions** — Duration, sample rate, channels, and format can be overridden per instance. - **Pass-through processing** — `stripSilence` and `normalise` return the input unchanged. - **Self-describing encode** — `encode` prefixes raw sample bytes with a JSON header containing metadata. ## Usage: Basic Example ```ts import { AudioSpritePacker, NullAudioAdapter } from "@suaveplan/audio-sprite-packer"; const packer = new AudioSpritePacker({ adapter: new NullAudioAdapter() }); const sprite = await packer.pack([ { name: "beep", data: new Uint8Array([1]) }, ]); ``` ## Usage: Advanced Example ```ts import { NullAudioAdapter } from "@suaveplan/audio-sprite-packer"; // Simulate a 5-second 48 kHz stereo clip. const adapter = new NullAudioAdapter({ durationSeconds: 5, sampleRate: 48000, channels: 2, }); const probed = await adapter.probe(new Uint8Array(0)); console.log(probed.durationSeconds); // 5 const pcm = await adapter.decode(new Uint8Array(0)); console.log(pcm.length); // 480000 ``` ## API Reference ### `NullAudioAdapterOptions` ```ts interface NullAudioAdapterOptions { readonly durationSeconds?: number; readonly sampleRate?: number; readonly channels?: number; readonly format?: AudioFormat; } ``` All fields are optional. Defaults are: - `durationSeconds` — `0.1` - `sampleRate` — `44100` - `channels` — `1` - `format` — `"wav"` ### `constructor(options?: NullAudioAdapterOptions)` Creates a new `NullAudioAdapter` with the supplied fixture configuration. If no options are provided, the defaults above are used. ### `supportedFormats` ```ts readonly supportedFormats: readonly AudioFormat[] = ["wav", "mp3", "ogg", "flac"]; ``` All formats are nominally supported; the adapter does not inspect the actual bytes. ### `probe(data: Uint8Array): Promise` Returns the fixture `durationSeconds`, `sampleRate`, `channels`, and `format`. The `data` argument is ignored. ### `decode(data: Uint8Array): Promise` Allocates a `Float32Array` of length `sampleRate * channels * durationSeconds` (floored) and fills it with zeros. If `data.length > 0`, index `0` is explicitly set to `0` so the branch is covered during testing. ### `encode(samples, sampleRate, channels, format): Promise` Produces a buffer consisting of: 1. A JSON header (`TextEncoder`-encoded) containing `sampleRate`, `channels`, `format`, and `length`. 2. The raw sample bytes from `samples.buffer`. This makes the encoded output self-describing and deterministic. ### `stripSilence(samples: Float32Array): Float32Array` Returns `samples` unchanged. ### `normalise(samples: Float32Array): Float32Array` Returns `samples` unchanged. ### `createNullAudioAdapter(options?: NullAudioAdapterOptions): NullAudioAdapter` Factory function equivalent to `new NullAudioAdapter(options)`. ## Implementation Notes - The adapter is **not** suitable for production use. It exists solely to satisfy the `AudioAdapter` contract in test environments. - `decode` sets `result[0] = 0` when `data.length > 0` purely to exercise the conditional branch for 100 % code coverage. - `encode` reuses `samples.buffer` via `new Uint8Array(samples.buffer, samples.byteOffset, samples.byteLength)` without copying, which is safe because the packer does not mutate encoded chunks after creation.