2002-09-03 17:25:01 -04:00
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<title>OpenAL Tutoral</title>
|
|
|
|
|
|
|
|
|
|
<meta http-equiv="content-type"
|
|
|
|
|
content="text/html; charset=windows-1252">
|
|
|
|
|
<meta name="author" content="Brian Matzon">
|
|
|
|
|
<meta name="description" content="Basic sound using OpenAL">
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h1 align="center">OpenAL Tutorial<br>
|
|
|
|
|
<font size="-1">(by Brian Matzon <<a href="mailto:brian@matzon.dk">brian@matzon.dk</a>>)</font><br>
|
|
|
|
|
</h1>
|
|
|
|
|
<b>1.0 OpenAL Basics</b><br>
|
|
|
|
|
Before embarking on our little OpenAL adventure, some tools are needed.<br>
|
|
|
|
|
<br>
|
|
|
|
|
<b>1.0.1 Ingredients</b><br>
|
|
|
|
|
Head on over to Creatives <a
|
|
|
|
|
href="http://developer.creative.com/scripts/DC_D&H_Games-Downloads.asp?opt=2">site</a>
|
|
|
|
|
and snag a copy of the OpenAL specification along with a copy of the Programmers
|
|
|
|
|
reference.<br>
|
|
|
|
|
If you haven't already done so, get a copy of the OpenAL runtime environment
|
|
|
|
|
too (and install it).<br>
|
|
|
|
|
<br>
|
|
|
|
|
<b>1.1 OpenAL theory</b><br>
|
|
|
|
|
Uhm... I'm not going to write this... In all honesty reading the specification
|
|
|
|
|
would be a good thing before continuing - but it isn't required...<br>
|
|
|
|
|
<br>
|
|
|
|
|
<b>1.2 Basic setup</b><br>
|
|
|
|
|
Lets start out by creating a skeleton class for some very basic sound. We'll
|
2003-04-27 17:46:30 -04:00
|
|
|
|
start of by creating the required OpenAL object<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt>import
|
|
|
|
|
org.lwjgl.openal.AL;<br>
|
|
|
|
|
<br>
|
|
|
|
|
public class PlayTest {<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> <br>
|
|
|
|
|
<EFBFBD> /** OpenAL instance */<br>
|
|
|
|
|
<EFBFBD> protected AL al;<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<br>
|
|
|
|
|
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<EFBFBD> /**<br>
|
|
|
|
|
<EFBFBD><EFBFBD> * Creates an instance of PlayTest<br>
|
|
|
|
|
<EFBFBD><EFBFBD> */<br>
|
|
|
|
|
<EFBFBD> public PlayTest() {<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> try {<br>
|
2002-12-21 07:10:05 -05:00
|
|
|
|
</tt><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<tt><EFBFBD>al = new AL();<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> <20> al.create();<br>
|
|
|
|
|
<EFBFBD><EFBFBD> } catch (Exception e) {<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> <20> e.printStackTrace();<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> }</tt><tt><br>
|
|
|
|
|
<EFBFBD> }<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
}</tt></p>
|
|
|
|
|
<p><b>1.3 Buffer and Source creation</b><br>
|
|
|
|
|
Now that we have created the AL instance, we need to create
|
2002-09-03 17:25:01 -04:00
|
|
|
|
two things to actually get some sound. We need to create a buffer to hold
|
2003-04-27 17:46:30 -04:00
|
|
|
|
sound data, and a source that is to play the sound data.<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
Lets start of by creating one source, and one buffer:</p>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<p style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);">
|
|
|
|
|
<tt>
|
|
|
|
|
//create one IntBuffer as buffer and one as source<br>
|
|
|
|
|
//createIntBuffer is a utility method which allocates a direct ByteBuffer in native order<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<EFBFBD> IntBuffer buffers = createIntBuffer(1);<br>
|
|
|
|
|
<EFBFBD> IntBuffer sources = createIntBuffer(1);<br>
|
|
|
|
|
<br>
|
|
|
|
|
<EFBFBD> //generate buffers and sources<br>
|
|
|
|
|
<EFBFBD> al.genBuffers(1, Sys.getDirectBufferAddress(buffers));<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<EFBFBD> al.genSources(1, Sys.getDirectBufferAddress(sources));
|
|
|
|
|
</tt>
|
|
|
|
|
</p>
|
|
|
|
|
<p>There, all set for actually loading some sound data into the buffer.<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
</p>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<b>1.4 Loading sound data and setting up a buffer</b><br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
Now that we have a buffer, we need to load some sound data into this buffer.
|
|
|
|
|
This is done using the <tt>al.bufferData</tt> method. In our example we will
|
2002-12-21 07:10:05 -05:00
|
|
|
|
"cheat" a bit, by using the <tt>WaveData</tt> class to load
|
2002-09-03 17:25:01 -04:00
|
|
|
|
a wave file, and copy this into the buffer:<br>
|
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt><EFBFBD>
|
|
|
|
|
//load wave data<br>
|
2002-12-21 07:10:05 -05:00
|
|
|
|
<EFBFBD> WaveData wavefile = WaveData.create("mywavefile.wav");<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><br>
|
|
|
|
|
<EFBFBD> //copy to buffer<br>
|
2002-12-21 07:10:05 -05:00
|
|
|
|
<EFBFBD> al.bufferData(buffers.get(0), wavefile.format, Sys.getDirectBufferAddress(wavefile.data), wavefile.data.capacity(), wavefile.samplerate);<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><br>
|
|
|
|
|
<EFBFBD> //unload file again<br>
|
2002-12-21 07:10:05 -05:00
|
|
|
|
<EFBFBD> wavefile.dispose();<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
</tt></p>
|
|
|
|
|
Having loaded the data, we pass it to <tt>bufferData</tt>. Once the buffer
|
2003-04-27 17:46:30 -04:00
|
|
|
|
has been filled with sound data, we unload it from the system using <tt>wavefile.dispose()</tt>.
|
|
|
|
|
Don't worry about deleting it this soon - the sound data has been <b>copied</b>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
to the buffer.<br>
|
|
|
|
|
<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<b>1.5 Associating sources and buffers</b><br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
To associate a source to a buffer we set the integer BUFFER attribute on
|
|
|
|
|
the source, and assign it a value of the buffer to play:<br>
|
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt><EFBFBD>
|
|
|
|
|
//set up source input<br>
|
|
|
|
|
<EFBFBD> al.sourcei(sources.get(0), AL.BUFFER, buffers.get(0));</tt><tt><br>
|
|
|
|
|
</tt></p>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<b>1.6 Setting source properties</b><br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
Having set up the source, it is time to set some attributes on the source
|
|
|
|
|
- there are many that can be set, but in this example we only set the looping
|
|
|
|
|
attribute to true by doing the following:<br>
|
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt><EFBFBD>
|
|
|
|
|
//loop source<br>
|
|
|
|
|
<EFBFBD> al.sourcei(sources.get(0), AL.LOOPING, AL.TRUE);</tt><tt><br>
|
|
|
|
|
</tt></p>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<b>1.7 Sound...<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
</b>There, ready to play the sound, do this using the <tt>sourcePlay </tt>method
|
|
|
|
|
of the <tt>AL </tt>class. to stop and pause use <tt>sourcePause </tt>and
|
|
|
|
|
<tt>sourceStop </tt>respectively, and supply the source to affect:<br>
|
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt><EFBFBD>
|
|
|
|
|
//play source 0<br>
|
|
|
|
|
<EFBFBD> al.sourcePlay(sources.get(0));<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <br>
|
|
|
|
|
<EFBFBD> //wait 5 secs<br>
|
|
|
|
|
<EFBFBD> try {<br>
|
|
|
|
|
<EFBFBD> <20> System.out.println("Waiting 5 seconds for sound to complete");<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD> Thread.sleep(5000);<br>
|
|
|
|
|
<EFBFBD> } catch (InterruptedException inte) {<br>
|
|
|
|
|
<EFBFBD> }<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <br>
|
|
|
|
|
<EFBFBD> //stop source 0<br>
|
|
|
|
|
<EFBFBD> al.sourceStop(sources.get(0));</tt></p>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<b>1.8 Cleaning up<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
</b>Having had loads of fun playing a sound (!), it is now time to do some
|
|
|
|
|
house chores. We need to clean up what we have created, this amounts to:<br>
|
|
|
|
|
<EFBFBD>- deleting source and buffer<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<EFBFBD>- destroying AL<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
as is shown here:<b><br>
|
|
|
|
|
</b>
|
|
|
|
|
<p
|
|
|
|
|
style="border-style: solid; border-width: 1px; padding: 3px; background-color: rgb(255,255,204);"><tt><EFBFBD>
|
|
|
|
|
//delete buffers and sources<br>
|
|
|
|
|
<EFBFBD> al.deleteSources(1, Sys.getDirectBufferAddress(sources));<br>
|
|
|
|
|
<EFBFBD> al.deleteBuffers(1, Sys.getDirectBufferAddress(buffers));<br>
|
|
|
|
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><br>
|
|
|
|
|
<EFBFBD> //shutdown<br>
|
2003-04-27 17:46:30 -04:00
|
|
|
|
<EFBFBD> al.destroy();<br>
|
|
|
|
|
</tt>
|
|
|
|
|
</p>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
There, all set. Now you should be able to play some basic sound!<br>
|
|
|
|
|
This tutorial is rather short, and the above examples feature no error checking.
|
2002-12-21 07:10:05 -05:00
|
|
|
|
For the complete source code, look at the classes in the <br>
|
|
|
|
|
<a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/java-game-lib/LWJGL/src/java/org/lwjgl/test/openal/" target="_blank"><tt>org.lwjgl.test.openal</tt></a> package.<br>
|
2002-09-03 17:25:01 -04:00
|
|
|
|
</body>
|
|
|
|
|
</html>
|