openmixer — generated API reference
    Preparing search index...

    Interface EngineConsoleStateProviderOptions

    interface EngineConsoleStateProviderOptions {
        adapter: MixerAdapter;
        announceAllocation?: () => void;
        announceChain?: (strip: ChannelId) => void;
        announcePatchMove?: (channel: ChannelId) => void;
        announceProcessors?: (strip: ChannelId) => void;
        announceRecordArming?: (channel: ChannelId) => void;
        bpmSnapshot?: () => number;
        broadcastResource?: (frame: ResourceBroadcast<object>) => void;
        channelPatch?: ChannelPatchStore;
        compController?: CompController;
        delayController?: DelayController;
        driveController?: DriveController;
        engine: MixerEngine;
        eqStore?: ChannelEqStore;
        fbsCorrector?: FbsCorrector;
        gateController?: GateController;
        hardwareManifest?: () => HardwareManifest | undefined;
        headAmp?: HeadAmpSessionDoor;
        headAmpsSnapshot?: () => readonly HeadAmpPortJson[] | undefined;
        hrpCorrector?: HrpCorrector;
        pagesSnapshot?: () => readonly SurfacePageJson[];
        pluginChains?: PluginChainController;
        preferencesSnapshot?: () => SurfacePreferencesJson;
        reacSegmentsSnapshot?: () => readonly ReacSegmentConfigJson[] | undefined;
        restoreBpm?: (bpm: number) => void;
        restoreHeadAmps?: (rows: readonly HeadAmpPortJson[] | undefined) => void;
        restorePages?: (pages: readonly SurfacePageJson[] | undefined) => void;
        restorePreferences?: (
            preferences: SurfacePreferencesJson | undefined,
        ) => void;
        restoreReacSegments?: (
            segments: readonly ReacSegmentConfigJson[] | undefined,
        ) => void;
        restoreSafety?: (safety: SafetySnapshot | undefined) => void;
        restoreSpeakerAlign?: (
            picks: {
                mic: ChannelId | null;
                reference: ChannelId | null;
                referenceSide: ChannelRole;
            },
        ) => void;
        restoreStripOrder?: (order: readonly ChannelRefJson[] | undefined) => void;
        restoreTalkbackMic?: (to: ChannelId | undefined) => void;
        reverbController?: ReverbController;
        rtaArming?: RtaArmingEngine;
        safetySnapshot?: () => SafetySnapshot;
        speakerAlignSnapshot?: () => {
            mic: ChannelId
            | null;
            reference: ChannelId | null;
            referenceSide: ChannelRole;
        };
        stageboxes?: () => readonly StageboxDevice[];
        stageOrderDoor?: StageOrderDoor;
        stripOrderSnapshot?: () => readonly ChannelRefJson[] | undefined;
        structural?: StructuralDsp;
        talkbackMicSnapshot?: () => ChannelId | undefined;
        warnOnLoad?: (source: string, messages: readonly string[]) => void;
    }
    Index
    adapter: MixerAdapter
    announceAllocation?: () => void

    Announce /console/allocation after a restore has rebuilt the console at the saved shape.

    The allocation is applied through the ENGINE's build door — the same one the row writes through — so unlike every restored row here it does not announce by construction. Without this the class-F battery measures exactly what it is for: the desk's shape moved and no frame carried it, so an open surface keeps showing the shape it had before the show loaded.

    announceChain?: (strip: ChannelId) => void

    Broadcast a rebuilt strip chain after apply (the server's plugin.chain fan-out). The LV2 chain has NO entity row yet, so this legacy fan-out is its only announce path — it cannot ride the by-construction announcement the five processor stores use until the chain becomes a row (filed with task #72's residue).

    announcePatchMove?: (channel: ChannelId) => void

    Announce that a RESTORE moved a channel's input patch — the announce half of the crosspoint-change contract a live write gets from the row's own settle (Server.reprojectPatchInput: the /patch/input frame, the /safety/spares swap latch that reads the same ledger, and the GHOST CARDS a departed box is drawn from while some channel still references it, #663).

    The restore drives the crosspoint through the engine, not through the row's station, so nothing announces by construction here. It is called ONLY where the patch actually moved — the same rule reconcileInput follows (southbound §6c: agreement is never a licence to re-assert) — which is what keeps a 64-channel load from firing 64 frames for 64 patches that did not change. Deliberately NOT the whole edge contract (Server.reprojectPatchEdge): that one also re-syncs app capture per call, and a bulk restore would run that sweep once per channel.

    announceProcessors?: (strip: ChannelId) => void

    Announce a strip's whole PROCESSING ARRANGEMENT — the /chain row and each of its per-processor rows. Separate from announceChain, which announces the LV2 insert rack: two stores, two doors, two announces.

    announceRecordArming?: (channel: ChannelId) => void

    Announce that a RESTORE moved a channel's RECORD ARMING — the announce half of /channel/{kind}/{index}/record, which a live PATCH gets from the row's own station.

    The row's store IS the strip (ChannelStrip.record, one store one writer), and a restore writes that store directly rather than through the station, so nothing announces by construction here. Called only where the value actually MOVED, the same rule announcePatchMove follows: a 64-channel load must not fire 64 frames for 64 decisions that did not change.

    bpmSnapshot?: () => number

    Capture/restore the console-wide BPM (native-FX tempo-sync). The server owns the BpmController, so it supplies a getter (capture) + setter (restore); absent on a server with no tempo clock, so bpm is simply omitted from the snapshot.

    broadcastResource?: (frame: ResourceBroadcast<object>) => void

    Fan out the resource frames a restore's entity write produces (the server's broadcastResource — the same fan-out that mirrors the accepted state onto the strip), so an interactive session load reaches connected surfaces exactly like a live PATCH. Boot autoload runs before any client connects, so absence loses nothing there.

    channelPatch?: ChannelPatchStore

    The console's input patch — what each channel's patch NAMES. Authoritative: a capture takes it verbatim rather than re-deriving identity from live ports, which is what let an absent box erase a patch.

    compController?: CompController
    delayController?: DelayController

    The built-in per-channel TIME-BASED inserts (native FX delay + reverb), round-tripped on the same terms as the three above. They belong in the show for the reason audit D2 names: the post-load lane assert pushes whatever these stores hold, so a load that never wrote them left the previous show's echoes and tail playing under the new one.

    driveController?: DriveController

    The strip's DRIVE stage store (2026-09-14-native-drive-stage.md) — rides the show.

    engine: MixerEngine
    eqStore?: ChannelEqStore

    The built-in per-channel EQ / gate / compressor stores, round-tripped when present.

    fbsCorrector?: FbsCorrector

    The FBS auto-corrector, round-tripped when present: capture stores each channel's arming (mode / hold / cap), apply re-arms through the corrector so a restored armed channel resumes detection on boot (its planted bands ride the eq field).

    gateController?: GateController
    hardwareManifest?: () => HardwareManifest | undefined

    Capture the session's expected hardware (issue #154) at save time — the stageboxes, soundcards, and control surfaces present on the rig. The server supplies this (it owns the live I/O enumeration + stagebox detection + adapter manager); absent on a server with no hardware view, so the manifest is simply omitted from the snapshot.

    The head-amp entity door (phase D2 of the double-door close). Where the entity resolves a channel to a physical input, capture persists ONLY the fields knownFieldsFor answers — a preamp nobody has read or set persists nothing, so a restore can never assert a placeholder onto real hardware — and restore writes the persisted trio through handle: the ONE record and its ONE projection queue, each written field becoming KNOWN. Absent, or where the channel resolves to no instance, capture reads the strip and restore drives the engine intents, unchanged.

    headAmpsSnapshot?: () => readonly HeadAmpPortJson[] | undefined

    The desk's DESIRED analog head-amp, by PHYSICAL INPUT — HeadAmpResource.knownPorts(), the store that already owns the desk's determinations (spec §6c). Absent, or an empty list, when the entity is not wired or nothing has been determined: the block is then simply omitted from the snapshot, same as stripOrderSnapshot.

    hrpCorrector?: HrpCorrector

    The HRP corrector — same seam as fbsCorrector, for the /hrp arming.

    pagesSnapshot?: () => readonly SurfacePageJson[]

    The operator's USER pages (/surface/pages) — show content, session-owned like the look above (ruling 2026-08-28). Capture reads the page block; restore seeds it — the EMPTY set when the session carries none — and re-projects the rows.

    pluginChains?: PluginChainController

    Present only when this server hosts software plugins.

    preferencesSnapshot?: () => SurfacePreferencesJson

    The operator's VIEW preferences — the desk's look (/surface/preferences). Owned by the session, not by a file of its own (operator decision 2026-08-04), so it round-trips here exactly like the BPM above: a getter for capture, a setter for restore, both reaching the ONE store behind the entity. Absent on a provider built without the row (a test, an embedder with no surface), and the block is then simply omitted from the snapshot.

    reacSegmentsSnapshot?: () => readonly ReacSegmentConfigJson[] | undefined

    The REAC segments' DESIRED config (/reac/segment/{name}'s writable rate/role) — session-owned like the pages above (2026-08-26-reac-runtime-config.md §3, "the SESSION owns desired config… the daemon persists nothing"). Capture reads the desired-config store; restore seeds it — NOTHING ASSERTED when the session carries no block, so the daemon's best-drivable default stands rather than a rate nobody chose.

    restoreBpm?: (bpm: number) => void
    restoreHeadAmps?: (rows: readonly HeadAmpPortJson[] | undefined) => void

    Re-assert a saved show's per-physical-input head-amp through HeadAmpResource .restoreKnownPort — the SAME door projectHeadAmpPort/patch use, never a second path to the preamp. Called unconditionally like restoreStripOrder: a session with no headAmps block restores nothing (absence is a fact, not a zero).

    restorePages?: (pages: readonly SurfacePageJson[] | undefined) => void
    restorePreferences?: (preferences: SurfacePreferencesJson | undefined) => void
    restoreReacSegments?: (
        segments: readonly ReacSegmentConfigJson[] | undefined,
    ) => void
    restoreSafety?: (safety: SafetySnapshot | undefined) => void
    restoreSpeakerAlign?: (
        picks: {
            mic: ChannelId | null;
            reference: ChannelId | null;
            referenceSide: ChannelRole;
        },
    ) => void
    restoreStripOrder?: (order: readonly ChannelRefJson[] | undefined) => void

    Seed the roster station from a loaded session and re-project /channel.

    restoreTalkbackMic?: (to: ChannelId | undefined) => void
    reverbController?: ReverbController
    rtaArming?: RtaArmingEngine

    The RTA engagement store — the broadcaster's own armed set. Round-tripped when present: capture records each armed channel, restore re-arms through the SAME door a PATCH uses, so a reloaded show comes back analysing exactly the lanes the operator armed. Absent on a console with no RTA source, and the field is then simply never written.

    safetySnapshot?: () => SafetySnapshot

    Gig-safety pre-loads. Accessors rather than a held copy, exactly as for the BPM above: SafetyController is the single owner, so a capture can never disagree with what a client was told (issue #404).

    speakerAlignSnapshot?: () => {
        mic: ChannelId
        | null;
        reference: ChannelId | null;
        referenceSide: ChannelRole;
    }

    The loudspeaker-alignment mic + reference picks (#838 — they ride the session like every other desk row, amending the 2026-08-31 dirtiesSession: false argument). Accessors over SpeakerAlignSetupStore, the row's one store, so a capture never disagrees with what a client was told.

    stageboxes?: () => readonly StageboxDevice[]

    The stageboxes the console currently sees, each carrying its registry identity — the same list the hardware manifest is built from. A patch is stored and resolved against it, so a channel's source names a BOX and an input rather than a port that may belong to different hardware tomorrow.

    stageOrderDoor?: StageOrderDoor

    The strip's STAGE ORDER store (2026-09-15-channel-stage-order.md §8) — the OVERRIDE only. A strip on the default carries no field, so a show says "this one was reordered" or says nothing, and a load onto a console with a different stage set cannot launder a derivation into the document.

    stripOrderSnapshot?: () => readonly ChannelRefJson[] | undefined

    The /channel roster's stored ORDER override, or nothing when never reordered.

    structural?: StructuralDsp

    Present only when this server hosts the structural-DSP layer (the software mixer). When set, capture/restore round-trips buses / sends / DCA / matrix / output state (closing the #5 gap); when absent those snapshot arrays stay empty and pass through untouched, exactly as before.

    talkbackMicSnapshot?: () => ChannelId | undefined

    The talkback MIC route hooks — a show fact the session carries (operator ruling 2026-08-19). Generators are deliberately NOT here: their edges are instrument state the assignment row re-declares, and capturePatch excludes them from the routing graph.

    warnOnLoad?: (source: string, messages: readonly string[]) => void

    Told about every retired-gainDb sighting a restore encounters (2026-07-30 — no back-compat, see ChannelSnapshotJson.digitalGainDb's doc). source is a verb-shaped label ('session.load' for a whole console restore, 'channelConfig.apply' for a pasted per-channel preset); messages is the full, human-readable set for that ONE apply — the server is expected to forward it verbatim to WarningsController.raise, which REPLACES rather than appends, so a clean apply must still be told (with []) to clear whatever a previous bad one left showing. Absent on a provider built without a warnings sink (a test, an embedder that does not care) — the sighting is then just silently dropped, same as the other optional accessors above.