Godot Version
4.4 stable
Question
I am attempting to crossfade between multiple synchronized music files played through a set of AudioStreamPlayer nodes. I want to maintain a consistent volume level during the transition.
The system I wrote mostly works, but I’m seeing inconsistent volume levels during the crossfade. I replaced my music tracks with a constant tone and recorded some transitions in Audacity to create this example volume diagram:
The crossfades are marked 1 through 8. I drew a crude graph below the recorded audio (A, B, C) to show an estimate of the volume of each of the three music tracks (measured in db).
The thing that’s driving me crazy is that (as far as I can tell) I’m calling the exact same custom function to apply a tween to the volume_db property of the AudioStreamPlayer nodes each time, but with different results. Sometimes the combined volume peaks a bit higher than one track alone, sometimes it dips down to almost nothing in the middle of the crossfade. It’s as though a random tween TransitionType is being applied instead of the one I want.
Is this a known bug in 4.4 or am I doing something wrong?
Here are the functions that perform the fades:
func layer_fade_to_db(layer:AudioStreamPlayer, new_db:float, duration:float):
var tween:Tween = create_tween().set_ignore_time_scale(true)
if layer.volume_db > new_db:
tween.tween_property(layer, "volume_db", new_db, duration).set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_QUART)
else:
tween.tween_property(layer, "volume_db", new_db, duration).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUART)
func layer_fade_stop(layer:AudioStreamPlayer, duration:float):
var tween:Tween = create_tween().set_ignore_time_scale(true)
tween.tween_property(layer, "volume_db", -80, duration).set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_QUART)
tween.tween_callback(layer.stop)
Here’s where those functions are called. I confirmed fade_time is always 2 seconds. Transitions 1, 3, 5, 7 are summer; 2, 4, 6, 8 are autumn:
mission.SEASON.SUMMER:
music_summer.volume_db = -80
music_summer.play(music_spring.get_playback_position())
layer_fade_to_db(music_summer, 0, fade_time)
layer_fade_stop(music_spring, fade_time)
mission.SEASON.AUTUMN:
music_autumn.volume_db = -80
music_autumn.play(music_summer.get_playback_position())
layer_fade_to_db(music_autumn, 0, fade_time)
layer_fade_stop(music_summer, fade_time)