Crossfade Background Music

beginner

By: Henrique Campos - July 17, 2020

In the background music tutorial, we saw how to keep the music playing when transitioning between game levels or screens.

What if we want to transition between two soundtracks smoothly? In this tutorial, you’ll learn to crossfade two music tracks smoothly.

Setting up the scene

To achieve a crossfade effect in Godot, we need two AudioStreamPlayer nodes, one for each music track. Create a new scene with a node named BackgroundMusic. Add two AudioStreamPlayer and an AnimationPlayer node as its children. I’ve called the stream players Track1 and Track2. Leave them without a stream and set them to not autoplay as we will control them from BackgroundMusic’s script.

Crossfade background music scene structure

Let’s start with the crossfade animations. We need two, respectively, to fade from track one to track two and vice-versa.

Animate the Volume dB property of the audio tracks. One Node should animate from 0.0 to -80.0 dB, and the other from -80.0 to 0.0. For the track that ends the animation at -80.0 dB, add a track and keyframe that sets its Playing property to false.

Here is my animation FadeToTrack1:

Animation fading from track two to track one

And FadeToTrack2:

Animation fading from track one to track two

Note that you need to change the easing on the animation keys at the start of the animation. Because audio volume follows a logarithmic scale, linear interpolation will cause the music to fade out in a split second. Instead, we want them to blend for a moment.

Using a non-linear audio easing

One curve should ease in, as on the image above, and the other ease out.

Coding the crossfade

We need some code to play music and automatically fade from one track to the other. Internally, our BackgroundMusic Node should toggle between the two audio stream players. From the user’s perspective, all we want is to call a function and let the fade happen magically.

Attach a script to BackgroundMusic and add the following code to it.

extends Node

# References to the nodes in our scene
onready var _anim_player := $AnimationPlayer
onready var _track_1 := $Track1
onready var _track_2 := $Track2


# crossfades to a new audio stream
func crossfade_to(audio_stream: AudioStream) -> void:
	# If both tracks are playing, we're calling the function in the middle of a fade.
	# We return early to avoid jumps in the sound.
	if _track_1.playing and _track_2.playing:
		return

	# The `playing` property of the stream players tells us which track is active. 
	# If it's track two, we fade to track one, and vice-versa.
	if _track_2.playing:
		_track_1.stream = audio_stream
		_track_1.play()
		_anim_player.play("FadeToTrack1")
	else:
		_track_2.stream = audio_stream
		_track_2.play()
		_anim_player.play("FadeToTrack2")

You can use the script above by adding BackgroundMusic as an autoload in your project and calling BackgroundMusic.crossfade_to(). Note that the function takes an AudioStream.

Made by

Our tutorials are the result of careful teamwork to ensure we produce high quality content. The following team members worked on this one:

Henrique Campos

Tutor

Nathan Lovato

Founder

Related courses

Banner image

Godot Node Essentials 60$

Learn to create professional 2D games with the Godot game engine.

Banner image

Ultimate Godot course bundle 295$

This ultimate bundle gives you access to ALL our current and future Godot courses, at a discount. It’s like a lifetime membership.

Related tutorials

No questions yet

Got a question or feedback regarding this guide?
Please use the form below.

Enter your email to get notified when someone replies to your comment.
We encrypt your addres with a strong 256-bit AES encryption.
We'll only use your address for notifications. You can unsubscribe anytime.