Install Asset
Install via Godot
To maintain one source of truth, Godot Asset Library is just a mirror of the old asset library so you can download directly on Godot via the integrated asset library browser
Quick Information
A Simple Adaptive Music & SFX Helper
Audio Booth
A Simple Adaptive Music & SFX Helper for Godot 3.1 This plugin comes with nodes that will help you set up your adaptive music and organize sound effects in Godot 3.1.
Music
Song Node
The Song node represents a single song with all it's instruments.
It has the following properties:
tempo- the speed of the song in beats per minute.
beats- how many beats a bar has.
You must fill out these properties.
The Song itself does not hold any audio stream to play, it will only hold containers, which then will hold AudioStreamPlayers as their children.
There are two types of Containers.
TrackContainer Node
A Song needs to have exacly one TrackContainer which itself needs to have at least one AudioStreamPlayer as its child. The first child of the TrackContainer will be the core of the song. If you play a song, it will only play its core.
However, you can add more AudioStreamPlayers to the TrackContainer and play them in addition to the core at will, by calling the corresponding functions of the MusicBooth.
All AudioStreamPlayers in the TrackContainer are considered tracks.
StingerContainer Node
Additionally to the TrackContainer, you can add any number of StingerContainers to the Song. Each StingerContainer can have any number AudioStreamPlayers.
The StingerContainer allows you to randomly play sound effects - here called stingers - synced to your song.
The StingetContainer has the following properties:
tick_type- defines whether the counter shall be connected to the
beatorbarsignal of the song
- defines whether the counter shall be connected to the
wait_ticks- defines on which beats / bars a stinger might be played.
- if set to
4, this means that every 4 beats / bars, there is the given probability to play one stinger of thisStingerContainer
probability- the probability that a stinger will be played on the beat / bar
MusicBooth Node
With the MusicBooth you control your songs, define when to play which song or when to add/remove certain tracks/instruments from the current song.
It provides the following functions:
play_song(song_name: String, fade_time : float = 0.0) -> voidsong_namethe name of theSongnode that shall be played. Only plays the first track.fade_timedefines how long the fade in shall durate.- will immediately play a specific track of the current song.
- if another song is already playing, it will stop it and all it's tracks before playing the new song.
play_song_on_beat(song_name: String, fade_time: float = 0.0, delay: int = 0)song_namethe name of theSongnode that shall be played. Only plays the first track.fade_timedefines how long the fade in shall durate.delaydefines how many beats later the song shall be played.- if another song is already playing, it will stop it and all it's tracks before playing the new song.
play_song_on_bar(song_name: String, fade_time: float = 0.0, delay: int = 0)song_namethe name of theSongnode that shall be played. Only plays the first track.fade_timedefines how long the fade in shall durate.delaydefines how many bars later the song shall be played.- if another song is already playing, it will stop it and all it's tracks before playing the new song.
play_track(track: int, fade_time: float = 0.0) -> voidtrackdefines the track which shall be played.fade_timedefines how long the fade in shall durate.- will immediately play a specific track of the current song.
play_track_on_beat(track: int, fade_time: float = 0.0, delay: int = 0)trackdefines the track which shall be played.fade_timedefines how long the fade in shall durate.delaydefines how many beats later the track shall be played.- will play a specific track of the current song on the next beat when no delay is defined.
play_track_on_bar(track: int, fade_time: float = 0.0, delay: int = 0)trackdefines the track which shall be played.fade_timedefines how long the fade in shall durate.delaydefines how many bars later the track shall be played.- will play a specific track of the current song on the next bar when no delay is defined.
stop_song(fade_time : float = 0.0) -> voidfade_timedefines how long the fade out shall durate.- stops the current playing song immediately.
stop_song_on_beat(fade_time: float = 0.0, delay: int = 0)fade_timedefines how long the fade out shall durate.delaydefines how many beats later the song shall be stopped.
stop_song_on_bar(fade_time: float = 0.0, delay: int = 0)fade_timedefines how long the fade out shall durate.delaydefines how many bars later the song shall be stopped.
stop_track(track: int, fade_time: float = 0.0) -> voidtrackdefines the track which shall be stopped.fade_timedefines how long the fade out shall durate.- will immediately stop a specific track of the current song.
stop_track_on_beat(track: int, fade_time: float = 0.0, delay: int = 0)trackdefines the track which shall be stopped.fade_timedefines how long the fade out shall durate.delaydefines how many beats later the track shall be stopped.- will stop a specific track of the current song on the next beat when no delay is defined.
stop_track_on_bar(track: int, fade_time: float = 0.0, delay: int = 0)trackdefines the track which shall be stopped.fade_timedefines how long the fade out shall durate.delaydefines how many bars later the track shall be stopped.- will stop a specific track of the current song on the next bar when no delay is defined.
is_playing() -> bool- returns whether the MusicBooth is playing a song or not
is_song_playing(song_name: String) -> bool- returns whether
song_nameis the song that is currently played or not.
- returns whether
General Structure
A scene tree with two songs could look like this:
- Root
- - MusicBooth
- - - Song1
- - - - TrackContainer
- - - - - Track0 (Core)
- - - - - Track1
- - - - - Track2
- - - Song2
- - - - TrackContainer
- - - - - Track0 (Core)
- - - - - Track1
- - - - - Track2
- - - - - Track3
- - - - StingerContainer
- - - - - Stinger1
- - - - - Stinger2
- - - - - Stinger3
The Root node might be your level.
it should have an onready var music_booth = $MusicBooth and from there you can call all the fancy functions the MusicBooth offers.
The MusicBooth itself only holds Song nodes as its children.
Each Song node should have exactly one TrackContainer and can have any number of StingerContainers.
If a Song is played, it will only play it's Core. Other tracks of that song can be layered on top of the core at will.
Song2 also has single StingerContainer. This means, depending on the properties, every some beat or bar one of the stingers will be played at random.
However, this is only true if Song2 is the current song played by the MusicBooth.
Sound
Sound Node
Sound effects are stored in the Sound node. The Sound node is similar to an audio player, but has some extended functionallity, like being able to play the sound it holds multiple times simultaneously, randomize pitch / volume or plays variations of your sound at random.
Sound has all properties that an AudioStreamPlayer has, plus the following properties:
singleton: bool- defines whether the sound should duplicated every time it's played or not
random_volume: float- limited to values between 1.0 - 2.0
- randomizes the volume of the sound every time it's played
streams: Array- if one or more streams are inside the
streamsarray, instead of playingstream, it will pick one stream insidestreamsat random to play. This is useful for variations in e.g. footsteps.
- if one or more streams are inside the
Sound2D Node
Same as Sound, but inherits from AudioStreamPlayer2D.
Can be played with SoundBooth.play2D()
Sound3D Node
Same as Sound, but inherits from AudioStreamPlayer3D, except it does not have random_volume.
Can be played with SoundBooth.play3D()
SoundBooth Node
The SoundBooth is where you manage your Sound nodes and play them. It also is really straight forward, it has only one function.
func play(sfx_name: String) -> void:sfx_namethe name of theSoundnode that shall be played.
func play2D(sfx_name: String, position := Vector2.ZERO) -> void:sfx_namethe name of theSoundnode that shall be played.positionwhere the sound should be played in 2D space.
func play3D(sfx_name: String, translation := Vector3.ZERO) -> void:sfx_namethe name of theSoundnode that shall be played.translationwhere the sound should be played in 3D space.
The SoundBooth automatically looks for all Sound nodes that are children to it and stores them.
To play it, simply call sfx_name() with the node name of the Sound you want to play!
It searches for Sound nodes recursively, so you can organize them in Node nodes if you want.
However it does not look for children of Sound nodes.
Personal Preference.
I like to create two Scenes with MusicBooth and SoundBooth as root node, call them Music and SFX and make them Singletons (autoloads). This way I have a single cental place to organice all my music and sfx, and can call them from any script in the game.
A Simple Adaptive Music & SFX Helper
Reviews
Quick Information
A Simple Adaptive Music & SFX Helper