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.

13 Comments

  1. 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. 🙂

  2. 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?

  3. 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.

  4. Yoon Lee

    For the iPhone OpenAL,

    alcCreateContext(device, NULL);
    part get memory leaks. Do you have any idea how to fix this?

  5. masnik

    how to use sound for my object(Entity) in my program (I am using Ogre)

  6. J Sunny

    Can you please tell me are the ‘Header files’, ‘.lib files’, ‘.dll files ‘ , that I need to include to use this code

  7. Subendra Sharma

    i can compile the file but the sound doesnt play help……..

    • Subendra Sharma

      in linux and i loaded the wav file manually…

  8. Pingback: iOS Project Log 2 – Stacie Arellano

Leave a Reply