Files
skills/docs/media/audio-ir/audio-ir-core
2026-05-29 08:20:56 +01:00
..
2026-05-29 08:20:56 +01:00
2026-05-29 08:20:56 +01:00

@suaveplan/audio-ir-core - Foundation contract for the @suaveplan audio-ir family: ImpulseResponse / IrManifestEntry / IrManifest Zod schemas, in-memory IrRegistry, AUDIO_IR.* error-code registry, and OpenTelemetry surface. Universal; zero @suaveplan/audio-* runtime deps.

Foundation contract for the @suaveplan/audio-ir-* family. Universal; zero @suaveplan/audio-* runtime deps. Every sibling package (audio-ir-loader, audio-ir-{mic,speaker,room}-plugin-<name>) consumes this package.

Documentation tree

  • error-codes — Defines the closed registry of every error code the @suaveplan/audio-ir-core runtime is allowed to throw, plus the `A…
    • error-codes — Defines the closed registry of every error code the @suaveplan/audio-ir-core runtime is allowed to throw, plus the `A…
  • otel — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
    • otel — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
  • registrar — MutableUriPluginRegistrar is the canonical collector interface every audio-ir-{family}-plugin-<name> content packag…
    • registrar — MutableUriPluginRegistrar is the canonical collector interface every audio-ir-{family}-plugin-<name> content packag…
  • registry — In-memory Map<string, IrManifestEntry> registry — the central seam between content packages (which register entries)…
    • register-manifest — Thin iterator over manifest.entries that calls `registry.register(entry, { manifestSlug: manifest.packageSlug, manife…
    • registry — In-memory Map<string, IrManifestEntry> registry — the central seam between content packages (which register entries)…
  • impulse-response — Defines the in-memory shape of a fully-decoded impulse response — the value @suaveplan/audio-ir-loader.load(id) retur…
  • manifest-entry — Defines the on-the-wire shape of a single entry inside an IrManifest. An entry is the smallest unit a content package…
  • manifest — Defines the on-the-wire shape of a complete IR manifest — the package-level contract a content package (e.g. `audio-ir-…

What ships

  • ImpulseResponse / IrManifestEntry / IrManifest Zod schemas — all frozen on parse, with cross-field refinements (ID-prefix coherence, family coherence, channel-count + duration coherence).
  • createIrRegistry() → IrRegistry with register, has, get, list, clear.
  • registerManifest(registry, manifest) bulk helper.
  • AUDIO_IR.* error-code registry — exactly five codes, every one reachable from a real production call site.
  • OpenTelemetry surface — audio_ir.registrations_total, audio_ir.lookups_total, audio_ir.errors_total, audio_ir.registry_size{family}.

Modules

Module Subpath Docs
Manifest entry schema ./types src/types/manifest-entry.md
Manifest schema ./types src/types/manifest.md
ImpulseResponse schema ./types src/types/impulse-response.md
AUDIO_IR.* codes ./error-codes src/error-codes/error-codes.md
In-memory registry ./registry src/registry/registry.md
registerManifest helper ./registry src/registry/register-manifest.md
OTel instruments ./otel src/otel/otel.md
URI plugin registrar ./registrar src/registrar/registrar.md

Design

The cross-cutting design for the IR family lives in

That file is the source of truth for the family layering, ID derivation rule, URI strategy, and OTel split.

Quick install

This package is wave-0 foundation — depended on, not depending on, the rest of the audio-ir family. Pull it directly:

import {
    createIrRegistry,
    IrManifestSchema,
    registerManifest,
} from "@suaveplan/audio-ir-core";

const registry = createIrRegistry();
const manifest = IrManifestSchema.parse(rawManifestFromContentPackage);
registerManifest(registry, manifest);

Composing IR content packages

Every audio-ir-{family}-plugin-<name> content package exposes a register(registry, collector, options?) function. collector is a MutableUriPluginRegistrar — a one-method object { use(plugin) }. Pre- construct a collector, call every content package's register(...), then hand the gathered plugins snapshot to createStorageUriResolver once:

import {
    createIrRegistry,
    createUriPluginCollector,
} from "@suaveplan/audio-ir-core";
import { register as registerClub } from "@suaveplan/audio-ir-room-plugin-club";
import { register as registerPool } from "@suaveplan/audio-ir-room-plugin-pool";
import { createStorageUriResolver } from "@suaveplan/storage-uri";

const registry = createIrRegistry();
const collector = createUriPluginCollector();

// Each content package calls collector.use(plugin) for every bundle plugin.
registerPool(registry, collector);
registerClub(registry, collector);

// `collector.plugins` is a frozen snapshot — safe to hand off directly.
const resolver = createStorageUriResolver({ plugins: collector.plugins });

The collector is order-preserving and snapshot-frozen, so consumers can compose multiple content packages — or fan out to multiple resolvers (parent + inner, sharded, future builder) — without each content package needing to agree on resolver shape. See src/registrar/registrar.md for the full API reference.