simvx.core.audio_bus¶
Audio bus system – named buses with volume, mute, and routing.
Provides a mixing hierarchy similar to Godot’s audio bus layout. Buses can route to parent buses (e.g., SFX -> Master, Music -> Master), and the final volume is computed by walking the chain.
Bus names are case-sensitive and use the Godot convention:
"Master", "Music", "SFX", "Voice", "UI". Looking up a
bus that isn’t in the layout raises :class:UnknownBusError with the
available names listed: no lazy creation, no fallback to Master.
send_to routes signal, not just gain. A bus’s output, after its own
effect chain, flows into its send_to target and through that bus’s
gain and effects on the way to the listener, so a reverb on Master
reverberates every bus routed into Master. Every backend that can
build a graph holds to that; the pure-Python fallback mixer runs no
effects at all, so it folds the chain into one gain per bus instead.
Public API: from simvx.core.audio_bus import AudioBusLayout, AudioBus
layout = AudioBusLayout.get_default()
layout.get_bus("Music").volume_db = -6.0
layout.get_bus("SFX").mute = True
# Effective volume considers the full chain:
effective = layout.get_bus("SFX").effective_volume
Module Contents¶
Classes¶
A single audio bus with volume, mute, and parent routing. |
|
Collection of audio buses with routing and volume computation. |
Data¶
API¶
- simvx.core.audio_bus.log¶
‘getLogger(…)’
- simvx.core.audio_bus.__all__¶
[‘AudioBus’, ‘AudioBusLayout’]
- class simvx.core.audio_bus.AudioBus(name: str, volume_db: float = 0.0, send_to: str = '')[source]¶
A single audio bus with volume, mute, and parent routing.
Attributes: name: Bus display name (e.g., “Master”, “SFX”). Case-sensitive. volume_db: Volume in decibels (-80 to 24). 0 = full volume. Clamped to the declared range on every write. mute: If True, this bus and everything routed into it produce no output. solo: If True, only this bus, everything routed into it and the buses carrying it onward to Master produce output. send_to: Name of the bus this one routes its signal into (empty for a bus that feeds the listener directly).
Initialization
- volume_db¶
‘Property(…)’
- mute¶
‘Property(…)’
- solo¶
‘Property(…)’
- property effective_volume: float[source]¶
Effective dB after walking the send_to chain to Master.
Sum of volume_db along the chain. If any bus in the chain is muted, returns -80 (silent). Returns own volume_db when not in a layout.
Solo gating: when any bus in the layout has
solo=True, every bus that is not on a soloed bus’s routing path is forced to the silence floor (-80 dB): mirroring the standard mixing-console “solo” behaviour. On the path means the soloed bus itself, the buses routed into it (which are the signal it isolates) and its ancestors (which carry that signal onward). Master is always exempt so the listener still hears the surviving signal.
- class simvx.core.audio_bus.AudioBusLayout[source]¶
Collection of audio buses with routing and volume computation.
Default layout creates four buses: Master (root) <- Music, SFX, Voice
Initialization
- add_bus(name: str, volume_db: float = 0.0, send_to: str = '') simvx.core.audio_bus.AudioBus[source]¶
Add a new audio bus.
Args: name: Unique bus name (case-sensitive). volume_db: Initial volume in dB (clamped to [-80, 24]). send_to: Name of parent bus to route to. Must already exist in this layout (other than the empty string for root buses).
"Master"is permitted regardless because it’s the conventional root and is always present in default layouts.Returns: The created AudioBus.
Raises: UnknownBusError:
send_toreferences a bus that does not exist in this layout (and isn’t"Master").
- remove_bus(name: str) None[source]¶
Remove a bus by name, re-routing whatever fed it. Cannot remove Master.
Every bus whose
send_tonamed the removed bus is re-routed onto the removed bus’s own target, falling back to"Master", so the layout never holds a bus pointing at a name that is not in it. An orphan is not a state the backends can agree on: one folds the chain into a gain and stops walking at the missing name, the other builds a graph and would leave the child wired to a dead node.The removed bus is detached from the layout, so its own
- Attr:
AudioBus.effective_volumereports its ownvolume_dbfrom then on. Removing a name that is not present does nothing.
- get_bus(name: str) simvx.core.audio_bus.AudioBus[source]¶
Return the bus named
name.Raises: UnknownBusError:
nameis not present in this layout. The error message lists the available names. Bus names are case-sensitive:"master"does not match"Master".
- property buses: list[simvx.core.audio_bus.AudioBus][source]¶
All buses in the layout.
- classmethod get_default() simvx.core.audio_bus.AudioBusLayout[source]¶
Return the default bus layout (Master, Music, SFX, Voice, UI).
- classmethod create_default() simvx.core.audio_bus.AudioBusLayout[source]¶
Create the standard five-bus layout (Godot convention).
Buses:
Master(root),Music,SFX,Voice,UI, each child routed toMaster. Names are case-sensitive; the engine and every shipped player Property default uses TitleCase.
- to_dict() list[dict][source]¶
Serialize to JSON-compatible format.
Each bus emits its effect chain via :meth:
AudioEffect.to_dict;- Meth:
from_dictrebuilds the effects symmetrically.
- classmethod from_dict(data: list[dict]) simvx.core.audio_bus.AudioBusLayout[source]¶
Deserialize from JSON format.
Buses are added in the order they appear, so children must follow their parent. Layouts produced by :meth:
to_dictalready obey this ordering.send_tovalidation in :meth:add_buswill raise- Class:
UnknownBusErrorif a child precedes its parent. Each bus’seffectslist is rebuilt via :meth:AudioEffect.from_dict.