So with our Feature Fragment 2 yesterday and Alpha turnin looming in less than a week the group is on high alert to get things into the game before Tuesday. The last 2 weeks for me have been devoted to using the brand spanking new XAudio2 API from Microsoft. A quick overview of what XA2 is, basically everyone on Windows who didn’t use FMOD, used DirectSound for their sound. This is a DirectX API and was fairly easy to use. On the XBox 360 XAudio was used by some. XA2’s reason is to replace both Direct Sound and XAudio and use one API to develop sound on both Windows and the XBox 360.
So the official release of XAudio2 was in the March 2008 SDK of DirectX. That being said it is a fairly new system with very little help and documentation on the internet, which has been a huge problem of mine finding people to help me with my bugs. Basically I have had to rely on my ability to read and understand the examples that XA2 shipped with and find ways to adapt it to what I needed in my game. So lets begin the tale of my XA2 experience.
So at GDC this year I sat in on Brian Schmidt’s presentation on XA2 and I immediately decided that I wanted to use it in my game. Not only because I became interested in audio programming but because I wanted the challenge of learning a brand new API on my own. So my journey began 2 weeks ago when I opened up the documentation for XA2 and began to develop a prototype engine for XA2. Getting XA2 initialized is actually simpler than I thought it was going to be. You create your IXAudio2 instance and your mastering voice. Basically the mastering voice serves as the final stage in creating sounds. Voices in XA2 are what your submit your sound buffers to and how you do mixing of sounds. The next step was coming up with a way to open and read .wav files. I first decided to get files loading straight into memory rather than streaming. The code examples for XA2 made this simple as they included a CWaveFile object that both opens and reads the wav. All you have to do is create a WAVEFORMATEX and get a hold of the information from the wav to fill this struct out. Once you have the data you can create a source voice and submit the buffer of sound to it. This was where I found my first problem. I thought that for every sound you loaded that you needed 1 source buffer. The problem that arose was when I would play a sound and then try to play another it would queue them up and not overlap like I intended. This was solved by me figuring out that its not every sound that you load that needs a source voice but every sound you want to play needs a source voice. Solving this problem allowed my soundFX to overlap and work correctly.
The next step to creating my engine was to get streaming audio to work. Basically streaming audio is when rather than loading the entire sound file into memory you read a smaller chunk into memory then when that is finished playing you read in another small chunk and continue until there are no more chunks to read. This seemed simple enough until I realized that in order to keep reading these chunks I was going to be stuck in a while loop, keeping me from doing anything else but reading sounds. This was very bad, but solvable by using multithreading. Now I had only had a small taste of multithreading before so this was a whole new challenge. Doing some researching on the web I was able to find a simple thread class that handled all of the initializing of the thread and all I had to do was overwrite the run function of the thread and pass the argument that I needed to it. Once this was accomplished I had my engine. I was ready to port it to my game….Or so I thought.
During the early stages of creating my prototype I read in one of the .h files I was inspecting that it required a Unicode build to work, essentially meaning that for XA2 to work it had to be in a Unicode build. I changed my build to Unicode and didn’t think twice about it. That was until I put it into our game which was a Multibyte build. I was at a loss for words. I thought there was going to be no way to use XA2. I asked around school and work and none of the teachers seemed to know of a way to get around this. Then the magic man him self Naveen told me that it was absolutely possible. By including my prototype project in our games project and having the XA2 engine build as a static library, I was able to build the XA2 engine in its own project with a Unicode build, then link in the functions to my game which was a Multibyte build. This turned out to be successful and as of right now we have streaming audio and working overlapping SFX in our build.
With Alpha coming up my XA2 engine will take a backseat for a week, but there is still work to be done. I need to figure out how to load XWMA’s. Right now we are using uncompressed .wav files which are HUGE!. Our installer alone right now is 112 MB because of the large sound files. A XWMA can turn a 30MB file into a 19k file so getting these into my game is important. I also want to attempt to get 3-D sound into our game as well as some sweet fade and other sound effects. Updates will come as I progress and expect to see more of the game next week after Alpha.