AudioBits

Recipes

Define a reusable sound with bounded versioned JSON data.

AudioBits API · 0.2.0 · Available on npm.

A recipe is data, not a native graph or code. defineSound() throws on invalid data and returns a deeply frozen snapshot. validateRecipe() returns path-specific issues without throwing for invalid input. Both work without browser globals. validateRecipe(unknown) returns { ok: true, recipe } or { ok: false, issues }. Each issue has code, path, and message; paths use JSON bracket notation such as $["layers"][0]["id"]. Inputs must be plain JSON data. The snapshot is copied, so later input mutations cannot change an existing definition.

import { defineSound, validateRecipe } from "audiobits";
const input: unknown = {
  schemaVersion: 1,
  kind: "one-shot",
  duration: 0.15,
  layers: [
    {
      id: "tone",
      source: { type: "oscillator", waveform: "sine", frequency: 660 },
      gainDb: -18,
      envelope: { attack: 0.004, decay: 0.08, sustain: 0.1, release: 0.04 },
    },
  ],
};
const result = validateRecipe(input);
if (result.ok) {
  const recipe = defineSound(result.recipe);
  console.log(recipe.kind);
} else {
  for (const issue of result.issues) console.error(issue.path, issue.message);
}

Catalog source you own

All eight existing sounds have canonical source in catalog/recipes/. Install an individual recipe from the source registry, import its local recipe.ts, create a sound, and play it after gesture activation. You own that source. The npm package supplies only the engine and recipe language. See Quick start for a complete local recipe using public engine APIs.

Interactive source

Reactive thruster is a developer-owned catalog recipe, separate from the catalog’s simpler thruster recipe. Copy recipe.ts for its sound definition, or take pointer.ts, host.ts, and index.html too for a complete vanilla interaction. Include canonical Impact at ../../recipes/impact/recipe.ts relative to the host, or install the complete registry item to preserve that layout. The showcase displays all canonical files. Install audiobits as the runtime dependency; the copied files belong to your application and have no website or framework imports.

Throttle is a live control in [0, 1]. The pointer integration maps velocity to throttle; the host adds canonical Impact on the same engine. Release preserves the sound tail, Stop all cuts voices, and the host suspends on hide. Call host.dispose() when removing the view. See Lifecycle for engine ownership in other integrations.

Supported subset

Schema version 1 supports one-shot gates up to 60 seconds or sustained playback without duration, 1–16 layers with unique IDs, four oscillator waveforms, white noise, fixed ADSR envelopes, frequency automation, and lowpass/highpass/bandpass filters. Layer gains are -60–0 dB; frequencies are 20–20000 Hz and must be below the context's Nyquist frequency at play time. Filters are limited to eight across the recipe; frequency automation to 128 points. Gain automation, expression strings, file fetches, and sequencing are unsupported.

One-shot duration ends the gate, excluding release and bounded filter tails. Attack and decay must fit within the gate, including the minimum effective attack; zero decay ramps directly to sustain. Frequency automation begins at zero, uses increasing times, and ends by gate close. Sustained automation is an onset sequence of at most 60 seconds, then holds its final value. All mapping and variation extrema must satisfy target bounds and playback Nyquist checks. Noise requires integer context sample rates from 8000 through 192000 Hz; unsupported rates fail with noise-rate before voice allocation.

Validation rejects unknown fields and versions, non-finite numbers, accessors, cycles, depth beyond 16, more than 10000 visited values, and invalid parameter references. Diagnostics are capped at 100. See Parameters for mappings and live controls. The exported recipeSchema and audiobits/schema.json describe the published schema version 1 structure.

Workbench editor

Each catalog workbench (/catalog/[slug]) accepts at most 32 KiB of JSON and shows the first ten validation issues. Apply explicitly; invalid input preserves the last valid playable sound. Applying a valid definition stops current playback and disposes the old sound. Play again to hear the new definition.

Keep the sound's playback kind and its primary parameter's range, default, and mode. Additional parameters use their declared defaults. Restore and Reset return to the catalog recipe, seed 42, and primary control defaults. Raw comparisons apply only to catalog definitions. Edited recipes still have a copyable AudioBits example containing the entire accepted JSON.

Typed authoring preserves recipe structure, parameter names and parameter modes. Runtime validation remains authoritative for exact schema validity.

On this page