How SFML handles spatialization

SFML has a number of functions that allow us to handle emitters, attenuation, and listeners. Let's take a look at them hypothetically, and then we will write some code to add spatialized sound to our project for real.

We can set up a sound effect ready to be played, as we have done so often, as follows:

// Declare SoundBuffer in the usual way 
SoundBuffer zombieBuffer; 
// Declare a Sound object as-per-usual 
Sound zombieSound; 
// Load the sound from a file like we have done so often 
zombieBuffer.loadFromFile("sound/zombie_growl.wav"); 
// Associate the Sound object with the Buffer 
zombieSound.setBuffer(zombieBuffer); 

We can set the position of the emitter using the setPosition function, as shown in the following code:

// Set the horizontal and vertical positions of the emitter 
// In this case the emitter is a zombie 
// In the Zombie Arena project we could have used  
// getPosition().x and getPosition().y 
// These values are arbitrary 
float x = 500; 
float y = 500; 
zombieSound.setPosition(x, y, 0.0f); 

As suggested in the comments of the previous code, how exactly you obtain the coordinates of the emitter will probably be dependent upon the type of game. As shown in the previous code, this would be quite simple in the Zombie Arena project. We will have a few challenges to overcome when we set the position in this project.

We can set the attenuation level using the following code:

zombieSound.setAttenuation(15); 

The actual attenuation level can be a little ambiguous. The effect that you want the player to get might be different from the accurate scientific formula used to reduce the volume over distance based on attenuation. Getting the right attenuation level is usually achieved by experimenting. Generally speaking, the higher the level of attenuation, the quicker the sound level reduces to silence.

Also, you might want to set a zone around the emitter where the volume is not attenuated at all. You might do this if the feature isn't appropriate beyond a certain range, or you have a large number of sound sources and don't want to overdo the feature. To do so, we can use the setMinimumDistance function, as shown here:

zombieSound.setMinDistance(150); 

With the previous line of code, attenuation would not begin to be calculated until the listener is 150 pixels/units away from the emitter.

Some other useful functions from the SFML library include the setLoop function. This function will tell SFML to keep playing the sound over and over when true is passed in as a parameter, as demonstrated by the following code:

zombieSound.setLoop(true); 

The sound will continue to play until we ended it with the following code:

zombieSound.stop(); 

From time to time, we will want to know the status of a sound (playing or stopped). We can achieve this with the getStatus function, as demonstrated in the following code:

if (zombieSound.getStatus() == Sound::Status::Stopped) 
{ 
   // The sound is NOT playing 
   // Take whatever action here 
} 
 
if (zombieSound.getStatus() == Sound::Status::Playing) 
{ 
   // The sound IS playing 
   // Take whatever action here 
} 

There is just one more aspect of using sound spatialization with SFML that we need to cover. Where is the listener? We can set the position of the listener with the following code:

// Where is the listener?  
// How we get the values of x and y varies depending upon the game 
// In the Zombie Arena game or the Thomas Was Late game 
// We can use getPosition() 
Listener::setPosition(m_Thomas.getPosition().x,  
   m_Thomas.getPosition().y, 0.0f); 

The preceding code will make all sounds play relative to that location. This is just what we need for the distant roar of a fire tile or incoming zombie, but for regular sound effects such as jumping, this is a problem. We could start handling an emitter for the location of the player, but SFML makes things simple for us. Whenever we want to play a normal sound, we simply call setRelativeToListener, as shown in the following code, and then play the sound in the exact same way we have done so far. Here is how we might play a normal, un-spatialized jump sound effect:

jumpSound.setRelativeToListener(true); 
jumpSound.play(); 

All we need to do is call Listener::setPosition again before we play any spatialized sounds.

We now have a wide repertoire of SFML sound functions and we are ready to make some spatialized noise for real.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.109.4