10
Jun
Playing sound using OpenAL
Just a quick side note, the 6 Indie Games Bundle for $5 is still available till June 20th http://www.indiegamespack.com/, help out indie devs by buying or spreading the word.
For sound I use OpenAL, it’s free, cross-platform, I’ve managed to get it working on iPhone, Windows and Mac.
Setting up OpenAL to play a sound is pretty straight forward, a bit like OpenGL.
First you need to create a context.
ALCcontext *context; ALCdevice *device; device = alcOpenDevice(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); if (device == NULL) { // Handle Exception } //Create a context context=alcCreateContext(device,NULL); //Set active context alcMakeContextCurrent(context); // Clear Error Code alGetError();
Now for the second part, loading a wav file. You have to open a file, fill buffers with data and then attach it to a source.
char* alBuffer; //data for the buffer ALenum alFormatBuffer; //buffer format ALsizei alFreqBuffer; //frequency long alBufferLen; //bit depth ALboolean alLoop; //loop unsigned int alSource; //source unsigned int alSampleSet; //load the wave file alutLoadWAVFile("my_music.wav",&alFormatBuffer, (void **) &alBuffer,(unsigned int *)&alBufferLen, &alFreqBuffer, &alLoop); //create a source alGenSources(1, &alSource); //create buffer alGenBuffers(1, &alSampleSet); //put the data into our sampleset buffer alBufferData(alSampleSet, alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer); //assign the buffer to this source alSourcei(alSource, AL_BUFFER, alSampleSet); //release the data alutUnloadWAV(alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);
Once the sound is loaded we can play it. To do this we use alSourcePlay.
alSourcei(alSource,AL_LOOPING,AL_TRUE); //play alSourcePlay(alSource); //to stop alSourceStop(alSource);
Once you’ve finished don’t forget to clean memory and release OpenAL context and device
alDeleteSources(1,&alSource); //delete our buffer alDeleteBuffers(1,&alSampleSet); context=alcGetCurrentContext(); //Get device for active context device=alcGetContextsDevice(context); //Disable context alcMakeContextCurrent(NULL); //Release context(s) alcDestroyContext(context); //Close device alcCloseDevice(device);
Easy right? I’ve extended this to play the open format OGG for my engine, which is pretty cool. Since you can keep putting data to buffers you can stream a whole OGG or WAV file without loading everything into memory.

June 10th, 2011 at 12:50
Thanks! I’ve been having some trouble lately with my current audio library and considering a switch to OpenAL. These snippets will come in handy.
June 10th, 2011 at 19:24
I didn’t think the ALUT library, and hence alutLoadWAVFile(), existed on iOS. Am I mistaken, or did you port over its sources from another platform?
June 10th, 2011 at 19:31
The alut source code is on this link if I’m not mistaken http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx?RootFolder=%2Fopenal%2FDownloads%2FALUT&FolderCTID=&View={6A9700C6-7248-4CD2-83F5-268F2C176072}
June 11th, 2011 at 20:16
OK. In our “Core Audio” book, we’re telling people to use Audio File Services instead, though it’s obviously less convenient for the easy case than ALUT. We’re doing stuff like streaming, so we couldn’t have gotten far with alutLoadWAVFile() anyways.
Still, the reason ALUT isn’t available on iOS in the first place is that Creative deprecated it in 2005, so Apple presumably felt justified in leaving it out.
October 18th, 2011 at 17:32
For the iPhone OpenAL,
alcCreateContext(device, NULL);
part get memory leaks. Do you have any idea how to fix this?
October 18th, 2011 at 21:34
Are you using alcCloseDevice at the end?