2.5 KiB
runtime — shared analyzer plumbing
Purpose
The runtime module is the shared spine for SpectrumAnalyzer, Spectrogram, and MFCC. It owns option parsing through the canonical Zod schema, abort-signal short-circuits, OTel span+counter+histogram instrumentation, and construction of the audio-core AnalysisResult envelope. Centralising this scaffolding means every analyzer stays focused on its DSP and the package as a whole emits identical telemetry shapes.
Features
parseOptions— single boundary intoSpectrumAnalyzerOptionsSchemathat throwsAUDIO_ANALYSIS_SPECTRUM.INVALID_OPTIONSwith the Zod issues.ensureNotAborted— throwsAUDIO_ANALYSIS_SPECTRUM.ABORTEDif a caller-suppliedAbortSignalis already aborted.startRun— opens a span, records sample-rate/duration attributes, and returnsend/failcallbacks bound to the runs counter and duration histogram.recordBlock— bumps the block-duration histogram foranalyzeBlock.buildBase— produces theAnalysisResultenvelope (analyserName,analyserVersion,sampleRate,durationSamples,computedAt).
Usage: Basic
import {
buildBase,
ensureNotAborted,
parseOptions,
startRun,
} from "@suaveplan/audio-analysis-spectrum/analyzer/runtime";
const opts = parseOptions(raw);
ensureNotAborted(opts.signal);
const handle = startRun("spectrum-analyzer", doc, "analyze");
try {
// ... run the DSP ...
handle.end();
} catch (err) {
handle.fail(err);
throw err;
}
Usage: Advanced
import { recordBlock } from "@suaveplan/audio-analysis-spectrum/analyzer/runtime";
const startedAt = performance.now();
const result = computeBlock();
recordBlock("spectrum-analyzer", performance.now() - startedAt);
API Reference
parseOptions(raw): SpectrumAnalyzerOptions— schema-validated options.ensureNotAborted(signal): void— throwsABORTEDon pre-aborted signals.startRun(op, doc, mode): { end, fail }— OTel run handle.recordBlock(op, durationMs): void— record a single block timing.buildBase(op, doc): { analyserName, analyserVersion, sampleRate, durationSamples, computedAt }.
Implementation Notes
Instrumentation uses @opentelemetry/api which short-circuits to a no-op when no SDK is registered, so importing this module mutates no global state and runs free in suites that don't configure a MeterProvider. Tags on the counter and histograms are intentionally minimal — op and mode — so cardinality stays bounded even with high analyzer fan-out.