AudioManager class

Manages the background music: a single track (asset/audio/bkg.ogg) + mute.

Uses its own private AudioCache/Bgm pair instead of the shared FlameAudio.audioCache/FlameAudio.bgm globals (BUG-04): those globals are also what FlameAudio.play(...) uses, so a consuming app playing its own SFX through that same top-level helper would have its asset lookups silently redirected into this package's own audio folder the moment this class touched FlameAudio.audioCache.prefix. A private pair keeps the kit's bgm fully independent of whatever the app does with FlameAudio.

Inheritance
  • Object
  • GetLifeCycle
  • DisposableInterface
  • GetxService
  • AudioManager

Constructors

AudioManager({int sfxPoolCapacity = 6})
ENH-79: how many AudioPlayers playSfx keeps warm and reuses for one-shot SFX, instead of creating (and disposing) a fresh native audio channel on every single call — a combo/win-streak casual game firing 15-20 SFX/second would otherwise open that many concurrent native channels, which can stutter/drop audio on a low-end Android device. A burst beyond sfxPoolCapacity still always plays (never refused/dropped) — ObjectPool just disposes the excess instead of retaining it, so the pool's resting size never grows past this.

Properties

bgmVolume → RxDouble
User-chosen bgm volume (ENH-95) — persisted via StorageKeys.bgmVolume. This is what a duck restores to once every ducked SFX has finished, and what startBgm/resumeBgm play/resume at. Orthogonal to muted: muting never resets this, so unmuting always restores the user's chosen level.
final
debugAudioCachePrefix → String
Exposes the private cache's prefix for tests — proves this instance never touches the shared FlameAudio.audioCache global.
no setter
debugDuckedBgmVolume → double
no setter
debugNormalBgmVolume → double
no setter
debugSfxCachePrefix → String
Exposes the SFX cache's prefix for tests — proves it's a separate instance from the bgm _cache, not locked to this package's own asset location.
no setter
debugSfxDisposeCount ↔ int
Count of SFX AudioPlayers actually disposed — a player is only ever disposed when _sfxPool evicts one over sfxPoolCapacity (a burst wider than the pool) or on onClose's full teardown; every ordinary playSfx call now returns its player to the pool instead (BUG-24's original "dispose every call" guarantee is superseded by debugSfxReleaseCount/debugSfxPoolActiveCount below — those, not this, are what prove a call doesn't leak post-ENH-79).
getter/setter pair
debugSfxPoolActiveCount → int
How many SFX players _sfxPool currently considers "in use" — must be back to 0 once every in-flight playSfx call has finished; a stuck non-zero value would mean a call acquired a player and never released it.
no setter
debugSfxPoolFreeCount → int
How many SFX players _sfxPool is currently holding onto, idle, ready for the next playSfx call — bounded by sfxPoolCapacity even right after a burst wider than that (the excess gets disposed on release instead of retained, see _sfxPool's doc comment).
no setter
debugSfxReleaseCount ↔ int
Count of playSfx calls that returned their player to _sfxPool — ENH-79's regression guard: every call (success or failure) must release exactly once, so this should always equal the number of playSfx calls that have finished.
getter/setter pair
debugSfxTotalCreated → int
Total AudioPlayers _sfxPool has ever created. For SEQUENTIAL playSfx calls (each one's player released before the next starts — the realistic staggered-combo-SFX case sfxPoolCapacity is about) this stays at 1 no matter how many calls run, proving reuse actually happens instead of "one new player per call" (the pre-ENH-79 behavior). For genuinely SIMULTANEOUS calls (all in flight at once, e.g. via Future.wait with none released yet) this can still exceed sfxPoolCapacity — that many native channels really are needed at that exact instant regardless of pooling; debugSfxPoolFreeCount is what stays bounded afterward (the excess gets disposed, not retained).
no setter
duckCount → int
Number of currently-playing ducked SFX (0 when bgm is at its normal volume) — public (not test-only) since a caller's own UI may want to show a small indicator while bgm is ducked.
no setter
hashCode → int
The hash code for this object.
no setterinherited
initialized → bool
Checks whether the controller has already been initialized.
no setterinherited
isClosed → bool
Checks whether the controller has already been closed.
no setterinherited
muted → RxBool
final
onDelete → InternalFinalCallback<void>
Internal callback that starts the cycle of this controller.
finalinherited
onStart → InternalFinalCallback<void>
Called at the exact moment the widget is allocated in memory. It uses an internal "callable" type, to avoid any @overrides in subclases. This method should be internal and is required to define the lifetime cycle of the subclass.
finalinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
sfxPoolCapacity → int
final
sfxVolume → RxDouble
User-chosen sfx volume multiplier (ENH-95) — persisted via StorageKeys.sfxVolume. Multiplies every playSfx call's own volume argument (that argument stays a per-call relative weight, e.g. a quieter footstep vs. a louder explosion; this is the player's overall SFX mix).
final

Methods

$configureLifeCycle() → void
inherited
init() → Future<void>
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onClose() → void
Called before onDelete method. onClose might be used to dispose resources used by the controller. Like closing events, or streams before the controller is destroyed. Or dispose objects that can potentially create some memory leaks, like TextEditingControllers, AnimationControllers. Might be useful as well to persist some data on disk.
override
onInit() → void
Called immediately after the widget is allocated in memory. You might use this to initialize something for the controller.
inherited
onReady() → void
Called 1 frame after onInit(). It is the perfect place to enter navigation events, like snackbar, dialogs, or a new route, or async request.
inherited
pauseBgm() → void
Pauses the music when the app goes to background (lifecycle paused/inactive/hidden). Keeps _bgmPlaying = true so it knows there's music to resume when coming back.
playSfx(String fileName, {double volume = 1.0, bool duck = false}) → Future<void>
Plays a one-shot SFX from a CONSUMING app's own assets (e.g. assets/audio/tap.mp3), respecting the same muted state as the bgm track. No-ops immediately when muted — doesn't even touch the audio cache. Borrows an AudioPlayer from _sfxPool (ENH-79) instead of creating+disposing a fresh one every call, so rapid overlapping taps each still play independently (up to sfxPoolCapacity concurrently pooled, more than that still plays — just via a short-lived extra instance instead of a pooled one) without opening unbounded native audio channels during a combo/SFX burst.
resumeBgm() → void
Resumes playback when the app returns to foreground (resumed). Does not resume if the user has muted. Re-applies bgmVolume (ENH-95, "focus policy") rather than trusting whatever volume the platform stream happened to keep across a pause — so a duck that was still active right as the app backgrounded can never leave bgm stuck quiet after returning to foreground.
setBgmVolume(double value) → Future<void>
Sets the player's chosen BGM volume (ENH-95), clamped to [0, 1] and persisted via StorageKeys.bgmVolume. Applies immediately if bgm is currently playing and not ducked; if a duck is in progress, the new level takes effect once _unduckBgm restores it (ducking is always relative to this value, never a stale snapshot).
setSfxVolume(double value) → Future<void>
Sets the player's chosen SFX volume multiplier (ENH-95), clamped to [0, 1] and persisted via StorageKeys.sfxVolume. Multiplies every subsequent playSfx call's own volume argument.
startBgm() → void
stopBgm() → void
toggleMute() → void
toString() → String
A string representation of this object.
inherited

Operators

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

Static Properties

maybe → AudioManager?
Gets the instance if already registered (safe to call from game/widget tests).
no setter