Twitter  Facebook  Google+  YouTube  E-Mail  RSS
The One Man MMO Project
The story of a lone developer's quest to build an online world :: MMO programming, design, and industry commentary
An Audio System in 2321 Lines using OpenAL and Ogg Vorbis
By Robert Basler on 2012-01-20 17:03:10
Homepage: email:one at onemanmmo dot com

Getting Audio into the game is a huge leap forward. You don't realize how much sound adds until the first time your game boots with its theme music playing. There's a physical reaction to sound that is hard to ignore.

After a bit of research I came to the conclusion that the only free option for an audio middleware layer is OpenAL. If you have some money you might want to consider Miles or FMOD - they have a ton of functionality you won't need to build yourself.

I was kind of uneasy initially when I discovered that the OpenAL 1.1 Core SDK and the OpenAL Installer haven't been updated since 2009. Hello? Anybody home? As it turns out, OpenAL has continued to develop, but it is within the drivers and with the extensions. Like OpenGL, the core OpenAL API has an extension mechanism to add new stuff while the core API doesn't change. If you're at all uneasy with OpenAL, go check out the list of games that have shipped using OpenAL - there are a lot of big names there.

OpenAL gives you 3D sound positioning (with distance volume attenuation) with hardware mixing support on some audio cards and the ability to play many sound sources (with different sample rates) at once. If you have a Creative Labs sound card, apparently you get other fancy EAX features through extensions. I haven't looked into that at all.

My first thought for the game's audio file format was MP3 to save space, but MP3 is covered by patent and requires per-copy royalties. Instead I went with Ogg Vorbis. Here's a handy link to a page with all the developer downloads. LibOgg is the container file library and is used by LibVorbis which is the audio codec.

At some point I might add a straight WAV file loader. WAV files are fat, but I've been told that Ogg Vorbis is a little CPU intensive so I might need the additional performance. Once the Ogg files are loaded, they convert to PCM, so there is no memory savings for Ogg over WAV. Where Ogg really rocks is streaming music tracks which when stored as straight PCM are gigantic. In any case, I'm using Ogg for both music and sound effects now and it is working good. ( also has the Tremor decoder as an alternative to LibVorbis which is integer-only and should be faster.)

Integrating the libraries is pretty straightforward. OpenAL comes with an example of playing an Ogg Vorbis file with OpenAL, so that's a pretty handy source to crib from. I also stole aldlist.cpp and LoadOAL.cpp out of the OpenAL toolkit samples to get OpenAL going (only hiccup there was it doesn't support wide character builds out of the box.) Ogg supports replacing its file I/O routines with your own, so I was easily able to hook it into my existing asset management system's file I/O.

The big thing I didn't plan for in this was a result of the discovery that OpenAL can only handle a specific number of simultaneous sounds (sources) being played back. For the software driver the limit is 255, but hardware drivers can have 16 or even less. I'm expecting to have a lot of sources playing at once, so I ended up building a priority system which rates all the playing sounds by their priority (critical/high/medium/low) as well as their distance from the listener, and then only actually plays as many of the highest priority sounds as it can. Any sounds which are too low priority, or too far away, continue to advance but are not actually sent to OpenAL to play.

The other complication I added was a system to build sounds out of three components: an attack (start), a sustain (a loopable sound that can repeat in the middle) and the release (the end.) This lets me start a sound, play it as long as I need, then shut it down cleanly.

The last thing I needed to get going was a way to convert audio files to Ogg. My go-to conversion program is VLC but I found that 1.1.11 and previous versions have a sloppy bug. Converting WMA (from Windows Recorder) to OGG, VLC would cut off the last second or so, which kind of sucks for 1 second audio clips -- you get nothing for output. But if you check the version on that link, it is the latest build and they've improved things - apparently it only cuts off 40ms at the end now. I've been looking into other tools, it looks like Audacity might be better for this. Anyway, the TOOGG.BAT batch file to convert using VLC is below. Call it like:

TOOGG infile.wma outfile.ogg

if exist %2 goto theexit
"C:Program Files (x86)VideoLANVLCvlc.exe" --intf dummy -vvv "%1" --sout=#transcode{acodec=vorbis,ab=160,channels=2,samplerate=44100}:standard{access=file,mux=ogg,dst="%2"} vlc://quit

One problem I ran into was with ov_pcm_seek(). It turns out that calling ov_pcm_seek before every read results in static during playback. The funny thing though, is that it does this even if you are seeking to the current file position. I also read online that ov_pcm_seek is very slow.

If I try to stream more than one instance of a sound, I need to be able to seek within the shared asset file to do the reads. Not all Ogg files are seekable, so if the system tries to stream a second instance of a non seekable Ogg file, the system prints a warning in the trace and loads the file into memory. For seekable Ogg files, I also modified the Ogg reading code to keep track of the position within the Ogg file and only seek if it needs to. This way you can still stream more than one instance of a sound and if QA finds static in the audio, the programmer has a big clue in the debug trace where to look.

Getting this going took a week. Not too shabby.

New Comment

Cookie Warning

We were unable to retrieve our session cookie from your web browser. If pressing F5 once to reload this page does not get rid of this message, please read this to learn more.

You will not be able to post until you resolve this problem.

Comment (You can use HTML, but please double-check web link URLs and HTML tags!)
Your Name
Homepage (optional, don't include http://)
Email (optional, but automatically spam protected so please do)
What color is the ocean? (What's this?)

  Admin Log In

[The Imperial Realm :: Miranda] [Blog] [Gallery] [About]
Terms Of Use & Privacy Policy