AudioScene class final

Decides what is heard, and how loudly.

The reason this exists rather than handing positions to the audio engine: SoLoud's own 3D needs update3dAudio() to apply a moved source or a turned listener, and flutter_soloud exposes neither that call nor anything that makes it — so a source set once at play3d never moves again. In a game where the listener turns constantly that is not a limitation, it is the whole feature missing. So the geometry is computed here and the backend is asked only for a flat voice with a volume and a pan, which every backend can do and which applies immediately.

A mix

update, once a frame, after everything has moved:

  1. the mixer moves on by the frame's seconds — snapshots blend, ducks attack and release, against what was heard in the mix before;
  2. the listener and every emitter that follows a node read it;
  3. the spatial renderer decides, for each emitter, how loud it arrives, where it sits and how dull it is;
  4. the loudest maxVoices by priority get voices, each at its bus's gain and through its bus's low-pass.

AudioPlugin runs it in the engine loop's audio phase.

Constructors

AudioScene({required AudioBackend backend, int maxVoices = 24, double occlusion(Vector3 from, Vector3 to)?, Mixer? mixer, Random? random, SpatialRenderer spatial = const EqualPowerPanner(), WorldProperties? world})
A scene playing through backend, at most maxVoices at once, 24 by default. A null mixer is a fresh one, a null random a generator seeded with 1, and a null world the standard world. Asserts maxVoices is above nought.

Properties

backend → AudioBackend
The device the voices are played on, as update asks for them.
final
emitters → List<AudioEmitter>
Everything currently held, audible or not.
no setter
hashCode → int
The hash code for this object.
no setterinherited
maxVoices → int
How many may sound at once.
final
mixer → Mixer
What each bus is turned to. Read every frame, so moving a slider is heard on the next one without restarting anything.
final
occlusion → double Function(Vector3 from, Vector3 to)?
What the world does to a sound between there and here, from 0 (silenced) to 1 (clear).
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
spatial → SpatialRenderer
Turns where a sound is into how it is heard: EqualPowerPanner unless a game hands in another — a binaural one, one that follows sound through the level.
final
voiceCount → int
How many held emitters have a voice on the backend now, a count of at most maxVoices.
no setter
world ↔ WorldProperties
The world the sounds travel in: its air's speed of sound, from its temperature, is what a Doppler shift is reckoned against (SpatialQuery.world). The standard world, a room at sea level, unless a game hands in its own.
getter/setter pair

Methods

attach(SoundDef sound, PoseSource pose, {AudioBus? bus}) → AudioEmitter
Starts sound on the node pose reads — a torch, an engine, a monster's mouth — placed there at once and following it every mix.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
play(SoundDef sound, Vector3 at, {AudioBus? bus, PoseSource? follow}) → AudioEmitter
Starts sound at at, in metres. The emitter is returned so a caller that owns a moving source can keep it.
preload(Iterable<SoundDef> bank) → Future<void>
Has the backend load every asset of bank once, so the first play of each is not held up decoding it. An asset named twice loads once.
stopAll() → void
Stops everything, for a level change or a pause.
toString() → String
A string representation of this object.
inherited
update(AudioListener listener, {double dt = 0.0}) → void
Recomputes the mix. Called once a frame, after everything has moved.

Operators

operator ==(Object other) → bool
The equality operator.
inherited