openmixer — generated API reference
    Preparing search index...

    Interface ChannelStrip

    interface ChannelStrip {
        alignDelayMs?: number;
        alignReference?: string;
        chain?: Processor[];
        clipped?: boolean;
        colour?: string;
        divergence?: number;
        fader?: FaderLevel;
        gain?: GainLevel;
        headAmpGainDb?: number;
        id: ChannelId;
        instrument?: string;
        mute?: boolean;
        name?: string;
        pad?: boolean;
        pan?: number;
        phantom?: boolean;
        polarity?: boolean;
        record?: boolean;
        recordTaps?: readonly string[];
        sends?: ReadonlyMap<string, FaderLevel>;
        solo?: boolean;
        soloSafe?: boolean;
        sourceRef?: string;
        trimDb?: number;
    }
    Index
    alignDelayMs?: number

    INPUT ALIGNMENT delay, ms. A pure input-stage latency — NOT delay (the musical FX) and not an output route's (a loudspeaker zone).

    alignReference?: string

    INPUT ALIGNMENT: the channel this one is aligned TO (a channel key, or absent for none). Kept beside the delay because a delay with nothing to be relative to is not a measurement, and because the next operator needs to know WHAT it was aligned against.

    chain?: Processor[]

    THE processing model — there is no other. The strip's ORDERED, reorderable import('./channel-chain.js').Processor list: trim, gate, eq, dynamics, each plugin insert and the fader are all the same kind of thing, a node carrying its own params.

    Position is the fact, and it is DATA. Where the EQ happens, where the gate happens, where each insert sits is the operator's decision carried by this list; the fader's index is what makes pre/post a position rather than a flag. A named slot cannot hold that, which is why there is one list and no slots (an internal spec, NORMATIVE; ADR-0006). A reorder is served by PATCH /channel/{kind}/{index}/chain { order } as a strict permutation and reaches the native step walk through deriveStageOrder — the order a client reads is the order the audio takes.

    Normalized by import('./channel-chain.js').normalizeChain, which guarantees exactly one always-present EQ (disableable and movable, never removable) and, for input strips, a structural fader. Absent means the strip has not been assembled yet, never that it processes through some other representation.

    clipped?: boolean

    The clip LATCH — /channel/{kind}/{index}/clip's clipped (an internal spec). ENGINE-OWNED: a surface never sets this true, only reflects it and PATCHes { clipped: false } to clear. undefined before the row has been read, same as every other mirrored fact here.

    colour?: string

    Scribble-strip colour — a token hue key (e.g. "red"), the channel's persisted identity colour shared by every surface (web strip head + X-Touch scribble). Pure metadata: no adapter vocabulary, no audio meaning. Absent = the surface default.

    divergence?: number

    LCR divergence (#176): 0 (hard discrete) .. 1 (full phantom). undefined reads as 1 — the value the strip actually plays absent an operator choice (see ChannelSnapshotJson.divergence).

    fader?: FaderLevel
    gain?: GainLevel
    headAmpGainDb?: number

    The head-amp's GAIN in dB — the BOX's analog gain ahead of the A/D. DISTINCT from trimDb and from gain: this one buys signal-to-noise ahead of the converter, trim is the console's digital stage, and the two are never summed. Real only where the source's patched input declares an analog head-amp; inert (and hidden) otherwise.

    On a head-amp channel this and gain carry the same number, in the same unit — the encoder and the preamp are one physical control. Both are MIRRORS: the ONE store is the /channel/{kind}/{index}/headAmp row's record, and this strip field exists for the legacy engine model that predates it.

    instrument?: string

    What this input IS — a factory template id the operator assigned it (the row's codec validates membership). Metadata, like colour: no adapter vocabulary and no audio meaning of its own. It is what lets a template picker group 21 factory chains, and what a per-instrument prior would key off. Absent = unassigned, which is a real state and not a tenth family.

    mute?: boolean
    name?: string
    pad?: boolean

    −20 dB analog PAD ahead of the preamp (a box control). An ATTENUATOR, not a change of the gain's travel: engaging it drops the real level 20 dB and leaves headAmpGainDb exactly where it was.

    pan?: number
    phantom?: boolean
    polarity?: boolean
    record?: boolean

    Whether the operator wants this channel CAPTURED by the multitrack recorder — the stored wish behind /channel/{kind}/{index}/record (recording-vsc §0.2's per-channel opt-out). undefined means the kind's own default (session.ts's recordDefaultFor: input and MAIN arm, every other bus waits to be asked), so an untouched desk carries no value at all.

    A FIELD HERE, unlike width below, and for the reason that comment gives: this is the operator's own decision and nothing else writes it. Nothing derives it from the patch and nothing on the audio side has an opinion — the native node is handed a finished track list and carries no arming verb — so there is no second writer for this store to disagree with. The patch does filter the wish, but only at record start and only in the derivation the recorder runs; it never writes back here.

    recordTaps?: readonly string[]

    WHICH TAP POINTS the recorder captures for this channel — the stored set behind /channel/{kind}/{index}/record's taps (recording-vsc §0.3). undefined means the kind's own default (session.ts's recordTapsDefaultFor: an input captures its clean input AND its post-fader stem, a bus captures its print), so an untouched desk carries no value at all.

    Catalogue ids (import('./tap-points.js').TapPointId), and a SET rather than a scalar: the operator's question is "can I record pre and post fader at the same time", and the answer is a subset of the points the kind offers, not a choice among them.

    Beside record rather than folded into it, because they are two decisions: record is whether this channel is in the take at all, recordTaps is where its files are taken from. An operator who takes a channel out of the take and puts it back gets their tap set back, which folding the two would lose.

    sends?: ReadonlyMap<string, FaderLevel>
    solo?: boolean
    soloSafe?: boolean

    Exempt from SIP muting ONLY — a solo-safe channel can still be individually PFL'd/AFL'd when explicitly soloed (resolved spec Open Question #2, 2026-07-15). Unrelated to scene recall-safe (scene.ts's RecallSafeMask) despite the shared word — this is an ordinary persisted per-channel property, not a recall-time overlay. Defaults to true for fxReturn/matrix channels, false otherwise (see session.ts's soloSafeDefaultFor).

    sourceRef?: string

    The import('./source.js').Source this channel processes — the source layer (WING/Roland). When set, the channel's input + the PHYSICAL preamp props (analog sens/pad/phantom) come from the referenced source, not from this strip, because two channels splitting one XLR share one preamp and cannot disagree about it. trimDb and polarity are NOT part of that: a split is two independent digital/DSP legs off the same preamp, so they stay on THIS strip even when sourceRef is set (2026-07-30 ownership decision — see source.ts's module doc).

    trimDb?: number

    Digital input TRIM in dB — the fine head-amp offset that COMPOSES with gain (the encoder value): the adapter's head-amp stage receives gain.db + trimDb. Kept separate so the operator's coarse gain and fine trim survive each other's moves.