openmixer — generated API reference
    Preparing search index...

    Function installBuiltinDspNativeMixerMirror

    • Built-in-processor control bridge: mirror every eq.set / gate.set / comp (dynamics) state change onto the native strip's biquad cascade + gate/comp slots — the EQ/Gate/Comp counterpart of the fader/mute/pan/gain mirror in main. The gate, comp, delay and reverb stores each take this mirror as their ONE engine sink (onApply), so a gate.set verb and a PATCH /channel/input/3/gate push identically; the EQ store, which has no such hook yet, is still mirrored by wrapping its mutators. Any pre-existing store state is pushed once at install. A failed native call is logged, never thrown. Extracted so it unit-tests with fakes.

      WHERE A PUSH LANDS. Every push is setStripEq / setStripDyn / setStripDelay / setStripReverb on the LANE that channel names: an INPUT channel is lane index − 1, main/1 is the MASTER LANE. There is no master-only branch and no master-only verb — MAIN's EQ, gate, comp AND its time-based FX all exist because MAIN is one more strip (operator ruling 2026-08-04), which is what closes the twice-reported "EQ in main does not work". Every OTHER kind — an aux, a group, a matrix, a second main — still answers NO_NATIVE_STAGE, naming the kind and index, because those tiers genuinely have no lane yet: the console says which control reached no audio and why, rather than reporting an effect it did not have.

      EQ coefficients are designed at the LIVE graph rate (task #125): opts.sampleRate is a provider (the native path injects a read of the node's clock-rate mirror) consulted on EVERY push, and the returned handle's BuiltinDspMirror.pollSampleRate re-pushes all strips when the observed rate changes. Without a provider the design falls back to NATIVE_DSP_SAMPLE_RATE — byte-identical to the previous fixed-48 kHz behavior.

      Parameters

      • stores: {
            bpm?: () => number;
            comp: CompController;
            delay?: FxDelayStore;
            drive?: FxDriveStore;
            eq: ChannelEqStore;
            gate: GateController;
            reverb?: FxReverbStore;
        }
        • Optionalbpm?: () => number

          Console BPM provider — read on every synced-delay push so a tap re-times every synced FX.

        • comp: CompController
        • Optionaldelay?: FxDelayStore

          Native FX-delay controller (native-FX spec); optional so existing callers are unaffected.

        • Optionaldrive?: FxDriveStore

          Native DRIVE controller (2026-09-14-native-drive-stage.md).

        • eq: ChannelEqStore
        • gate: GateController
        • Optionalreverb?: FxReverbStore

          Native reverb controller (native-FX spec).

      • native: BuiltinDspNative
      • opts: {
            busSlot?: (channel: ChannelId) => number | undefined;
            chainOf?: (channel: ChannelId) => readonly Processor[] | undefined;
            inputs: number;
            log: (m: string) => void;
            sampleRate?: () => number;
            stageOrderOf?: (
                channel: ChannelId,
            ) =>
                | readonly ("eq" | "gate" | "dynamics" | "delay" | "reverb" | "drive")[]
                | undefined;
        }
        • OptionalbusSlot?: (channel: ChannelId) => number | undefined

          WHICH BUS SLOT a console bus master occupies on this node — the engine's own SoftwareMixer.nativeBusIndexOf. With it, a bus's processors resolve to that bus's LANE and a push reaches the audio; without it a bus resolves to no lane and every push is refused by name, which is what a host with no bus array should say.

        • OptionalchainOf?: (channel: ChannelId) => readonly Processor[] | undefined

          The strip's declared chain, for the whole-console sweep. Absent on a console with no chain engine, and then the sweep pushes no order — honest: there is no chain to derive one from.

        • inputs: number
        • log: (m: string) => void
        • OptionalsampleRate?: () => number
        • OptionalstageOrderOf?: (
              channel: ChannelId,
          ) =>
              | readonly ("eq" | "gate" | "dynamics" | "delay" | "reverb" | "drive")[]
              | undefined

          The operator's STAGE ORDER for a strip, or undefined where nobody has reordered it — /channel/{kind}/{index}/order's station, read through its door (2026-09-15-channel-stage-order.md §7).

          Deliberately the OVERRIDE and not the resolved order: applyStageOrderOverride is total on an absent one, so handing it the derived default would make "the operator chose this" and "nobody chose anything" the same input, and a derivation would be laundered into an actuation.

      Returns BuiltinDspMirror