In this tutorial we will be looking at how you can make the volume of a sound effect vary, based on the distance between the emitter and the listener. This is called volume attenuation. In the previous tutorial we looked at how to do basic 3D audio effects by positioning. We will be using all of the stuff we learned in that tutorial during this tutorial, so if you haven't looked through it yet, go take a look!
A Little More About XACT
In order to better understand how attenuation will work, let's go back into XACT and learn a little bit more about how XACT works.
XACT was created mainly as a method for separating the programmer's job from the sound designer's job. We've already seen how the programmer can specify the location of the emitter and listener in an XNA game. How the distance effects the volume of a sound is really the sound designer's job, so we will need to make some changes to our XACT project in order to do this.
Go ahead and open your XACT project. If you look on the left side, in the project tree, you will see a section labeled 'Variables', as shown in the image below:
The variables in an XACT project allow it to determine various properties about how to play a sound. There are two types of variables. Global variables affect every cue that is being played. Cue Instance variables are unique to a particular cue. In the picture above you can see that there is one global variable, called SpeedOfSound, and four cue instance variables. NumCueInstances is just a count of the number of instances that a particular cue has at the moment. The other three are a little more interesting. One, in particular, is what we will use in this tutorial: Distance.
Each of these cue instance variables are set when you call the Cue.Apply3D() method. We just need to tell XACT how the variable should affect the sound cue that is being played.
Setting Up the Variable's Range
The first thing we need to do is define the variable's range. Since we want the volume to decrease with respect to the distance, we will do this with the Distance variable. So click on the Distance variable. A new control panel will appear towards the bottom of the left panel, as shown below.
In the new panel that appears, look for the section that says 'Variable Range', which is marked in the picture below:
We want to set the minimum and maximum values so that they are appropriate for our game world. Depending on the size of your game, this will vary, so pick whatever makes the most sense for your game. The units are in game units. So as an example, if in your game, 1 unit was equivalent to 1 meter, and you wanted to have the sound be completely silent if the object is 5000 meters away, then you would put in 0 and 5000 for your minimum and maximum values. These are the values that I will use for this tutorial, but feel free to put in whatever values suit your game best.
Creating an RPC (Runtime Parameter Control)
The next step that we need to do is to create an RPC (Runtime Parameter Control). An RPC tells XACT how to modify the sound, based on a particular variable. RPCs are pretty flexible, and you can accomplish quite a bit with them.
To create an RPC, click on the RPC Presets node in the project tree on the left, and select New RPC Preset as shown in the image below.
Doing this will create a new RPC node in the project tree, and will open a window like the one shown below:
We now need to tell the RPC what it should be associated with. Along the top is a series of drop down boxes that we will need to configure. In the Variable box, select Distance. In the Object box, choose Sound. And finally, in the Parameter box, select Volume. This will tell it to change the volume, based on the distance between the audio emitter and the listener.
The last thing we need to do for our RPC is to tell it how the distance should affect the volume. In the RPC window, you will notice a black graph area. In the graph area is a colored line, which is probably at the top by default. This tells XACT how distance should affect the sound's volume. You will see two points on the graph that you can drag around. You can also add more points to the line by double clicking on it. Move the points around to get the desired curve you want. Below is a screen shot of my finished RPC.
You can now close the RPC window. I'm also going to rename my RPC at this point, since the default name is pretty generic. You can do this by right clicking on the new RPC and selecting Rename. I've called mine 'Attenuation RPC'.
Apply the RPC to the Sound
The final thing that we need to do is tell our sound to apply the RPC. To do this, simply right click on the sound, and select 'Attach/Detach RPC…' from the menu, as shown in the image below.
Select the desired RPC from the list and press the 'Attach' button. The RPC will now appear as attached to the sound.
Everything is ready to go now, so save your project and run your game. Of course, in order to hear the attenuation, you will need to have the sound emitter at varying distances. If you are adding this to one of your own games, then you probably already have that. If you are simply following the tutorials, and you are working off of the code from the previous tutorial, you will need to change the distance of the emitter in your XNA project, since it was constant in the previous tutorial. You can accomplish this by adding one line of code to the update method:
distance += 0.1f;
This will change the location of the emitter to move farther and farther away, in addition to circling around the listener. So now if you run the code, you should be able to hear the sound getting quieter as time goes on.
In addition to volume attenuation, RPCs can be used for a variety of other things as well. From these tutorials, you've seen how powerful XACT can be. You know enough that you can do all sorts of things with your audio. I have a few other audio tutorials in my mind that I would like to put on here eventually, but for now, this is the final XACT audio tutorial. If you haven't already, you might want to take a look at the tutorial for playing .wma and .mp3 files in XNA. Otherwise, you might want to take a look at some of the other categories of XNA tutorials on this site.
|Having problems with this tutorial? Try the troubleshooting page!|