AudioGraphBuilder interface

Builds a spectrum-audio processing graph. Start from AudioGraphBuilder.input (the single source); each operation takes input handle(s) + params and returns a new handle. Operations are added one at a time as the library grows.

Signature:

export interface AudioGraphBuilder

Properties

Property Type Description

input

AudioNode

The input audio stream — the graph’s (first) source; inputs[0].

inputs

AudioNode[]

One handle per configured source, in AudioGraphSettings.sources order (a single-input graph has exactly [input]). Feed them into any op — mix(inputs) is the classic multi-source shape.

Methods

Method Description

agc(input, opts)

A loudness-driven automatic volume control: steers BS.1770 short-term loudness toward targetLufs with slew-limited gain (upDbPerS / downDbPerS) inside [minGainDb, maxGainDb]; adaptation freezes while momentary loudness is below gateLufs, so silence is never pumped. Also a measurement tap: emits agc readings (gain_db, shortterm_lufs) every 100 ms — give it a name to receive them via AudioGraphSettings.onMeasurement. All numeric fields are runtime params. Defaults: −23 LUFS (EBU R128), ±18 dB, 3 dB/s up, 12 dB/s down, gate −45 LUFS.

biquad(input, opts)

An RBJ biquad filter (the full cookbook), built against the stream’s rate. gainDb applies to the shelf/peaking shapes. Runtime-retunable via AudioGraphNode.setParams() (cutoffHz / q / db) — the live EQ tweak.

calmChain(input, opts)

An ATSC A/85 (CALM Act) compliance chain (−24 LKFS programme, ≤ −2 dBTP): as AudioGraphBuilder.ebuR128Chain() with the US broadcast targets — agc to −24 LUFS and the true-peak limiter ceiling at −2 dBTP. Default tap name "calm".

channelConcat(inputs)

Concatenate the inputs' channels into one stream (input k’s channels become the next block of output channels). N mono inputs → an N-channel stream; two stereos → 4 channels.

channelGain(input, opts)

A per-channel gain, in dB (one entry per channel, in channel order; a channel beyond the list stays at unity). Unlike a diagonal matrixMix, each channel can be faded independently at runtime (setParams with gainsDb).

channelPad(input, opts)

Force a stream to exactly target channels: pad short inputs with silence, truncate wide ones. The crash-safe front of a fixed-channel-count graph (e.g. a fan-out configured for 16 channels).

channelSelect(input, opts)

Select one channel of the input as a mono stream (0-based channel index).

clip(input, opts)

A windowed clipping tap: per window emits clip_ratio, the fraction of samples at/above threshold of full scale (default 0.99).

compressor(input, opts)

A feed-forward dynamic range compressor (linked channels — one gain across all channels, so the image doesn’t shift; log-domain soft knee; branching attack/release smoothing; makeup gain). All parameters are runtime-tunable via AudioGraphNode.setParams(); makeupDb honours a transition. Defaults: −20 dBFS threshold, 3:1, 6 dB knee, 5 ms attack, 50 ms release.

correlation(input, opts)

A windowed inter-channel correlation tap (stereo phase, −1..1).

dcBlock(input, opts)

A one-pole DC blocker (corner at cutoffHz, default 20 Hz).

dcOffset(input, opts)

A windowed DC-offset tap: per window emits the largest per-channel mean.

deadChannel(input, opts)

A windowed dead-channel tap: flags a channel below floorDb (default −70) while another channel is above it — the lost-leg case whole-stream silence detection misses.

ebuR128Chain(input, opts)

An EBU R128 compliance chain (−23 LUFS programme, ≤ −1 dBTP): an agc steering short-term loudness to −23, an optional compressor for range control, and a brick-wall true-peak limiter with its ceiling at the standard’s −1 dBTP. A loudness tap on the chain’s output (named name, default "ebuR128") is returned alongside the output node: pin it into your output’s qualityMetrics (measurements: [chain.loudness]) and/or read it via AudioGraphSettings.onMeasurement for compliance metering; the agc’s own gain readings arrive as tap "<name>.agc".

envelope(input, opts)

The waveform-timeline tap (audio passes through): per channel per window it emits signed linear min/max sample values — the scrolling-waveform feed. 1—​10 ms windows give DAW-zoom resolution at trivial bandwidth (measurements are batched per processed frame on the wire).

eq(input, opts)

A multi-band parametric EQ: bands biquads applied in series as one node. Each band’s filter kind is fixed at build; its frequency/Q/gain are runtime-tunable via AudioGraphNode.setParams() eqBands (entry i tunes band i). The number of bands is fixed at build.

gain(input, opts)

Apply a gain, in dB (0 = unity).

gapInject(input, opts)

TEST/AUDITION tool — deterministically punches timeline gaps into the stream (drops gapMs of samples every periodMs, phased from the first frame, so gap positions are identical on every run of the same content). Feed a downstream node to audition concealment on real material. periodMs/gapMs are runtime-updatable via setParams. When named, emits gap_injected_ms on the measurement firehose as each gap closes. Not for production graphs.

goniometer(input, opts)

The stereo-image (goniometer / Lissajous) feed: per window the measurement carries data — decimated L/R sample pairs packed as interleaved i16 LE. Copy before viewing (the bytes view may be unaligned): const b = data.slice(); new Int16Array(b.buffer, 0, b.length / 2). Also carries a pairs count. Defaults (33 ms window, ÷8 decimation) ≈ 190 kbit/s.

limiter(input, opts)

A brick-wall look-ahead limiter (linked channels): the gain attacks ahead of a transient (content is delayed by lookaheadMs, keeping its PTS; the delay is reported as node latency) and a final clamp makes the ceiling absolute. lookaheadMs is fixed at build; the rest are runtime params. With truePeak the detector is 4× oversampled inter-sample peaks (BS.1770), so ceilingDb can be a true-peak (dBTP) limit directly; without it the detector is sample-peak — leave ~1 dB inter-sample margin on the ceiling. Defaults: −1 dBFS ceiling, 2 ms look-ahead, 1 ms attack, 50 ms release, sample-peak.

loudness(input, opts)

An EBU R128 loudness tap (audio passes through): emits whole-stream momentary/shortterm/integrated LUFS + LRA + true-peak per window. Reference it from an output’s measurements to pin its readings into that output’s qualityMetrics (for downstream switchers), and/or read it via AudioGraphSettings.onMeasurement.

matrixMix(input, opts)

Up/down-mix by a linear-gain matrix: matrix[out][in] — rows are output channels (the output layout is the row count), columns input channels.

meter(input, opts)

The channel-strip meter tap (audio passes through): per channel per window it emits rms_db (the bar), peak_db (the floating peak line) and peak_hold_db (max window peak over the last holdMs, default 1500 ms); with truePeak, also per-channel true_peak_db (BS.1770 4× inter-sample peaks). 10—​50 ms windows drive a responsive console meter.

mix(inputs, opts)

Mix N inputs into one stream. The output’s layout and rate are the FIRST input’s (other inputs are resampled to its rate; a layout mismatch is a build error — align layouts first with matrixMix / channel ops). weights are linear, one per input; omitted = unity for every input. Weights are runtime-tunable (setParams with weights, ramped).

monitor(input, opts)

A local audio-out MONITOR sink: play this point of the graph on a local output device (operator monitoring, "listen in at any point"). A tap — it passes audio through, nothing downstream. device is an output device name from hardware info’s audioDevices (omit/"" = default). Both the device and enabled are runtime-tunable via AudioGraphNode.setParams() (device / enabled), so you can start/ stop and re-point monitoring live without rebuilding the graph. Returns the node so you can target it with setParams.

mute(input, opts)

A click-free hard MUTE. Ramps between unity and silence over rampMs (default 15 ms) so toggling never clicks. muted is runtime-tunable via AudioGraphNode.setParams() (muted), so it toggles live.

plc(input, opts)

Packet-loss concealment: fills timeline gaps in the input with synthesized audio so a dropout (a dropped SDI frame, a lost packet run) is broadly inaudible up to ~40 ms and inoffensive beyond.

strategy (default "plc"): signal-adaptive — tonal content continues at its own pitch, noise-like content extends as shaped noise, both attenuated to silence by ~100 ms. "replicate" is the legacy GapFiller echo; "silence" fades out and back in (debug).

Gaps longer than maxGapMs (default 500) are an outage: nothing is manufactured — the (smaller) hole passes through and the audio fades back in on return. latencyMs (default 0) holds audio back so the silence strategy can fade out the pre-gap tail retrospectively, at the cost of that much latency.

When a name is given, concealment events (concealed_ms, voiced) are emitted on the measurement firehose under that tap name.

polarity(input)

Polarity inversion (× −1, all channels).

resample(input, opts)

Sample-rate convert to rate Hz (layout preserved).

rms(input, opts)

A windowed RMS level tap: the audio passes through unchanged (the returned handle carries it) and per window it emits a per-channel rms_db measurement. name identifies the tap in the AudioGraphSettings.onMeasurement callback; windowMs is the measurement window.

silenceDetect(input, opts)

A windowed silence-detection tap (audio passes through): per window emits silent (0/1) + rms_db, flagged when the loudest channel is below thresholdDb (default −60 dBFS).

spectral(input, opts)

A windowed FFT tap: per window emits spectral_flatness / peak_ratio / peak_freq / hum_energy (the tone / static-noise / mains-hum substrate). windowMs is converted to the FFT size in frames.

spectrum(input, opts)

The RTA (spectrum analyser) tap: per window, bands log-spaced band magnitudes (dB, 20 Hz→Nyquist; default 31, max 64) as band_0..band_{N−1} readings plus a bands count. A tone reads ≈ its programme level in its band. windowMs is the FFT length.

split(input, channels)

Convenience: split a channels-wide input into that many mono streams (one channelSelect per channel). Returns the handles in channel order. The wire graph is identical to writing the selects by hand — the source runs once and each select extracts only its own channel.