Sound in XNA Game Studio / .NET
Introduction
As a follow-up to my XNA Game Studio Tutorial from Hugi #34, I'm now going to talk about how to include sound and music in your game with XNA Game Studio 2.0.
But first I must give you some information that was missing in the previous article. In Hugi #34, I wrote that if you want to enable other people to run your games coded with XNA Game Studio 2.0, you must ask them to download and install the following two files:
.NET Framework 2.0 Redistributable
XNA Framework Redistributable
That is correct, but it's sometimes not enough. There are also some other files required for running XNA 2.0 games, which are not shipped together with Windows. Depending on whether the user has Windows XP or Windows Vista, the list of necessary files is even different. Here's a (according to Aaron Stebner, one of the developers of XNA Game Studio) complete list of files that are required:
For Windows XP:
DirectX 9.0c
.NET 2.0 Servicepack 1
XNA Framework 2.0 Redistributable
For Windows Vista:
DirectX 9.0c
.NET Framework 3.5
XNA Framework 2.0 Redistributable
Only then will the game probably work. Note that it may be necessary to download DirectX 9.0c again even if some components of it are already installed - it's possible that not all the necessary components required for XNA are installed. Sorry for not mentioning this in the previous issue - I didn't know better. In some cases, e.g. when you use the networking library, it's even necessary that the user downloads and installs Visual C# Express Edition and the complete XNA Game Studio 2.0. For more information on that check out the FAQ in the forum at creators.xna.com.
But now let's come to our actual topic. There are several possibilities how you can include music in your game. One is to use the XACT (Cross-Platform Audio Creation Tool) which is included in the XNA Game Studio package. Another is to use an external library. Both ways have their advantages and disadvantages.
With XACT, you need not include any additional libraries to your project. The audio replay routines are included in the XNA framework. However, the big disadvantage is that you can only use WAV files. WAV files have an excellent sound quality, but they occupy quite a lot of space, depending on the length of the sound. Therefore they are more suitable for short in-game sounds and jingles than for the background music.
If you want to have only short sounds in your game, XACT is a good tool. If you want to include background music with a longer duration, it would be better to use a player that supports more compressed audio formats such as MP3. One of these players is Bass.Net, the .NET version of the well-known BASS ("Best Available Sound System") which also the Hugi engine is using.
I'll now talk about the usage of XACT. After that I'll tell the same things about Bass.Net.
XACT
XACT can be started from the Start menu. It's located in the "Microsoft XNA Game Studio 2.0" folder, subfolder "Tools". After starting you must click "File - New Project". Then you enter the filename the project should be stored as. I recommend storing it in the "Content" directory of your XNA game project because that's the place where all the data should be.
Now you must create a new wave bank. Right-click "Wave Banks" in the menu on the left and select "New Wave Bank". Two new windows open. In the right window, right-click and select "Insert Wave File(s)" (or press CTRL+W). Now you have to select the audio file(s) you want to include in your game. Only WAV and the similar formats AIF and AIFF are supported. Once the file is loaded, you must create a new Sound Bank. This is done in a similar way as creating the wave bank: Right-click "Sound Banks" in the menu on the left and select "New Sound Bank". Now you must drag the wave files from the Wave Bank into the new window that has just opened.
If you click the name of your sound below the "Sound Name" caption, you can select some options in the bottom-left window. What may be important is the loop count: You can either loop the sound zero, a positive number or an infinite number of times. This is especially important if you want to use XACT for background music since background music is usually looped an infinite number of times. (However, as explained above, I don't recommend using XACT for background music.)
Once you're done, save the project. To include the sounds in your game, enter Visual Studio. Right-click the line with the name of your project in the left part of the screen (the project explorer), select "Add", "Existing Element" and then open the file you've just created with XACT (it has the extension .xap).
Inside the Game1.cs file, you must declare the following variables:
AudioEngine audioEngine;
WaveBank waveBank;
SoundBank soundBank;
In the Initialize method, set up these variables with the following code (replace "filename" with the name of the file you created with XACT):
audioEngine = new AudioEngine("Content\\filename.xgs");
waveBank = new WaveBank(audioEngine, "Content\\Wave Bank.xwb");
soundBank = new SoundBank(audioEngine, "Content\\Sound Bank.xsb");
Then, at the position where you want to play a particular sound out of the sound bank, write (replace "Name of the sound" with the name of the sound you want to play):
soundBank.PlayCue("Name of the sound");
That's it for XACT.
Bass.Net
Now about Bass.Net: Bass.Net can be downloaded from http://www.un4seen.com/. In addition you must also download the actual BASS archive because you will need bass.dll.
Once you've downloaded everything, unpack the zip file with Bass.Net and run setup.exe. This will install Bass.Net in your Visual Studio environment.
In order to add music to your game, first of all copy the music file into the Content directory and copy bass.dll (from the original BASS archive, not from the BassNet archive) to the directory in which your executable will be stored (e.g. bin\debug). You then have to include a reference to Bass.Net in your project. This is done by right-clicking "References" in the project explorer (the second line) and then selecting Bass.Net. In Game1.cs, you write the following lines:
using Un4seen.Bass;
using Un4seen.Bass.Misc;
using Un4seen.Bass.AddOn.Wma;
Declare a variable called stream and let it be zero:
int stream = 0;
In the Initialize method, write (replace "filename.mp3" with the actual filename of your music):
if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero, null))
stream = Bass.BASS_StreamCreateFile("Content\\filename.mp3", 0, 0, BASSFlag.BASS_DEFAULT);
In order to start the music playback, write the following at the position where the music shall be played:
if (stream != 0)
Bass.BASS_ChannelPlay(stream, false);
That's it!
In order to get rid of the splash screen, you have to register your copy of Bass.Net at http://www.ten53.de/bass_register.html. Then you must write in your code:
BassNet.Registration("email address", "registration key");
Of course you have to replace "email address" and "registration key" with the actual data.
Instead of registering, you could of course also hack BassNet and find out how the registration key is computed from the email address, but I don't know how it's done. ;-)
Conclusion
Adding music to your game is easy, and with Bass.Net it won't even occupy much diskspace.
One last note: In the next version of XNA Game Studio (3.0), MP3 playback will be supported natively. So you won't need Bass.Net any more.