DevMaster.net Forums
[[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]]

Go Back   DevMaster.net Forums > Site Discussions > Articles Discussion
User Name
Password
Register FAQ Members List Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 06-07-2003, 11:32 PM   #1
cardinals33
New Member
 
Join Date: May 2003
Posts: 2
Default

<html><h1 align="center">Programming 3D Sound With OpenAL</h1><p align="center">By: Dan Ricart </p>

As the capabilities of sound cards and sound APIs have increased over the years, 3D sound has played an increasingly important role in games. Creating an immersive experience for the gamer goes beyond nice looking graphics. Done correctly, ambient sound and music can take games to a whole new level. To achieve this effect, different sound programming APIs have been developed such as Microsoft's DirectSound and DirectSound3D, Aureal's A3D and Creative Labs EAX. More recently, Loki Entertainment and Creative Labs have developed OpenAL. They have done this in an effort to create a more standard, cross-platform API to allow developers to add sound to any title. This article explains the basics of OpenAL and how to get started adding 3D sound to your project.</p>

OpenAL is basically an audio library that contains functions for playing back sounds and music in a game environment. It allows a programmer to load whatever sounds they like and control certain characteristics such as position, velocity, direction and angles for cones that determine how the sound is traveling. All sounds are positioned relative to the listener which represents the current place in the game universe where the user is. The closer the listener gets to a sound, the louder it gets. OpenAL can also be used for the playback of music. OpenAL can make use of streaming to continuously play music back in the background. OpenAL supports the use of DirectSound3D and EAX. There are functions contained in the library that allow the use of these APIs without any extra programming.</p>

The main advantage of OpenAL over DirectSound and EAX is that OpenAL is designed to be a cross platform API. It is possible to download Windows, Mac and
Linux binaries of it so it can be used on many Operating Systems. DirectSound and DirectSound3D were designed only for Windows and EAX is basically an extension of DirectSound3D. For those wishing to create an application for multiple Operating Systems, OpenAL might be the way to go. This tutorial is designed to show you how to get basic functionality out of OpenAL in Windows. The code shown here is from the demo application that you can download which contains the complete example. OpenGL is used for the rendering so the demo
shows some similarities between OpenGL and OpenAL. </p>

Getting Started</p>


The first thing to do is to obtain the OpenAL SDK. This can be obtained from Creative Labs developer site at [url=http://developer.creative.com]. Once the SDK is set up you can begin using its functions. You will first need to initialize OpenAL at the start of your game or application. For my application I have chosen to use DirectSound3D but it is also possible to make use of EAX. The initialization code looks like this:</p>
<p class="codeNormal"><span class="codeNormal">ALCcontext *Context;
ALCdevice *Device;
Device = alcOpenDevice((ALubyte*)"DirectSound3D");
</span><span class="codeKeyword">if</span><span class="codeNormal"> (Device == NULL)
*** exit(-1);</span></p><p class="codeComment"><span class="codeComment">//Create context(s)
</span><span class="codeNormal">Context=alcCreateContext(Device , NULL);
</span><span class="codeComment">//Set active context
</span><span class="codeNormal">alcMakeContextCurrent(Context);
</span><span class="codeComment">// Clear Error Code
</span><span class="codeNormal">alGetError();</span></p>

Loading Sounds</p>


Once OpenAL has been initialized you can start filling buffers with sounds. The first step is to fill a buffer with sound using the <span class="codeNormal">alutLoadWAVFile</span> function. Once you have filled the buffer you need to attach it to a source. This source can then be used to play back the sound. The code for loading a sound looks like this:</p>

<span class="codeKeyword">char</span><span class="codeNormal">* alBuffer;**** *******</span><span class="codeComment">//data for the buffer</span><span class="codeNormal">
ALenum alFormatBuffer;**** </span><span class="codeComment">//for the buffer format</span>
<span class="codeNormal">ALsizei alFreqBuffer;***** </span><span class="codeComment">//for the frequency of the buffer</span><span class="codeNormal"></span>
<span class="codeKeyword">long </span><span class="codeNormal">alBufferLen;********* </span><span class="codeComment">//the bit depth</span><span class="codeNormal">
ALboolean alLoop;********* </span><span class="codeComment">//looped</span>
<span class="codeNormal"></span><span class="codeKeyword">unsigned int</span><span class="codeNormal"> alSource;**** </span><span class="codeComment">//buffer source</span><span class="codeNormal">
</span><span class="codeKeyword">unsigned int</span><span class="codeNormal"> alSampleSet; </span></p>

<span class="codeComment">//load the wave file
</span><span class="codeNormal">alutLoadWAVFile("test.wav",&alF ormatBuffer, (</span><span class="codeKeyword">void</span><span class="codeNormal">**) &alBuffer,(</span><span class="codeKeyword">unsigned int</span><span class="codeNormal"> *)&alBufferLen, &alFreqBuffer, &loop);

</span><span class="codeComment">//create 1 source
</span><span class="codeNormal">alGenSources(1, &alSource);

</span><span class="codeComment">//create 1 buffer
</span><span class="codeNormal">alGenBuffers(1, &alSampleSet);

</span><span class="codeComment">//fills sample set with buffer data from alBuffer
</span><span class="codeNormal">alBufferData(alSampleSet, alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);

</span><span class="codeComment">//assign the buffer to this source
</span><span class="codeNormal">alSourcei(alSource, AL_BUFFER, alSampleSet);

</span><span class="codeComment">//release the data
</span><span class="codeNormal">alutUnloadWAV(alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);</span></p>

The first step here was to load the file "<span class="codeNormal">test.wav</span>". The data is read in and stored in <span class="codeNormal">alBuffer</span>. Next a source and a buffer are created. Then the buffer is filled with data from<span class="codeNormal">alBuffer</span>. Next the buffer is assigned to the source and the wave data is released.</p>

Setting Source Properties</p>


Once you have a sound source set up you will need to set some of its properties. To do this you use the <span class="codeNormal">alSource</span> command. This function works similar to functions in OpenGL where different versions of the function exist such as <span class="codeNormal">alSourcei</span>,<span class="codeNormal">alSourcef</span>, <span class="codeNormal">alSource3f</span>, and so on. The properties you are setting determine which function you use. Setting something like pitch for example just needs one floating point parameter so <span class="codeNormal">alSourcef</span> is used. The first parameter passed to the function is that of the source you are modifying. The second parameter corresponds to what property you are changing. The rest of the parameters are the actual settings for this property. Here is an example of setting position and velocity for a sound source:</p>

<span class="codeComment">//set source position</span>
<span class="codeNormal">alSource3f(alSource,AL_POSITION , xposition, yposition, zposition);

</span><span class="codeComment">//set source velocity
</span><span class="codeNormal">alSource3f(alSource,AL_VELOCITY , xvelocity, yvelocity, zvelocity);</span></p>

Here <span class="codeNormal">alSource</span> is our sound source and<span class="codeNormal">AL_POSITION</span> and <span class="codeNormal">AL_VELOCITY</span> signal that we want to change the position and velocity parameters. The rest correspond to floating point numbers with preset values.</p>

Using a Listener</p>


The use of a listener in 3D sound is important so that you have a reference point from which to hear sounds. The closer a listener is to a sound source's position, the louder the sound will get provided there are no obstacles. OpenAL already has a listener object set up so all you need to do is modify its properties as needed. The most important properties of the listener are the position and orientation of the listener. These properties are generally updated once for every loop in a game. The position indicates where the listener currently is while the orientation is where the listener is facing. For example, if a listener is facing west and a sound is coming from the north, the sound will appear to come from the right. However if the user orientation changes and turns to face the north, the sound will now appear to come from straight ahead.</p>

Modifying a listener's properties works similarly to the way you change a sound source's properties. The function <span class="codeNormal">alListener</span> is used and has variations depending on the property you are modifying. For example, to set the listener position you can call alListener3f and specify 3 separate floating point numbers or you could call <span class="codeNormal">alListenerfv</span> and pass an array of floating point numbers. The parameters for the position are simply the x, y and z values for the listener in the game world. The orientation property however takes 6 parameters. The first 3 are for the vector that corresponds to what the user of listener is currently looking at. The next 3 are for the vector leading straight up from where the listener is facing. Here is an example of setting the listener position and orientation:</p>


<span class="codeKeyword">float</span><span class="codeNormal"> listenerx, listenery, listenerz;
</span><span class="codeKeyword">float</span><span class="codeNormal"> vec[6];

listenerx=10.0f;
listenery=0.0f;
listenerz=5.0f;

vec[0] = fvecx; </span><span class="codeComment">//forward vector x value</span><span class="codeNormal">
vec[1] = fvecy; </span><span class="codeComment">//forward vector y value</span><span class="codeNormal">
vec[2] = fvecz; </span><span class="codeComment">//forward vector z value</span><span class="codeNormal">
vec[3] = uvecx; </span><span class="codeComment">//up vector x value</span><span class="codeNormal">
vec[4] = uvecy; </span><span class="codeComment">//up vector y value</span><span class="codeNormal">
vec[5] = uvecz; </span><span class="codeComment">//up vector z value</span></p>

<span class="codeComment">//set current listener position
</span><span class="codeNormal">alListener3f(AL_POSITION, listenerx, listenery, listenerz);

</span><span class="codeComment">//set current listener orientation
</span><span class="codeNormal">alListenerfv(AL_ORIENTATION, vec);</span></p>

In the first function call, 3 separate floating point numbers were passed for the x, y and z of the listener's position. For the second call, an array called <span class="codeNormal">vec</span> is passed. This array is comprised of the six values for the two vectors dealing with the listener's orientation.</p>

Playing Sounds</p>

Once your sounds are loaded and you have set your listener properties you can then play your sounds. To do this you call the function <span class="codeNormal">alSourcePlay</span>. This function takes a single parameter which is the source you want to play. To stop a sound you call the function <span class="codeNormal">alSourceStop</span> which also takes the name of the source you want to stop. If you want your sound effect to loop such as if you have a sound of running water, you can set the looping property of the sound to true before playing the sound. Here is some sample code:</p>

<span class="codeComment">//tell the sound to loop continuously
</span><span class="codeNormal">alSourcei(alSource,AL_LOOPING,A L_TRUE);

</span><span class="codeComment">//play the sound
</span><span class="codeNormal">alSourcePlay(alSource);</span></p>

To stop the sound:</p>

<span class="codeNormal">alSourceStop(alSource);</span></p>

Cleaning Up</p>


Once you are finished with your program you need to free up your sources and buffers and shut down OpenAL. The commands are relatively simple. Here is how to delete your sources and buffers:</p>

<span class="codeComment">//delete our source</span><span class="codeNormal">
alDeleteSources(1,&alSource);</span>
<span class="codeComment">//delete our buffer</span><span class="codeNormal">
alDeleteBuffers(1,&alSampleSet);</span></p>

Here the first parameter for each is the number of buffers or sources to be deleted and the second is the buffer or source to be deleted. The last step is to close out OpenAL itself. This is done as follows:</p>


<span class="codeComment">//Get active context</span>
<span class="codeNormal">Context=alcGetCurrentContext(); </span>
<span class="codeComment">//Get device for active context</span>
<span class="codeNormal">Device=alcGetContextsDevice(Con text);</span>
<span class="codeComment">//Disable context</span>
<span class="codeNormal">alcMakeContextCurrent(NULL);</span>
<span class="codeComment">//Release context(s)</span>
<span class="codeNormal">alcDestroyContext(Context);</span>
<span class="codeComment">//Close device</span>
<span class="codeNormal">alcCloseDevice(Device);</span></p>

That's about it for playing basic sounds in OpenAL. The basic steps are to first initialize OpenAL, then load in whatever sounds you need, set the properties of the sounds and listener and then play the sounds. There is a lot more you can do with OpenAL but this was just written to describe some of the basics. The source code that comes along with this demonstrates the use of all of this in an OpenGL demo. In the demo, you control the listener and its position is set to your current position every loop. If you have any questions or comments, e-mail me at ricart3@tcnj.edu</p>


Download the sample application here.</p>
</html>
cardinals33 is offline   Reply With Quote
Old 06-08-2003, 02:32 AM   #2
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

wow! Cool man .

You might want to check your code-highlighting font tags though ;P
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 06-08-2003, 07:42 AM   #3
Noor
Senior Member
 
Join Date: Jan 2003
Location: ON, Canada
Posts: 524
Default

cardinals33: Great Job.... Thank you so much
___________________________________________
"What ever happened to happily ever after?"
Noor is offline   Reply With Quote
Old 06-08-2003, 12:48 PM   #4
cardinals33
New Member
 
Join Date: May 2003
Posts: 2
Default

Thanks for the support guys. Hope people can make use of some of the code. If people have ideas for other articles I wouldn't mind writing some more. I was thinking of doing one on EAX and doing 3D sound without OpenAL. I've also done some work streaming Ogg Vorbis files with DirectSound.
cardinals33 is offline   Reply With Quote
Old 06-08-2003, 02:07 PM   #5
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

looks very nice. i'll read it more carefully when i have time now its soon utopia-time!! yeah!!
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 06-08-2003, 02:48 PM   #6
stodge
Valued Member
 
Join Date: May 2003
Location: Canada
Posts: 111
Default

Great article! Nice and concise and easy to read. This will come in handy if I decide to use OpenAL instead of SDL_Mixer.

Thanks
___________________________________________
http://stodge.blogspot.com
stodge is offline   Reply With Quote
Old 06-08-2003, 11:03 PM   #7
donBerto
Senior Member
 
donBerto's Avatar
 
Join Date: Jan 2003
Location: East Coast, USA
Posts: 370
Default

stodge: ditto
dave: utopia, your second home?

thanks! great article, great read.
___________________________________________
Imagine.
donBerto is offline   Reply With Quote
Old 06-09-2003, 09:15 AM   #8
DarkLight
Member
 
DarkLight's Avatar
 
Join Date: Feb 2003
Location: HellCity
Posts: 57
Default

Great article, cardinals33!
___________________________________________
<a href='http://www.kaldata.net' target='_blank'>kaldata.net - IT News</a>
DarkLight is offline   Reply With Quote
Old 06-09-2003, 12:14 PM   #9
stodge
Valued Member
 
Join Date: May 2003
Location: Canada
Posts: 111
Default

A simple 3D sound tutorial using something like SDL_Mixer would certainly be interesting. It would provide a nice comparison with OpenAL and help people choose between the two.
___________________________________________
http://stodge.blogspot.com
stodge is offline   Reply With Quote
Old 06-09-2003, 05:13 PM   #10
Dia Kharrat
DevMaster Staff
 
Join Date: Jan 2003
Posts: 1,201
Default

That's a very good idea stodge...Anyone would like to volunteer for doing an article about SDL_Mixer ?
Dia Kharrat is offline   Reply With Quote
Old 06-10-2003, 12:47 AM   #11
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

Quote:
Originally Posted by donBerto
dave: utopia, your second home?
nope, my 3rd home.

first: my home (hochbordweg 2)
second: my gf home (rheinstrasse 8)
third: utopia

___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 06-10-2003, 12:44 PM   #12
donBerto
Senior Member
 
donBerto's Avatar
 
Join Date: Jan 2003
Location: East Coast, USA
Posts: 370
Default

haha nice! still, I'm surprised you're still able to find time to post!

___________________________________________
Imagine.
donBerto is offline   Reply With Quote
Old 06-10-2003, 10:15 PM   #13
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

just don't say it to my boss lalala. no, really. at home i have currently about _NO_ time.. hehe.

but the project of me gets bigger and bigger (in brain). just need time and energy to code it down.. it will revolutionize the world. this one at least definitely.. or gets noted in some newspapers, what ever. and no, i don't plan yata (yet another terroristic attack ). its just a sweet looking program
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 06-10-2003, 10:17 PM   #14
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

it can even be useful for sound... (to get back on the topic).. while too slow today.. one day... we don't know yet.. sound lacks global reflections and all that as well at least.. a current problem of it.. same as we only have direct lighting realtime today, we have only direct "sounding" realtime today.. well, the future's bright, hehe
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 06-11-2003, 07:48 AM   #15
donBerto
Senior Member
 
donBerto's Avatar
 
Join Date: Jan 2003
Location: East Coast, USA
Posts: 370
Default

yeah sorry for hijacking this thread :nervous:

but yes, it would definitely be interesting to see a side-by-side comparison of OpenAL v SDL_mixer.

___________________________________________
Imagine.
donBerto is offline   Reply With Quote
Old 08-23-2003, 08:22 AM   #16
fletcher
New Member
 
Join Date: Aug 2003
Posts: 1
Default

Does anyone have a link to discussion or graphics to illustrate INNER_ and OUTER_CONE_ANGLE ??
fletcher is offline   Reply With Quote
Old 08-24-2003, 02:22 AM   #17
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

I don't want to start the necromancy argument again, but did that really have to be posted here? I mean, I personally would have started a new thread.
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 08-24-2003, 05:07 AM   #18
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

this time, i'll agree with you
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 08-24-2003, 11:38 AM   #19
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

now maybe you can see why necromancy can be bad ;P
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 10-13-2003, 07:00 PM   #20
i2eye
New Member
 
Join Date: Oct 2003
Posts: 4
Question

Hi, I'm a newbie in this openAL world, just checking out how this example works...
But I got stuck in getting these compiling errors:

Compiling...
alsound.cpp
dinput.cpp
e:\geewoo\project\openal\openaltut\dinput.cpp(9) : error C2146: syntax error : missing ';' before identifier 'g_DI'
e:\geewoo\project\openal\openaltut\dinput.cpp(9) : error C2501: 'LPDIRECTINPUT8' : missing storage-class or type specifiers
e:\geewoo\project\openal\openaltut\dinput.cpp(9) : fatal error C1004: unexpected end of file found
main.cpp
e:\geewoo\project\openal\openaltut\main.cpp(24) : error C2146: syntax error : missing ';' before identifier 'g_KDIDev'
e:\geewoo\project\openal\openaltut\main.cpp(24) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

openaltest.exe - 5 error(s), 0 warning(s)


I didn't make any changes in the source code. Does anybody have an idea what's wrong with this? I think I've linked all the library files needed...
i2eye is offline   Reply With Quote
Old 10-14-2003, 02:49 AM   #21
baldurk
DevMaster Staff
 
baldurk's Avatar
 
Join Date: Jan 2003
Location: Mars
Posts: 1,141
Default

this is just a guess, but I'd say you're not including a header you need. Looks like a DX one, but I couldn't say for sure.
___________________________________________
baldurk
He who knows not and knows that he knows not is ignorant. Teach him.
He who knows not and knows not that he knows not is a fool. Shun him.
baldurk is offline   Reply With Quote
Old 10-15-2003, 01:26 AM   #22
i2eye
New Member
 
Join Date: Oct 2003
Posts: 4
Default

Well, I don't really know what happened actually, but it got to work somehow.
I figured out something was wrong with my computer, because it had problems with openGL & DirectX sources also. So I just re-installed everything(starting from win2k...). Thank you anyway.
i2eye is offline   Reply With Quote
Old 10-28-2004, 11:00 PM   #23
yjh1982
New Member
 
Join Date: Oct 2004
Posts: 2
Default

bug openal is GPL lisence.
is mean your program must GPL?
I am not like GPL;BSD or zlib is greater.
yjh1982 is offline   Reply With Quote
Old 10-29-2004, 12:55 AM   #24
SpreeTree
Valued Member
 
SpreeTree's Avatar
 
Join Date: Jan 2004
Location: England
Posts: 265
Default

No, if you use OpenAL your final program doesnt need to be GPL based. If that was the case then big companies out there wouldnt use it e.g. Epic Games.

Spree
SpreeTree is offline   Reply With Quote
Old 10-31-2004, 05:49 PM   #25
yjh1982
New Member
 
Join Date: Oct 2004
Posts: 2
Default

Quote:
Originally Posted by SpreeTree
No, if you use OpenAL your final program doesnt need to be GPL based. If that was the case then big companies out there wouldnt use it e.g. Epic Games.

Spree
[snapback]13438[/snapback]
is mean,OpenAL use two lisence?as mysql ,QT?
yjh1982 is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Forum Jump


All times are GMT -7. The time now is 06:09 AM.


Powered by vBulletin
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.