openmixer — generated API reference
    Preparing search index...

    Interface SurfaceHost

    The north-side contract a control surface (a physical MIDI desk like the Behringer X-Touch / a Mackie MCU, an OSC client, or the web UI) binds to. It is exactly the slice of MixerEngine a surface needs: push canonical control intents in (SurfaceHost.setFader …), and subscribe out to canonical state changes (SurfaceHost.subscribe) so motor faders, button LEDs, scribble strips and meters can track the model. The surface never touches a device protocol — it meets every other control source at this canonical boundary.

    This is the ControlSource host promised in adapter.ts's header: a surface adapter depends on this interface, not the concrete engine, so it stays testable against a lightweight fake host.

    interface SurfaceHost {
        mainFormat?: BusFormat;
        topology?: MixerTopology;
        select?(channel: ChannelId): Promise<void>;
        setDivergence?(channel: ChannelId, divergence: number): Promise<void>;
        setFader(channel: ChannelId, level: FaderLevel): Promise<void>;
        setGain(channel: ChannelId, gain: GainLevel): Promise<void>;
        setMute(channel: ChannelId, muted: boolean): Promise<void>;
        setPan(channel: ChannelId, pan: number): Promise<void>;
        setSolo(channel: ChannelId, soloed: boolean): Promise<void>;
        snapshot(): ChannelStrip[];
        strip(id: ChannelId): ChannelStrip;
        subscribe(listener: EngineListener): () => void;
    }

    Implemented by

    Index
    mainFormat?: BusFormat

    MAIN's discrete-channel format (2026-09-08-lcr-mains.md §4/§8) — undefined where this host has no LCR concept at all (a bridge to another hardware desk), 'stereo' before the row has been read, 'lcr' once MAIN carries a discrete centre. Optional and read-only for the same reason topology is: a projection of SERVED truth, never a client-side guess — phase 1 scopes it to MAIN alone (useBusFormat.ts's own header: only MAIN can answer 'lcr'), so one field is the whole surface-facing fact, not a per-channel one.

    topology?: MixerTopology

    The bound device topology (undefined until the engine reports connected).

    • Select a channel — the console's global SEL (one selected strip per mixer, like a real desk). Optional: a host without shared selection simply omits it, and the surface keeps its selection local (the pre-#97 behaviour). Hosts that implement it fan the change back out as a selection event so every surface's SELECT LEDs and the web-ui's selected strip converge.

      Parameters

      Returns Promise<void>

    • LCR divergence 0..1 (2026-09-08-lcr-mains.md §8) — the strip's own divergence field. Optional: a host with no mainFormat concept has nothing meaningful to write here, and a surface never calls it without first checking mainFormat === 'lcr' (§8.4's "inert elsewhere" rule).

      Parameters

      Returns Promise<void>

    • Parameters

      Returns Promise<void>

    • Parameters

      Returns Promise<void>

    • Parameters

      Returns Promise<void>

    • Current canonical strips (for repainting a surface after a bank change).

      Returns ChannelStrip[]

    • Subscribe to canonical state changes; returns an unsubscribe fn.

      Parameters

      Returns () => void