How to 3D sound in windows (hint: it’s not OpenAL)

So yesterday and today, I bit the bullet and started working on compiling the game for windows.  I wanted to do this before the project got too much further along so I didn’t write any code that would have serious implications on windows.  I must say, I’m amazed at how much trouble I didn’t have with the rendering system.  The levels/screens load up and look great!  I did have some issues with visual studio that I chalk up to lack of experience in windows dev on my part.  Namely getting the builds to be 64-bit instead of the default 32, SSE3 operator overload stuff, and getting debug builds to forego some of the extremely slow settings that make the engine run at a crawl.  Once I took care of all that, my little game was running on windows like a champ, complete with same stellar OpenGL 3.3 performance I get on mac.  All was well… that is except for one little tiny issue.  The sound.

One thing that became apparent almost right away was that OpenAL support on windows is in a terrible state.  Counting on it to just be there like OpenGL is a no no.. and installing your own via something like OpenAL soft gives pretty poor support.  I realized that I had to do something I’ve never done before, and that’s directly use a DirectX subsystem.  After some quick googling I discovered what I need can be done using a combination of xAudio2 and X3DAudio.  Both of these systems come with DirectX and the DX SDK so I was already set up to use em.

So basically, the plan on windows was pretty simple:  since I already have all my 3D sound calls abstracted out in my SoundManager class, I all I had to do is re-implement the stuff that OpenAL handled using this new xAudio2 stuff.. and pray that it played nice along side SDL_Mixer which I use for mp3 music.  More or less, things went relatively painless and I was able to find an xAudio2/X3DAudio analog for just about everything I was doing in OpenAL EXCEPT for a little issue I had with source playback.

On mac, I’m able to play a source overtop of itself as many times as I want to.  On windows, this seems to be a no-go.  So for win, I had to manually pre-allocate pools of sources for the sounds that I would be playing rapidly such as bullet ricochet sounds and typewriter keystrokes and ensure that I return an available source whenever I ask to play that sound.  That process more or less worked out just fine.

After all that, we have my reworked soundmanager class for windows.  The code is below for anyone who wants to learn from it.

All of the multiple source stuff is essentially handled by my inner MultiSource class which handles the souce pools for sounds that need em.  I found that I never needed more than 8 sources per sound.  I also had to add a new update3D method to update the 3D sound calculations and call it once every other frame or so (which wasn’t needed in OpenAL since it was done automatically).

Not shown here is a Wave class which essentially is a slightly modified version of the one from this tutorial.  That class basically handles wav file loading for me and manages the sound buffer data internally.  

That’s just about it.  Everything else was pretty straightforward.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>