Class Bus

A named summing node with a filter chain and per-edge send gain. See module-level docstring for topology.

Constructors

  • Parameters

    • context: BaseContext

      Web Audio context the bus's nodes live on.

    • name: null | string = null

      Name to register under, or null for an anonymous bus.

    • Optional input: GainNode

      Optional pre-existing GainNode to use as the input. Used by the master bus to alias cacophony.globalGainNode. If omitted, a fresh GainNode is allocated.

    • Optional onDestroy: (() => void)

      Optional registry-cleanup hook fired by destroy().

        • (): void
        • Returns void

    Returns Bus

Properties

_bypassedFilters: Set<AudioNode> = ...

Filter nodes currently bypassed (skipped in the audible chain). A bypassed node stays in _filterNodes — so filters order, identity, and its live AudioParams are preserved — but _desiredFilterChainEdges builds the series chain over the NON-bypassed filters only, wiring the signal around it. Membership is by node identity.

_context: BaseContext
_destroyed: boolean = false
_directConnections: Set<BusConnectionTarget> = ...
_filterChainEdges: (readonly [AudioNode, AudioNode])[] = []
_filterNodes: AudioNode[] = []
_onDestroy?: (() => void)

Hook invoked by the owning Cacophony instance to remove this bus from the named-bus registry on destroy. Anonymous buses leave this undefined.

Type declaration

    • (): void
    • Returns void

_routedSources: Set<BusRoutedSource> = ...

Inbound sources currently routed to this bus (primary route and/or sends). A Web Audio node cannot enumerate its own inputs, so sources register themselves here (via _registerRoutedSource) when they route to this bus and unregister on reroute/cleanup. drainTo walks this set to move live sounds off the bus before it is torn down.

_sendGains: Map<BusConnectionTarget, GainNode> = ...
input: GainNode

Entry node — connect upstream sources here (sound playbacks, other bus outputs).

name: null | string

Stable name for registry lookup, or null for anonymous buses.

output: GainNode

Exit node — connected to downstream targets (other bus inputs, master, raw nodes) via connect.

Accessors

  • get gain(): number
  • Output node gain — controls the overall level the bus sends downstream.

    Returns number

  • set gain(v): void
  • Parameters

    • v: number

    Returns void

Methods

  • Compute the desired ordered chain edge list from the current _filterNodes, skipping any node in _bypassedFilters: the series chain is built over the NON-bypassed filters only. With no active (non- bypassed) filters — whether the bus has no filters at all or every filter is bypassed — the desired list is [[input, output]] (the direct edge); otherwise [[input, a1], [a1, a2], ..., [aN, output]] over the active filters a1..aN. Bypassed nodes stay in _filterNodes (and thus in filters) but receive no inbound/outbound chain edge.

    Returns (readonly [AudioNode, AudioNode])[]

  • Returns void

  • Structural AudioParam check: a value is treated as an AudioParam if it exposes the ramp scheduling methods. Avoids instanceof AudioParam so it works under the standardized-audio-context mock (which may lack the global).

    Parameters

    • value: unknown

    Returns value is AudioParam

  • Reconcile the live chain to input → [filter1 → ... → filterN] → output. Called after any add/remove/reorder of a filter. This is an INCREMENTAL diff, not a full rebuild: it disconnects only edges that are no longer part of the desired chain and connects only edges that are newly required, leaving edges present in both the old and new chain connected and untouched (no audible click on the unchanged portion of the chain).

    Edges are matched by OBJECT IDENTITY on both endpoints. Only this bus's own internal input → ... → output edges are touched — never a broad node.disconnect(), never the outbound send/direct edges.

    Returns void

  • Internal

    Register an inbound source that routes to this bus (primary and/or send). Called by the source when it begins routing here. Idempotent (Set). Safe to call without a destroyed guard — registration during normal routing must never throw — but a destroyed bus has nothing to drain, so this early-returns once destroyed.

    Parameters

    • source: BusRoutedSource

    Returns void

  • Resolve the named AudioParam on a node. Tries the worklet parameters map first, then a directly-exposed native param (node[paramName]). Returns undefined if neither yields an AudioParam.

    Detection is structural (duck-typed), never instanceof — the mocked test context may not provide the AudioParam global.

    Parameters

    Returns undefined | AudioParam

  • Internal

    Unregister an inbound source (it rerouted away or was cleaned up). No-op if the source was never registered.

    Parameters

    • source: BusRoutedSource

    Returns void

  • Add a filter node to the bus's chain. Accepts:

    • A Cacophony-built BiquadFilterNode (created via cacophony.createBiquadFilter) → added directly to the chain.
    • A CacophonyEffectbuild(context) is awaited; the resulting node is added to the chain.
    • A raw third-party AudioNode → REJECTED. Wrap it with cacophony.shareEffect(node) (or a proper CacophonyEffect class) to make the shared-state intent explicit.

    Returns Promise<AudioNode>

    the built AudioNode that was added to the chain. For a biquad this is the argument itself; for a CacophonyEffect it is the node produced by build. The returned handle can be passed to rampFilterParam to automate the node's parameters. Existing callers that ignore the result keep working unchanged.

    Throws

    if the bus has been destroyed, or if the argument is a raw AudioNode that is not a Cacophony-built biquad.

  • Connect this bus's output to another bus or to a raw AudioNode.

    If gain is omitted or equal to 1, connect directly (output → targetInput). If gain is provided, allocate an internal GainNode for per-edge attenuation: output → sendGain → targetInput. The sendGain is tracked so disconnect can tear it down cleanly.

    Re-connecting a target that is already wired is a no-op for the direct case; for a gained connection, the existing sendGain's gain.value is updated in place (no new edge is allocated).

    Parameters

    Returns void

    Throws

    if the bus has been destroyed.

  • Tear down the bus — disconnects input, output, every send-gain, every filter, then deregisters from the owner Cacophony's named-bus map. Subsequent addFilter/removeFilter/connect/disconnect calls throw.

    If options.drainTo is provided, every source routed to this bus is first rerouted onto that bus (via drainTo) so live sounds keep playing through a live bus. With no options the default teardown is unchanged: sounds routed to the destroyed bus fall back to master on their next playback (the routeTo machinery checks destroyed at preplay).

    Parameters

    • Optional options: {
          drainTo?: Bus;
      }
      • Optional drainTo?: Bus

    Returns void

  • Disconnect this bus's output from a target previously connected with connect. Tears down the allocated sendGain (if any). No-op if the target was never connected.

    Parameters

    Returns void

    Throws

    if the bus has been destroyed.

  • Move every source currently routed to this bus onto target, so live sounds keep feeding a live bus instead of the dead input after this bus is torn down. Each registered source's BusRoutedSource._onBusDrained reroutes its primary route and/or the send that targeted this bus.

    Parameters

    Returns void

    Throws

    if this bus has been destroyed, or if target is this bus.

  • Whether node is currently bypassed (skipped in the audible chain). Returns false for nodes that were never added to this bus.

    Parameters

    Returns boolean

  • Ramp an effect node's parameter to a target value over time. This is the uniform automation handle for filter-chain effects: pass a node obtained from addFilter (or the filters getter) and the name of the parameter to drive.

    Parameter resolution:

    • If node exposes a worklet-style parameters AudioParamMap, the param is resolved via parameters.get(paramName) (e.g. a worklet effect's named params).
    • Otherwise, if node[paramName] is itself an AudioParam (native nodes such as a biquad expose .frequency / .Q / .gain directly), that is used.

    Ramp shape (mirrors the codebase fade convention): the target time base is node.context.currentTime. With no duration (or duration <= 0) the value is set immediately via setValueAtTime(value, now). Otherwise the start is pinned with setValueAtTime(param.value, now) and the value ramps to now + duration / 1000 (milliseconds) using linearRampToValueAtTime (default) or exponentialRampToValueAtTime when type is "exponential" (an exponential target of 0 is floored to 0.0001, matching fadeTo).

    Automation degrades gracefully: if node is not on this bus, or the parameter cannot be resolved to an AudioParam, a warning is logged and the call is a no-op. The only condition that throws is a destroyed bus.

    Parameters

    • node: AudioNode

      A filter node currently on this bus (from addFilter).

    • paramName: string

      The name of the parameter to automate.

    • value: number

      The target value.

    • Optional options: {
          duration?: number;
          type?: FadeType;
      }
      • Optional duration?: number

        Ramp duration in milliseconds. Absent/<= 0 sets the value immediately.

      • Optional type?: FadeType

        Ramp curve, "linear" (default) or "exponential".

    Returns void

    Throws

    if the bus has been destroyed.

  • Remove a filter node from the bus's chain. The node must have been added via addFilter; the same object identity is used to match.

    Parameters

    Returns void

    Throws

    if the bus has been destroyed or if the node was never added.

  • Bypass (or un-bypass) a filter without removing it from the chain. A bypassed filter stays in filters — its order, identity, and live AudioParams are preserved (so an automation target survives a bypass) — but it is skipped in the audible series chain: the signal is wired around it. Un-bypassing wires it back in at its original position.

    The reconnect goes through the incremental _refreshFilters, so only the seam around node is touched — the rest of the chain is left connected.

    Parameters

    • node: AudioNode

      A filter node currently on this bus (from addFilter or filters).

    • bypassed: boolean

      true to skip the node, false to wire it back in. A no-op if the node is already in the requested state.

    Returns void

    Throws

    if the bus has been destroyed, or if node was never added to this bus.

  • Reorder the existing filter chain. nodes must be a PERMUTATION of the current filters — the same set of node objects (matched by identity), the same length, with no duplicates — just in a new order. Because _refreshFilters is incremental, only the edges that actually move are reconnected; unchanged edges are left untouched.

    Parameters

    Returns void

    Throws

    if the bus has been destroyed, or if nodes is not a permutation of the current filters.