simvx.core.audio_protocol¶
Backend-agnostic audio interface.
The audio system talks to three thin structural :class:Protocol types:
- class:
AudioPlaybackBackend: start / stop / pause / live-update sounds.
- class:
AudioStreamingBackend: chunk-fed PCM streaming (for procedural synthesis, AudioWorklet, etc.).
- class:
AudioBusBackend: bus-layout reconciliation and capability advertisement.
A concrete backend implements whichever facets it can. The union
- class:
AudioBackendkeeps the legacy “everything in one Protocol” surface for callers that genuinely need all three (e.g.MiniaudioBackend,WebAudioBackend); narrower callers should depend on the smallest Protocol they actually use and reach the backend via- attr:
SceneTree.audio_playback/ :attr:audio_streaming/- attr:
audio_busesso the type checker enforces the facet boundary.
Capabilities are a :class:enum.StrEnum so typos are caught at import.
Existing string callers keep working: Capability.PLAY_BASIC compares
equal to "play.basic" and round-trips through frozenset literally.
Channels are opaque integer handles allocated by the backend. The backend owns the mapping from handle to native voice; the Python layer treats them as bookmarks.
Module Contents¶
Classes¶
Capabilities a backend can advertise via :meth: |
|
Backend facet for starting and controlling individual sounds. |
|
Backend facet for chunk-fed PCM streaming. |
|
Backend facet for bus-layout reconciliation and capability discovery. |
|
Union Protocol: a backend that implements all three facets. |
Data¶
Capabilities every backend that participates in playback + streaming advertises. |
|
Mode kwarg for :meth: |
API¶
- simvx.core.audio_protocol.__all__¶
[‘AudioBackend’, ‘AudioBusBackend’, ‘AudioPlaybackBackend’, ‘AudioStreamingBackend’, ‘CAPABILITIES_C…
- class simvx.core.audio_protocol.Capability[source]¶
Bases:
enum.StrEnumCapabilities a backend can advertise via :meth:
AudioBusBackend.list_capabilities.Members are strings so
Capability.PLAY_BASIC in capsworks against either afrozenset[Capability]or a legacyfrozenset[str]. New capability flags must be declared here: string literals in backend code bypass the typo check and are banned.Initialization
Initialize self. See help(type(self)) for accurate signature.
- PLAY_BASIC¶
‘play.basic’
- PLAY_2D¶
‘play.2d’
- PLAY_3D¶
‘play.3d’
- SPATIAL_HRTF¶
‘spatial.hrtf’
- SPATIAL_DOPPLER¶
‘spatial.doppler’
- STREAMING¶
‘streaming’
- STREAMING_WAV¶
‘streaming.wav’
- STREAMING_OGG¶
‘streaming.ogg’
- STREAMING_MP3¶
‘streaming.mp3’
- STREAMING_FLAC¶
‘streaming.flac’
- EFFECT_GAIN¶
‘effect.gain’
- EFFECT_FILTER_BIQUAD¶
‘effect.filter_biquad’
- EFFECT_PARAMETRIC_EQ¶
‘effect.parametric_eq’
- EFFECT_DELAY¶
‘effect.delay’
- EFFECT_REVERB¶
‘effect.reverb’
- EFFECT_COMPRESSOR¶
‘effect.compressor’
- EFFECT_SOFTCLIP¶
‘effect.softclip’
- __new__(*values)¶
- __add__()¶
- __contains__()¶
- __delattr__()¶
- __dir__()¶
- __eq__()¶
- __format__()¶
- __ge__()¶
- __getattribute__()¶
- __getitem__()¶
- __getnewargs__()¶
- __getstate__()¶
- __gt__()¶
- __hash__()¶
- __iter__()¶
- __le__()¶
- __len__()¶
- __lt__()¶
- __mod__()¶
- __mul__()¶
- __ne__()¶
- __reduce__()¶
- __reduce_ex__()¶
- __repr__()¶
- __rmod__()¶
- __rmul__()¶
- __setattr__()¶
- __sizeof__()¶
- __str__()¶
- __subclasshook__()¶
- capitalize()¶
- casefold()¶
- center()¶
- count()¶
- encode()¶
- endswith()¶
- expandtabs()¶
- find()¶
- format()¶
- format_map()¶
- index()¶
- isalnum()¶
- isalpha()¶
- isascii()¶
- isdecimal()¶
- isdigit()¶
- isidentifier()¶
- islower()¶
- isnumeric()¶
- isprintable()¶
- isspace()¶
- istitle()¶
- isupper()¶
- join()¶
- ljust()¶
- lower()¶
- lstrip()¶
- partition()¶
- removeprefix()¶
- removesuffix()¶
- replace()¶
- rfind()¶
- rindex()¶
- rjust()¶
- rpartition()¶
- rsplit()¶
- rstrip()¶
- split()¶
- splitlines()¶
- startswith()¶
- strip()¶
- swapcase()¶
- title()¶
- translate()¶
- upper()¶
- zfill()¶
- __deepcopy__(memo)¶
- __copy__()¶
- name()¶
- value()¶
- simvx.core.audio_protocol.CAPABILITIES_CORE: frozenset[simvx.core.audio_protocol.Capability]¶
‘frozenset(…)’
Capabilities every backend that participates in playback + streaming advertises.
The Null backend deliberately omits the streaming members because it does not implement :class:
AudioStreamingBackend; seeNullAudioBackendfor its narrowed capability set.
- simvx.core.audio_protocol.PlayMode¶
None
Mode kwarg for :meth:
AudioPlaybackBackend.play_audio.The Node-side dispatcher (
_AudioPlaybackMixin._play_common) selects the mode from the player class; backends branch on it internally so the spatial / non-spatial code paths share one entry point.
- class simvx.core.audio_protocol.AudioPlaybackBackend[source]¶
Bases:
typing.ProtocolBackend facet for starting and controlling individual sounds.
The unified :meth:
play_audiocollapses the historicalplay_audio/play_audio_2d/play_audio_3dtrio into one entry point parameterised bymode. Backends branch onmodeinternally; spatial kwargs (position,max_distance) are ignored whenmode == "non_positional".- play_audio(stream: simvx.core.audio.AudioStream, *, mode: simvx.core.audio_protocol.PlayMode = 'non_positional', position: Any = None, volume_db: float = 0.0, pitch: float = 1.0, loop: bool = False, bus: str = 'Master', max_distance: float = 100.0, from_position: float = 0.0, pan: float = 0.0, gain_db: float = 0.0) int | None[source]¶
Play
stream. Returns the channel id orNoneon failure.modeselects the spatial path:"non_positional": background music / UI sounds.positionmax_distanceare ignored;busdefaults to"Master".
"2d": Node-side spatialization computespan+volume_dbfrom the listener; the backend just applies them before the first audio buffer is rendered.busdefaults to"SFX"."3d": same as 2D, plus :meth:update_audio_3dper frame for Doppler. The Node pre-computes initial pitch and forwards it.
from_positionseeks the playback cursor (in seconds) before the first sample is rendered.pan([-1, 1],0= centre) is applied beforesound.start()so spatial players’ first audio buffer is correctly panned.
- __slots__¶
()
- classmethod __init_subclass__(*args, **kwargs)¶
- classmethod __class_getitem__(item)¶
- class simvx.core.audio_protocol.AudioStreamingBackend[source]¶
Bases:
typing.ProtocolBackend facet for chunk-fed PCM streaming.
Procedural synthesis (
AudioSynth.attach_to), AudioWorklet feeds, and compressed-container streaming via native decoders all flow through these two methods. Backends that can’t stream (the Null backend, any no-device test stub) deliberately do NOT implement this Protocol: callers mustisinstance(backend, AudioStreamingBackend)and raise- Class:
AudioCapabilityError(or warn-once and skip) when the facet is absent.
- open_stream(*, volume_db: float = 0.0, bus: str = 'Master', buffer_seconds: float = 0.5, stream: simvx.core.audio.AudioStream | None = None) int[source]¶
Open a streaming channel for chunk-fed PCM playback.
If
streamis provided and itscontaineris a compressed format ("ogg"/"mp3"/"flac"), backends with a native streaming decoder open the file directly and ignore subsequent- Meth:
feed_audio_chunkcalls. For"wav"or synthetic"pcm"streams, the caller is expected to feed raw int16 stereo bytes via :meth:feed_audio_chunk. Backends that cannot decode the requested container raise :class:AudioCapabilityError.
- __slots__¶
()
- classmethod __init_subclass__(*args, **kwargs)¶
- classmethod __class_getitem__(item)¶
- class simvx.core.audio_protocol.AudioBusBackend[source]¶
Bases:
typing.ProtocolBackend facet for bus-layout reconciliation and capability discovery.
- sync_bus_layout(layout: simvx.core.audio_bus.AudioBusLayout) None[source]¶
Reconcile the backend’s native bus / effect graph against
layout.Cheap and idempotent: backends keep their own
dict[bus_name, native_handle]and add/remove/update only what changed since the last call. Called automatically by the audio server when :class:AudioBusLayoutor any bus’seffectslist changes; manual call is safe.
- list_capabilities() frozenset[simvx.core.audio_protocol.Capability][source]¶
Capability flags this backend supports.
Effect modules and Nodes call this before attempting to materialise a native feature; absent capabilities raise
- Class:
AudioCapabilityError(strict) or warn-once (lenient).
- __slots__¶
()
- classmethod __init_subclass__(*args, **kwargs)¶
- classmethod __class_getitem__(item)¶
- class simvx.core.audio_protocol.AudioBackend[source]¶
Bases:
simvx.core.audio_protocol.AudioPlaybackBackend,simvx.core.audio_protocol.AudioStreamingBackend,simvx.core.audio_protocol.AudioBusBackend,typing.ProtocolUnion Protocol: a backend that implements all three facets.
MiniaudioBackend(and its legacy fallback) andWebAudioBackendsatisfy this.NullAudioBackenddoes NOT (it doesn’t implement- Class:
AudioStreamingBackend): callers that need streaming should isinstance-check :class:AudioStreamingBackenddirectly via- Attr:
SceneTree.audio_streaming.
- play_audio(stream: simvx.core.audio.AudioStream, *, mode: simvx.core.audio_protocol.PlayMode = 'non_positional', position: Any = None, volume_db: float = 0.0, pitch: float = 1.0, loop: bool = False, bus: str = 'Master', max_distance: float = 100.0, from_position: float = 0.0, pan: float = 0.0, gain_db: float = 0.0) int | None¶
- stop_audio(channel_id: int) None¶
- pause_audio(channel_id: int) None¶
- resume_audio(channel_id: int) None¶
- update_audio_2d(channel_id: int, volume_db: float, pan: float) None¶
- update_audio_3d(channel_id: int, volume_db: float, pan: float, pitch: float) None¶
- set_pitch(channel_id: int, pitch: float) None¶
- set_listener_position(x: float, y: float, z: float) None¶
- set_listener_velocity(x: float, y: float, z: float) None¶
- set_listener_direction(x: float, y: float, z: float) None¶
- set_listener_world_up(x: float, y: float, z: float) None¶
- get_playback_position(channel_id: int) float¶
- is_channel_active(channel_id: int) bool¶
- shutdown() None¶
- __slots__¶
()
- classmethod __init_subclass__(*args, **kwargs)¶
- classmethod __class_getitem__(item)¶
- open_stream(*, volume_db: float = 0.0, bus: str = 'Master', buffer_seconds: float = 0.5, stream: simvx.core.audio.AudioStream | None = None) int¶
- feed_audio_chunk(channel_id: int, chunk: bytes) None¶
- sync_bus_layout(layout: simvx.core.audio_bus.AudioBusLayout) None¶
- list_capabilities() frozenset[simvx.core.audio_protocol.Capability]¶