76 lines
2.3 KiB
GDScript
76 lines
2.3 KiB
GDScript
class_name AudioFader extends Node
|
|
## Controls an AudioStreamPlayer and allows for fading and crossfading.
|
|
|
|
## Audio fade-out target.
|
|
const AUDIO_FADE_MIN_VOLUME: float = -20.0
|
|
## Default audio transition time.
|
|
const DEFAULT_AUDIO_FADE: float = 1.0
|
|
|
|
## Audio bus.
|
|
@export var bus: StringName
|
|
|
|
## Current AudioStreamPlayer.
|
|
var player: AudioStreamPlayer = null
|
|
## Current TweenChannel.
|
|
var tween_channel: TweenChannel = null
|
|
|
|
## Creates an initial AudioStreamPlayer child and TweenChannel.
|
|
func _ready() -> void:
|
|
_create_members()
|
|
|
|
## Creates an AudioStreamPlayer child and TweenChannel.
|
|
func _create_members() -> void:
|
|
player = AudioStreamPlayer.new()
|
|
add_child(player)
|
|
tween_channel = TweenChannel.make_replacing()
|
|
|
|
## Fades in the current audio player.
|
|
func fade_in(stream: AudioStream, fade: float = DEFAULT_AUDIO_FADE) -> void:
|
|
await fade_out()
|
|
player.stream = stream
|
|
if player.stream:
|
|
player.volume_db = AUDIO_FADE_MIN_VOLUME
|
|
player.play()
|
|
var tween := await tween_channel.create_tween(player)
|
|
tween.tween_property(player, ^'volume_db', 0.0, fade)
|
|
await tween_channel.sync(tween)
|
|
|
|
## Fades out an arbitrary audio player on an arbitrary tween channel.
|
|
static func _fade_out_foreign(
|
|
p_player: AudioStreamPlayer,
|
|
p_tween_channel: TweenChannel,
|
|
fade: float = DEFAULT_AUDIO_FADE
|
|
) -> void:
|
|
if p_player.playing and p_player.volume_db > AUDIO_FADE_MIN_VOLUME:
|
|
var tween := await p_tween_channel.create_tween(p_player)
|
|
tween.tween_property(
|
|
p_player, ^'volume_db', AUDIO_FADE_MIN_VOLUME, fade
|
|
)
|
|
await p_tween_channel.sync(tween)
|
|
p_player.stop()
|
|
|
|
## Fades out the current audio player.
|
|
func fade_out(fade: float = DEFAULT_AUDIO_FADE) -> void:
|
|
await AudioFader._fade_out_foreign(player, tween_channel, fade)
|
|
|
|
## Plays audio without fading in.
|
|
func play(stream: AudioStream) -> void:
|
|
await player.fade_out()
|
|
player.stream = stream
|
|
if player.stream:
|
|
player.volume_db = 0.0
|
|
player.play()
|
|
|
|
## Fades out old audio and fades in new audio at the same time.
|
|
func crossfade(stream: AudioStream, fade: float = DEFAULT_AUDIO_FADE) -> void:
|
|
var old_player := player
|
|
var old_tween_channel := tween_channel
|
|
var thunk := func() -> void:
|
|
await AudioFader._fade_out_foreign(old_player, old_tween_channel, fade)
|
|
old_player.queue_free()
|
|
_create_members()
|
|
await Wait.until(player.is_node_ready)
|
|
var task := Task.new(thunk)
|
|
await fade_in(stream, fade)
|
|
await task.sync()
|