Skip to content

Skinflap/AudioVault

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AudioVault — a Godot 4 audio manager that doesn't fight itself

Most game audio is one AudioStreamPlayer and a volume slider — until two sounds play at once and one chops the other off, or the slider does nothing over half its travel because nobody converted linear to decibels. AudioVault is the drop-in that handles the parts you only notice after they sound wrong.

Godot 4.x · GDScript · no dependencies · ~160 lines you can read in one sitting.

What it does that naive audio code doesn't

  • No SFX cutoff. A single shared player means every new sound cuts off the last one. AudioVault keeps a round-robin pool, so the last N sounds overlap cleanly instead of chopping each other.
  • Correct volume. Bus volume is in decibels; sliders are 0..1 linear. Map them wrong (the usual bug) and the slider is useless over half its range. AudioVault converts properly, with a real mute floor at 0.
  • Music crossfade. Swapping tracks with .stream = x is a hard cut. AudioVault fades the old track out while the new one fades in.

Install

  1. Copy addons/audio_vault/ into your project.
  2. Project → Project Settings → Plugins → enable AudioVault (or add audio_vault.gd as an autoload named AudioVault yourself).

Use

# Optional: create the named buses you'll mix on, once
AudioVault.ensure_buses(["Music", "SFX"])
AudioVault.sfx_bus = "SFX"
AudioVault.music_bus = "Music"

# Fire-and-forget sound effects — they never cut each other off
AudioVault.play_sfx(preload("res://sfx/hit.wav"))
AudioVault.play_sfx(preload("res://sfx/coin.wav"), -3.0, 1.2)  # quieter, higher pitch

# Crossfade music between scenes
AudioVault.play_music(preload("res://music/forest.ogg"), 1.5)
AudioVault.play_music(preload("res://music/boss.ogg"), 2.0)    # fades forest out, boss in
AudioVault.stop_music(1.0)

Volume sliders that actually work

The bus volume helpers take and return plain 0..1 values, so they drop straight onto an HSlider and pair with a save system:

func _on_music_slider_changed(value: float) -> void:
    AudioVault.set_bus_volume_linear("Music", value)

func _ready() -> void:
    $MusicSlider.value = AudioVault.get_bus_volume_linear("Music")

0.0 is true silence (clamped to a -80 dB floor, not -inf); 1.0 is 0 dB; everything between is mapped through linear_to_db so the slider's travel matches what you hear.

API

Call Does
play_sfx(stream, volume_db=0.0, pitch=1.0) -> AudioStreamPlayer Play a one-shot on the next pool player. Returns the player used.
play_music(stream, fade_sec=1.0) -> void Crossfade to stream. No-op if it's already playing.
stop_music(fade_sec=1.0) -> void Fade the current track out and stop it.
current_music_stream() -> AudioStream The track playing as music, or null.
set_bus_volume_linear(bus, linear) -> void Set a bus's volume from a 0..1 slider value.
get_bus_volume_linear(bus) -> float Read a bus's volume back as 0..1.
ensure_buses(names) -> void Create any named buses that don't exist yet. Idempotent.
sfx_pool_size How many SFX can overlap before the oldest is reused (default 16).
sfx_bus / music_bus Buses new players route to (default Master).

Tested

tests/test_audio_vault.gd is a headless suite covering the pool round-robin, the linear↔dB volume round-trip and mute floor, bus creation, and the music track-swap bookkeeping. Run it:

godot --headless --path . -s tests/test_audio_vault.gd

License

MIT. Drop it in a commercial game, no attribution required.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors