Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## Script for the AudioManager singleton
- extends Node
- ## Volume of Master bus (0.0 -> 1.0, affects all other busses)
- var vol_Master: float:
- set(volume): vol_Master = __set_bus_volume(__idx_Master, volume)
- ## Volume of User Interface SFX bus (0.0 -> 1.0)
- var vol_UI: float:
- set(volume): vol_UI = __set_bus_volume(__idx_UI, volume)
- ## Volume of DSP Effects bus (0.0 -> 1.0, affects Music and SFX busses)
- var vol_DSP: float:
- set(volume): vol_DSP = __set_bus_volume(__idx_DSP, volume)
- ## Volume of Music bus (0.0 -> 1.0)
- var vol_Music: float:
- set(volume): vol_Music = __set_bus_volume(__idx_Music, volume)
- ## Volume of Sound Effects bus (0.0 -> 1.0)
- var vol_SFX: float:
- set(volume): vol_SFX = __set_bus_volume(__idx_SFX, volume)
- ## Plays a non-spatial, oneshot sound effect
- func play_sfx(stream:AudioStream, volume:float = 1.0) -> void:
- var player := AudioStreamPlayer.new()
- player.bus = &"SFX"
- player.stream = stream
- player.volume_linear = vol_Master * vol_SFX * volume
- add_child(player)
- player.play()
- # Notes for this (in the future, double check if this info is correct):
- # AudioStreamOggVorbis [*] Works as expected
- # AudioStreamWAV [*] Works for non-looping WAVs
- # AudioStreamMP3 [*] Works as expected
- # AudioStreamRandomPitch/AudioStreamPlaylist [*] Emits after last entry
- # AudioStreamGenerator [ ] Infinite stream, never "finishes"
- # AudioStreamPolyphonic [ ] Manages multiple sources
- '''
- player.finished.connect(player.queue_free)
- '''
- # Potential improvement?
- var duration := player.stream.get_length()
- get_tree().create_timer(duration).timeout.connect(player.queue_free)
- func play_music(stream:AudioStream, fade_time_seconds:float = 1.0) -> void:
- # If same track is already playing, return early
- if __player_Music.stream == stream and __player_Music.playing: return
- # If a track is already playing, fade-out before playing the next track
- if __player_Music.playing:
- if __tween_Music: __tween_Music.kill()
- __tween_Music = get_tree().create_tween()
- __tween_Music.set_trans(Tween.TRANS_SINE)
- __tween_Music.set_ease(Tween.EASE_IN_OUT)
- # Set fade-out tween
- __tween_Music.tween_property(__player_Music, "volume_db", __MUSIC_DB_MIN, fade_time_seconds)
- # 'Fade-in and switch track' is called after fade-out
- __tween_Music.tween_callback(Callable(self, "__switch_music_track").bind(stream, fade_time_seconds))
- # Otherwise, simply fade-in
- else:
- __switch_music_track(stream, fade_time_seconds)
- #region Overrides and Signals
- #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
- func _ready() -> void:
- # This should be redundant, but just in case
- __clear_all_busses()
- # Set up busses
- __idx_UI = __append_bus(&"UI")
- __idx_DSP = __append_bus(&"DSP")
- __idx_Music = __append_bus(&"Music", &"DSP")
- __idx_SFX = __append_bus(&"SFX", &"DSP")
- # Initialize volumes (should invoke their setter functions)
- vol_Master = 1.0
- vol_UI = 1.0
- vol_DSP = 1.0
- vol_Music = 1.0
- vol_SFX = 1.0
- # Set up music player
- __player_Music = AudioStreamPlayer.new()
- __player_Music.bus = &"Music"
- # (Technically, it's not necessary to add this as a child, given that this
- # is an autoload script, and there's only one instance of __player_Music,
- # that's created the moment the game runs. However, there's not much of a
- # reason *not* to either, and it's idiomatic to do so anyway.)
- add_child(__player_Music)
- #endregion Overrides and Signals
- #region Internals
- #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
- ## Used to sync relevant resource accesses if multithreading is eventually added
- #var __mutex := Mutex.new()
- ## Added for consistency, since this is always 0
- const __idx_Master: int = 0
- ## Bus index for user interface sounds (should ignore DSP effects, and is sent straight to Master)
- var __idx_UI: int
- ## Bus index for the DSP (Digital Signal Processing) audio effects' send bus.
- ## While both Music and SFX are sent to this bus, its usage may be limited, given
- ## that its main purpose is for applying effects that affect both Music and SFX.
- var __idx_DSP: int
- ## Bus index for music; output is sent to DSP
- var __idx_Music: int
- ## Bus index for sound effects; output is sent to DSP
- var __idx_SFX: int
- ## The decibel level that music fades in from, and fades out to
- const __MUSIC_DB_MIN: float = -80.0
- ## Used for tweening music fade ins/outs
- var __tween_Music: Tween
- ## The stream player used for music
- var __player_Music: AudioStreamPlayer
- ## Removes all busses except for Master (which can't be removed anyway),
- ## as well as removing any effects from Master.
- func __clear_all_busses() -> void:
- # Remove busses
- while AudioServer.bus_count > 1:
- AudioServer.remove_bus(AudioServer.bus_count-1)
- # Remove effects
- while AudioServer.get_bus_effect_count(__idx_Master) > 0:
- var last_effect_index: int = AudioServer.get_bus_effect_count(__idx_Master)-1
- AudioServer.remove_bus_effect(__idx_Master, last_effect_index)
- ## Appends a bus to the list, with an optional bus to send to (i.e. target)
- func __append_bus(bus_name:String, send_name:StringName = &"Master") -> int:
- # Will be equal to bus_count-1 after adding the new one
- var new_index: int = AudioServer.bus_count
- AudioServer.add_bus()
- AudioServer.set_bus_name(new_index, bus_name)
- AudioServer.set_bus_send(new_index, send_name)
- return new_index
- func __set_bus_volume(bus_index:int, volume:float) -> float:
- volume = clampf(volume, 0.0, 1.0)
- AudioServer.set_bus_volume_linear(bus_index, volume)
- return volume
- func __switch_music_track(stream:AudioStream, fade_in_seconds: float) -> void:
- __player_Music.stop()
- __player_Music.stream = stream
- __player_Music.volume_db = __MUSIC_DB_MIN # Set decibels to this initially
- __player_Music.play()
- if __tween_Music: __tween_Music.kill()
- __tween_Music = get_tree().create_tween()
- __tween_Music.set_trans(Tween.TRANS_SINE)
- __tween_Music.set_ease(Tween.EASE_IN_OUT)
- __tween_Music.tween_property(__player_Music, "volume_db",
- linear_to_db(1.0), fade_in_seconds)
- #endregion Internals
- # TODO:
- # add dsp effects
- # (EOF)
Advertisement
Add Comment
Please, Sign In to add comment