We are going to use libraries external to our own engine. So, we don't have to implement all the components of the video game's engine. The sound library is a very clear case in this kind of libraries. Basically, nowadays the video games industry uses two libraries for AAA video games, such as the FMOD library or the Audiokinetic WWise library, and then we find another library, OpenAL, which is also a multi-platform just like the previous ones. So, we can take our video game to other consoles or to other platforms apart from the computer, and it's the one we are going to use in our engine. So it is, obviously, an external library. This means we aren't going to need to implement the sound code on the sound card we have in our computer, or use the sound driver. We will use the library that encapsulates all this code. In aim to be able to use this library, we are going to use a class called CSoundManager, which will encapsulate the library, making it much easier to our daily use. So we will go to Visual Studio. We have our SoundManager class, which as we said before will encapsulate the OpenAL library. This SoundManager class will go to an XML file. So we derivate from XML Parser class to be able to read this XML file and we have the different methods we see here. Let's go to the CPP code to explain step by step what each method does. On one side, we have the SoundManager class builder, which initializes the member variables, SoundOn and Pause, and initializes the sound library, calling InitAL method, in line 9. Later we've got the SoundManager class debuilder which will just close the OpenAL sound library through the FinalizeAL method, in line 14. Upload method, which will load the XML file, will be the next. The methods SetGain and GetGain will establish the sound's volume we are going to use in our game in the OpenAL library. And GetGain will give us back the current volume. Reset will stop all the effects being currently reproduced and it will clean the sounds buffer we are going to use to reproduce our game's sounds. Pause will go through all the sound buffers we are reproducing and in case they are playing, it will pause them. As long as we want to pause them. In case we want to continue, to Resume, if they are paused, they will simply hit play. With the methods ALSourcePause, line 51, and ALSourcePlay, line 55. In the case of Stop, it will be very similar. We will go through the sounds that are being played buffers vector and in case the state is playing, it will stop this sound buffer. The onStartElement method is the method we will always use to parse XML files. So, to do so we are going to an XML sounds file we have here, Sounds.xml. And we have this XML file we have on the screen, in which each sound tag represents a sound effect. They have two attributes, Action, which tells us the sound's name and can be easily identified by the sound's name, and Path, which is the name of the place where the file can be found, in aim to be able to read the sound file. So, this is what we will read in onStartElement. In lines 79 and 80, it reads l_Action and the file name. If these names are different from empty, it loads the sound, line 95, and inserts it in the Buffers and in the Cargados file of the class. As we can see in lines 83 to 93, it's commented. We can delete this. PlayAction method is a method which allows us to play a sound effect in a 3D position. OpenAL will allow us to play surround sounds. To do this, we will need to define the camera's position, the direction where it is looking at, and the sound effects where they play. Also, we need to take into account that when we play a 3D sound, this sound must be in Mono, can't be in Stereo. This makes sense, as when we play a sound in a 3D environment, it has an origin and it isn't played by 2 or 4 speakers, it will be played in the speakers that the sound card considers correct, but from only one point, only one sound source in this case. PlayAction plays this sound effect, establishing in SourceID the sound and the position. So here we establish the Buffer's values, as well as the values of Pitch, Gain, volume, position, speed of the sound, which allows us to make effects, and the Looping state. In this case it will be False, as it can't be played continuously. And finally, we get to the ALSourcePlay method, in 119, which will play this sound. The PlayAction method, in line 124, which is what Action receives, is the one which will be used to play a sound effect. So, it simply receives the SourceName, the ActionName, which is the sound's name, it sets it and it finally calls line 129 to play this sound. Also, it will be a sound which won't make a loop, it won't be cyclic. CreateSource method simply calls GetSource and will give us back the SourceID inside the sounds buffer we have initialized in the beginning, when we created the engine. GetSource will stop the sound we tell it and empty or leave unseen the sound we are currently using. PlayRelativeSource will play a sound effect regarding the camera's position and it will do it either in Loop or no Loop method. With this we will be able to play sound effects taken from the camera. PlaySource will simply play a sound effect and it has the Loop state in case we want a cycle for the sound effect. We can use this one to play songs. We have, in Loop state, the variable, the Loop parameter activated. PauseSource will stop a sound effect we will use in the sound identifier, in the whole number inside our sound buffer. In case it's being played, it will pause it. In case it is paused it will Resume, it will unpause the sound. StopSource will be similar to the previous one, but in this case it will, in case it's being played, or if the sound is paused, it will try to stop it. Lines 255 and 256. GetSourcePosition method will establish the 3D position of a sound effect. We can start playing a sound effect in a certain position and make it move during the game. In example, let's imagine we shoot a projectile and this projectile is linked to a sound. So, while the projectile is moving we must move the sound source. And we can do it using GetSourcePosition. GetSourcePosition method gives us back the current position a sound has. SetSourceGain and GetSourceGain will give us back or set the volume a sound currently has. So, with these methods we could do a feeding and a fade out of the sound depending on the played time. SetListenerPosition and GetListenerPosition will set or give us back the Listener's 3D position, which is the element in which the sound must be heard. In our case it will be the camera, the camera's position which is the Player's position. SetListenerOrientation and GetListenerOrientation get InAt and InUp parameters. They simply determine where the camera or the Listener is looking at, and the Listener's vertical vector. This will allow the sound to play on one side or another depending on where we are looking at. And GetListenerOrientation gives us back the camera's Look, the place it's facing and the camera's Out vector, in this case the Listener. InitAl method simply initializes OpenAL's part, which is the classic initiation. In this case, it uses the standard OpenAL methods the library says we need to use in aim to initialize methods in it; and then we have FinalizeAL method, which will empty the buffers we have created here and it will destroy OpenAL library. Again the code is standard, it's what CBK's library says, what needs to be played. Then we have LoadSound method, to which we give a FileName, a filename and an exit buffer. That is, it loads the file and with this load it creates this file's buffer. The way the library is made now, the sound effects are completely loaded in the memory. We can do sound streaming with this library. But in this small implementation we have done in this engine, for this topic, we haven't implemented it. This can be implemented as well. Clear method will simply go through the buffers and empty them. It will delete all the sources we've created in the Buffers, depending on the Sources vector and it will empty all the lists we've created. GetSource method will check if there is any active source inside our vector. In case there is any vector we can use, we will give it back. Otherwise, we will add a new element inside the Sources vector and give this ID back. Finally, we have a support method in Book mode which will let us know in text mode the kind of error that has happened in a part of the OpenAL code, through the ALenum enumeration, ALenum-type, which sets the parameter. So, depending on the kind of enumeration we get, we give back a String-type value. For any info you wish to know, apart from the one we have already commented, you can enter in the OpenAL library, which can be found in Google. It's OpenAL.org. Here you have the web page in which you can find, on one side, in Downloads, the SDK, which is what we have downloaded to use, or WindowsInstaller which, if we unfold it, we see it has the install part the user has to make. And then we also have the documentation part, in which we will insert in PDF bot the specifications and a programmers' guide. As always, here we should use an external library, we have inside Properties>General, and we have on one side we have implemented the additional inclusion directories. We've included where it has to go to find OpenAL library, the headers and the H points. In our case, it's in ThirdParty/OpenAL/Include. And in Vinculador, we told it the same to find the OpenAL library. In this case, we also have the ThirdParty/OpenAL and there it will look for the library it needs. The sound part ends here.