Implementing 3D audio with FMOD
One of the great things about FMOD is its ability to play sounds in 3D space, internally handling all the details of panning, volume rolloff and Doppler effects without requiring too much trouble from the developer’s side. I’ve recently started adding sound effects to Tannhauser and I’d like to share with other people some of the problems I’ve had – perhaps it will save someone a bit of time.
Setting up the listener
The listener is the player’s “head” in 3D space. It is setup by calling set3DListenerAttributes() and receives a position, a velocity, as well as a forward and up vectors. However, make sure that the forward and up vectors are normalised: due to a bug in my code the forward vector hadn’t been normalised and it was causing the sounds to always play at full volume from both speakers.
3D sounds are initially placed at the listener
If a 3D sound is created without being set to start paused, it will begin playing at the listener’s location. Even if the sound’s 3D attributes are set immediately afterwards, you’ll likely still get a noticeable “pop” as the sound starts playing and gets relocated.
To avoid this, create the sound as initially paused, set the attributes and then unpause it.
Minimum sound instance distance
Setting the minimum distance on a channel allows us to define how audible the sound is as you get further away from it. Something I am currently playing with, however, is having different minimum distances for the player and for other ships, making the player’s actions more noticeable in the chaos of battle.
Too many active sounds
There are explosions in Tannhausers. Lots of explosions. On a bad day, there are over fifteen ships all flinging large amounts of missiles, torpedoes and other fun things at each other, potentially creating hundreds of sound instances within a couple of seconds. This both makes the game very noisy and makes the CPU fairly unhappy at having to handle that many simultaneous instances.
The current solution is to prevent sounds of the same type (e.g. the same explosion resource) from generating a new instance more than once every 100ms. This still makes it sound like there is a great deal going on, while preventing an excessive number of instances. This is also helped by each sound effect having a short duration.
Audacity is a great free program to play a bit with sound effects, which is something I’ve been wanting to do for a while. Other than modifying the sound to generate variants of a sound (such as the “missile launched” sound being used as source for the “torpedo launched” and “rocket launched” effects), it also allows for sounds to be trimmed in order to remove any silence at the beginning or at the end of the sound.