Game Development Reference
Audio in 3D
Each sound that we've used so far has been played at full volume (assuming that we haven't
altered the volume with SoundSource::setVolume() ). In other words, they weren't
spatialized. In this section, we will talk about how to place sounds in the world so that they
are played relative to a sound listener (the main character, for example). By doing this, we
can simulate a realistic sound environment, where, if something explodes on our character's
left, we hear the explosion only in our left speaker.
Before we go any further, it is important to note that a sound can be spatialized only if it
has a single channel (a mono sound). Spatializing sources with multiple channels makes
little sense since they explicitly define how to use the speakers.
Creating a sound environment requires two things: someone or something to play the
sounds and someone or something to listen to them. In the previous sections of this chapter,
we talked about how to play sounds and music. However, those sounds were not spatialized
and thus did not require a listener—they just played at full volume in the speakers. If we
want to place them in a world and create a realistic environment, we have to set up a listen-
er who actually has the ability to hear them. This enables features such as sound direction
and attenuation when the sound is played.
Setting up the listener
At any moment in our program's execution, we need (and have) only one listener for, hear-
ing sounds. SFML provides a static class to manipulate the audio listen-
er— sf::Listener . The listener has three properties which we can manipu-
late—position, orientation, and global volume.
The position of a listener is set by calling Listener::setPosition() . This function
takes a three-dimensional vector because SFML doesn't assume that we are building a flat
game. If we are building a 2D game though, our world would be flat and we wouldn't need
all three axes. We can use the conventional x and y axes and leave z = 0 everywhere. We
don't have to use this convention but, in most cases, following these conventions brings be-
nefits—people understand the code and common examples are more relevant.
So, if we were to have a sprite as our main character, we would have to set the listener's po-
sition to the sprite's position each time it moves: