openmixer — generated API reference
    Preparing search index...

    Class MixerServer

    Index
    • get align(): AlignWatcher | undefined

      The smart-alignment watcher (present once started).

      Returns AlignWatcher | undefined

    • get bpmValue(): number

      The console-wide BPM (native-FX tempo-sync) — read by the FX mirror to resolve synced delays.

      Returns number

    • get channelEqStore(): ChannelEqStore

      The built-in console EQ store (per-channel five-band parametric + HPF/LPF). Exposed so a host (the demo) can mirror eq.set state onto the native mixer's biquad cascade — the same seam the fader/mute/pan control bridge uses for the native strips.

      Returns ChannelEqStore

    • get compController(): CompController

      The per-channel compressor controller — exposed for the native comp-DSP mirror.

      Returns CompController

    • get delayController(): DelayController

      The per-strip native FX-delay controller — exposed for the native FX mirror (native-FX spec).

      Returns DelayController

    • get driveController(): DriveController

      The per-strip native DRIVE controller — exposed for the native DSP mirror.

      Returns DriveController

    • get externalRoutes(): ExternalRouteLedger | undefined

      The external route ledger, when persistence is configured — exposed so the composition root (console-rig.ts, the only place holding both the native registry feed and the mixer's desired graph) can wire live Link observation and heal-time reapply onto it. The server itself only ever reads it, through /patchbay/external.

      Returns ExternalRouteLedger | undefined

    • get fbs(): FbsCorrector | undefined

      The FBS correction engine (present once started).

      Returns FbsCorrector | undefined

    • get feedbackWatcher(): FeedbackWatcher | undefined

      The FBS detection watcher (undefined on a host with no RTA source).

      Returns FeedbackWatcher | undefined

    • get gateController(): GateController

      The per-channel gate controller — exposed for the native gate-DSP mirror (see above).

      Returns GateController

    • get hrp(): HrpCorrector | undefined

      The HRP correction engine (present once started).

      Returns HrpCorrector | undefined

    • get port(): number

      The bound HTTP port once start has resolved (0 before).

      Returns number

    • get reverbController(): ReverbController

      The per-strip native reverb controller — exposed for the native FX mirror.

      Returns ReverbController

    • get room(): RoomWatcher | undefined

      The room-analysis watcher (present once started).

      Returns RoomWatcher | undefined

    • get roomModePlant(): RoomModePlanter | undefined

      The room-mode EQ planter (present once started).

      Returns RoomModePlanter | undefined

    • get rtaBroadcaster(): RtaBroadcaster | undefined

      The RTA broadcaster (undefined on a host with no RTA source) — its demand ledger is what a test inspects to see which channels the desk has armed and why.

      Returns RtaBroadcaster | undefined

    • get rtaSubscriberCount(): number

      The RTA poll's live subscriber count — the same fact /telemetry/subscription serves.

      Returns number

    • get speakerAlign(): SpeakerAlignWatcher | undefined

      The loudspeaker-alignment watcher (present once started).

      Returns SpeakerAlignWatcher | undefined

    • get stageboxes(): StageboxRegistry | undefined

      The persistent stagebox registry — exposed so a test can prove the persistence LAW rather than infer it: pendingBackgroundWork drains a write this instance started before stop() returns, and a test proving that needs the same registry the fire-and-forget seed wrote through.

      Returns StageboxRegistry | undefined

    • get stageOrderDoor(): StageOrderDoor

      The stage-order store, as the DOOR the native mirror and the session reader read it through — an interface, never the class, so neither depends on where the override happens to live.

      Returns StageOrderDoor

    • The adapter entries as adapters.yaml holds them — the operator's own Setup store, read at call time so a gesture applies to the next read. [] on a console with no adapter manager.

      The consumer is hardware-presence: a reac entry naming a box model is the operator's written-down expectation that a box SHOULD be there, and that expectation lives here rather than in any transport config file.

      Returns readonly AdapterConfig[]

    • THE LANDING EDGE of a head-amp write, announced as ?watch=1 answers a GET on that row.

      The write is QUEUED and the door returned long before the box was told anything (southbound §6b), so delivery.reached is false with nothing refused when a client is answered. This is how it learns the fact moved, without polling.

      READ and broadcast — deliberately NOT reprojectHeadAmp, and marked ANNOUNCING so fanOutHeadAmp mirrors onto the strips without re-projecting the sibling legs. A re-projection is what DRIVES the preamp, so announcing a landing through one dispatches a write nobody asked for, which lands, which announces again. The streams law wants exactly this anyway — an event IS what a GET on the address answers, and a GET carries no projection.

      Called once per LEG by the resource itself, which owns the record and therefore the authority on which channels share the preamp — so the sibling legs' rows are announced from their own reads rather than derived a second way here.

      Parameters

      Returns void

    • Re-read /reac/segment and, only when it actually moved, reproject it to its watchers — the one announce seam for a change no PATCH carried: the live-pace poll above, and the re-locking ledger's open/close edges (reac-segment-relock.ts).

      Returns void

    • Auto-route the main mix to the host's current default Audio/Sink — the startup step that gives the bus tree a real consumer. Without one, PipeWire leaves the whole chain suspended (no sound AND no meters, even with correct patches — the demo's post-reboot field failure). The route goes through the SAME StructuralDspController.routeOutput path the UI's sink-picker (patchbay.output) uses, and the resulting patchbay.output frame is broadcast, so the Buses & outputs picker reflects the sink immediately and a later re-route / clear behaves exactly as if the operator had picked it.

      Precedence: an existing main route wins — only an unrouted main, or one still on a MainAutorouteOptions.replaceable placeholder (the demo's own consumer-less omx-demo-main node) or on a sink this method itself auto-chose earlier, is (re)routed. A restored session's route or an operator's explicit picker choice is never overridden. Re-invoking re-resolves the default sink under the same rule, so a default-sink change is followed only while the main is still on the auto pick.

      TODO(main-autoroute-follow): follow live default.audio.sink metadata changes (a pw-metadata -m watcher) instead of only re-resolving on server start / explicit re-invocation.

      Cleanly skips — never throws — when this server has no structural surface, when no eligible sink exists (CI / headless hosts), or when the live route fails.

      Parameters

      • options: MainAutorouteOptions = {}

        placeholder endpoints + default-sink resolver + sinks to avoid + log

      Returns Promise<MainAutorouteResult>

      the routing verdict (what was routed, or why nothing was)

    • Fan one resource-layer frame out to every surface.

      Public because the frames do not all originate here: a re-projection driven by a mute group or a panic happens in the composition root, where the native mixer is, and it must reach the same clients through the same seam as a REST write. A group activation that moved the meters while every surface kept rendering the pre-group picture is the same disagreement this layer exists to remove, merely pointed the other way.

      Parameters

      Returns void

    • The curated-plugin door the chain control rows read and write through — the controller that owns the commanded-value ledger and the two writers that reach mod-host.

      undefined before start(), which is the honest answer: with no controller there is no plugin to command, so every control address is absent rather than a value nobody set.

      Returns StructuralDspController | undefined

    • The READ twin of surfaceWrites: the console's rows, in process, for a bridge that runs INSIDE this server (ConsoleRowFeed).

      It is the ROOT STREAM and nothing else — this.streams.observe admits the caller as a root watcher exactly as GET /api/?watch=1 admits a browser, so it gets the same opening snapshot, hears every committed change through the same one seam, and ref-counts the same metering and telemetry pumps. The only thing it does not do is serialise, which for a consumer in this process was never anything but a socket it could also drop.

      undefined on a console with no resource layer — there are no rows to watch, and a feed that answered with silence would be indistinguishable from a quiet desk.

      Returns ConsoleRowFeed | undefined

    • The detected stageboxes as a THREE-valued reading for the presence oracle (hardware-presence-oracle.ts): undefined until the I/O monitor has run at least once, then the (possibly empty) list. The distinction is load-bearing — see stageboxesRead.

      Returns readonly StageboxDevice[] | undefined

    • Drop the curated-plugin values recorded against the plugin a chain processor used to host. Public because the chain ENTITY is the other door onto that choice: the cache is one store and both doors invalidate it, or the chain.processors echo would carry the old plugin's symbols against the new one.

      Parameters

      Returns void

    • The operator-tuned gesture timings, read live per press by the surface hosts.

      Returns GestureTiming

    • One cycle of the 2026-09-15 route-heal spec (§3) — re-route every bus whose destination has left the graph, prove it took, and say so.

      Driven by the route healer's own settled Node/Port burst (console-rig.ts's wireRouteHealing), never a poll: a route is dead exactly when the ports it names are gone, which is a Node/Port fact. It is the complement of autorouteMainOutput, not a rival: that one places an UNROUTED main at boot and deliberately keeps its hands off an explicit route; this one is for the explicit route that stopped existing, which is the case that left MAIN silent on 2026-09-15 with already-routed answered on every heal.

      Writes through the SAME StructuralDspController.routeOutput the sink picker uses and re-projects the route row, so the heal is indistinguishable downstream from an operator's own pick. Cleanly does nothing — never throws — on a console with no structural surface.

      Returns Promise<void>

    • The native engine mirror is wired and has asserted the console onto its lanes.

      Called by the composition root right after it installs the mirror, because only the root knows when that happened: the server owns the stores, the root owns the native node. Until it is called a NO_ENGINE_MIRROR verdict is the boot sequence; after it, it is a defect.

      Returns void

    • Record that the box behind recognition key was just heard on REAC segment segment — the write half of stageboxKnownReacSegment, called from console-rig.ts's role projection whenever a segment's door resolves a real box. Fire-and-forget like every other registry write off the hot path; a box this registry does not (yet) hold records nothing.

      Parameters

      • key: string
      • segment: string

      Returns void

    • Register the built-in-DSP whole-console assert (BuiltinDspMirror.assertAll) — set once by the composition root that owns the native node, exactly as it hands the meter poll its rate watch. A server with no native mixer never registers one and reassertProcessorLanes is then a no-op, which is honest: there are no lanes.

      Parameters

      • assert: () => void

      Returns void

    • Register the ONE consumer of an order change: the native mirror's re-push. Called by the composition root, which owns the native node — the same registration shape onProcessorLaneAssert uses, and for the same reason.

      Parameters

      Returns void

    • The PUMP-FED paths — every row with a streamPumps entry, the set the stream hub's pumped predicate derives from (demand gate §3c). Read by the snapshot conformance suite so what an undeclared root watch omits is asserted against the console's own list, never a hand-kept one.

      Returns readonly string[]

    • The live reac.link-state of the sole configured REAC bridge (issue #217), from the SAME cache trackStageboxes keeps for the patchbay stagebox badge (#154) — never a fresh pw-dump. undefined before the first I/O read or when no reac-pw bridge is detected at all. MVP is single-segment (no VLAN — see reac-adapter.ts's module doc), so there is at most one detected stagebox to read.

      This is the seam the composition root (console-rig.ts) injects into reacRegistration({ getReacLinkState }) so the reac adapter's status() reports the REAL handshake state instead of deriving established from mere NIC carrier.

      Returns string | undefined

    • Re-assert EVERY channel's built-in EQ / gate / comp / delay / reverb onto its native lane — the processor twin of reprojectAllChannelMutes / reprojectAllChannelLevels, run after every bulk state apply (session load, scene recall) for the same reason and one more: those stores are written straight by EngineConsoleStateProvider, and a channel the stored snapshot carries NO eq/gate/comp block for is not written at all — so without this the PREVIOUS show's cascade and dynamics keep running under the new show's rows.

      That is what the rig hit on 2026-08-05: a MAIN gate running while every row read { on: false }, audible only as quiet passages cutting, corrected only when the operator toggled the gate by hand — the one act that pushes. Absence in a store means the DEFAULT, and the default must be PUSHED.

      Returns void

    • The patch store follows the GESTURE — the row's recordPatch seam lands here. What the operator DECLARED is recorded, identified against the boxes on stage right now, not re-derived from live ports: a deferred patch (its box absent) has no live port, and re-deriving would erase exactly the identity leg the ghost card is drawn from. Without this the store held only what the last RESTORE adopted, so patchedPortLegs() / identityLegs() — the ghost cards, the hardware-manifest diff — read stale for the rest of the show after any live re-patch (#663's second half). Loop cuts still bypass the row and are re-adopted on the next restore; the row is every operator door.

      Parameters

      • channel: ChannelId
      • endpoints: readonly StereoEndpoint[]

      Returns void

    • Re-project EVERY held channel's LEVEL pair — fader and pan — through the rows that own them. The twin of reprojectAllChannelMutes, for the same reason and the same causes: a bulk state apply (boot autoload, session load, scene recall) writes every strip's fader/pan without passing the per-channel door, and the rows' nativeStripDrive sink is the ONE writer of ctrl[lane].fader / ctrl[lane].pan — nothing else pushes those fields onto the native lanes, so a restored show would otherwise be displayed and not heard.

      Public because the composition root runs the boot sweep once the engine holds its restored strips, exactly as it does for mute.

      Returns void

    • Returns void

    • Re-project EVERY input's head-amp through the ONE entity, when it is wired — the arrival re-assert (task #12). A reac-pw restart (or a box establishing) commits the box's OWN base scene; without this nothing corrects it, so the operator's parked values (sens −40 / GAIN 30, phantom on) stayed on the console's display while the box silently sat at whatever it came back with (field evidence, 2026-07-31 — the operator had to re-park by hand).

      registry.reproject re-reads and re-projects WITHOUT writing (no capability gate to consult), so it drives exactly HeadAmpResource.knownFieldsFor — never a param nobody has read or set. Public so a fabric-changed handler (and a test) can trigger it directly, mirroring reprojectAllChannelMutes.

      Parameters

      • options: { automaticRejoin?: boolean } = {}

      Returns void

    • Parameters

      Returns boolean

    • The patch rows' QUEUED-SINK landing: a crosspoint write has now reached the engine, so the instance is re-projected and every client converges on the settled ledger. Public because it is the composition root that hands the rows this seam (the rows are built before the server).

      The input side also carries the crosspoint-change contract every source move owes, whichever door it came through:

      • re-advertise head-amp capabilities, so an OPEN surface shows/hides phantom/pad/SENS without a reload (#155, #211) — a console has no keyboard to reload with;
      • sweep for +48 V left on a physical input no channel sources any more (#384);
      • re-sync app-stream capture, and hand a released app stream back to the default sink (it stays audible off-desk instead of silent until its next respawn). Both are best-effort — a graph read hiccup must not fail the settled write. prevSources is the channel's source set before the write, captured by the row's own reconcile — the hand-back delta cannot be re-derived after the ledger has moved.

      Parameters

      • side: "output" | "input"
      • channel: ChannelId
      • OptionalprevSources: readonly StereoEndpoint[]

      Returns void

    • Has this registry EVER recorded a REAC segment for ANY box — console-rig.ts's FIRST-BOOT guard (issue #842) ahead of stageboxKnownReacSegment: an unloaded/absent registry answers false, the honest "nothing is known" a fresh persistence root or a server built without one both mean.

      Returns boolean

    • Has ANY currently-registered box EVER carried REAC segment name segment — read through the PERSISTED registry (StageboxRegistry.knownReacSegment), never a boot-scoped memory. That is load-bearing wherever a box's LAST-KNOWN segment must survive its node vanishing: the stagebox rows read it on a fresh boot with the box unplugged, before any live door ever reads a MAC, and a closure-scoped ledger fed only by live sightings is empty at exactly that moment. (It was written for the REAC_ROLE_<segment> stale-key retirement of issue #839, which retired with the keys themselves — master-arbitration §8a, twelfth amendment.)

      Parameters

      • segment: string

      Returns boolean

    • The operator's registry label for a stagebox by its recognition key, or undefined. The public seam /reac/segment uses to show a REAC box's patch name: the composition root builds the key from the BOX's MAC (stageboxKeyOf('reac', mac), the address reac.box.mac carries — never the segment's master MAC, which is our own NIC) and asks here. Read through the registry's own door — the ONE reader — and answers undefined until persistence has loaded, exactly as resolveStageboxName does.

      Parameters

      • key: string

      Returns string | undefined

    • Instantiate the adapter (unless one was provided), connect it, wrap it in a MixerEngine, wire engine events to all sockets, then bind the HTTP server. Resolves once listening; returns the bound { host, port }.

      Returns Promise<{ host: string; port: number }>

    • Close sockets, the HTTP server, and dispose the adapter. Idempotent.

      Returns Promise<void>

    • The in-process entity door a managed control surface writes through (SurfaceEntityWrites): every desk gesture is a registry patch on the owning declaration — capability gate → write → project → broadcast, the same pipeline as a REST PATCH. Autosave and undo follow from the ROW's declared policy through the registry's commit report — a mix performed entirely from the physical desk survives a restart and is reversible, with nothing to remember here.

      A refusal moves nothing and is never re-routed — and it is ANSWERED, not merely logged: every door method resolves a SurfaceWriteOutcome at the landing. A physical desk is the one client that can keep showing what the console refused (the hand left the motor fader there), so silence would be a lie; the answer is what lets the surface put the served value back on the hardware.

      undefined on a console with no declared resource layer — there is no entity door to write through, and the surface host drops the gesture rather than inventing a path.

      Returns SurfaceEntityWrites | undefined

    • Parameters

      • options: { log?: (message: string) => void } = {}

      Returns Promise<ExclusiveTakeoverReport | undefined>

    • RAISE a standing warning set from a component outside this server — the composition root's REAC role projection is the first (reac:config-not-generated).

      Public because the raiser is not always inside this class, and the alternative is a second warnings store in console-rig. Same contract as every internal raise: the set REPLACES that source's previous set, so an empty array clears it, and /warnings is re-projected only when something actually changed.

      Parameters

      • source: string
      • messages: readonly (string | WarningMessage)[]

      Returns void