Jogamp
www/devmaster/lesson*.html: Fix header, title, navigation and links.
[joal-demos.git] / www / devmaster / lesson3.html
Content-type: text/html jogamp.org Git - joal-demos.git/blame - www/devmaster/lesson3.html
Jogamp


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 5) line 1, <$fd> line 601.
CommitLineData
da8d0035 1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html>
3<head>
aaf9d0a3 4 <title>JOAL OpenAL Tutorials from DevMaster.net Lesson 3: Multiple Sources</title>
da8d0035 5</head>
49e0d378 6<body>
aaf9d0a3 7<a href="../index.html"><img src="../../../images/jogamp_symbols/website_final_blue_joal_346x70pel.png" alt="JOAL Symbol"></a><a href="http://www.openal.org"><img src="../openal_c.gif"></a>
da8d0035 8<br>
9OpenAL Tutorials from DevMaster.net. Reprinted with Permission.<br>
10<br>
11
12<table border="0" cellspacing="0" style="border-collapse: collapse" width="100%" cellpadding="0" id="AutoNumber1" height="12" bgcolor="#666699">
13 <tr>
14 <td width="47%" height="12" valign="middle"><p><b><font color="#FFFFFF">OpenAL
15 Tutorials</font></b></p></td>
16 <td width="53%" height="12" align="right" valign="middle"><p align="right"><a href="http://devmaster.net/"><font color="#66FF99">DevMaster.net</font></a></p></td>
17 </tr>
18 </table>
19
20<p class="ArticleTitle"><font size="5">Multiple Sources<br>
21 </font><font size="4"><strong>Lesson 3</strong></font></p>
22
23<p align="right" class="ArticleAuthor">Author: <a href="mailto:lightonthewater@hotmail.com">Jesse
24 Maurais</a><br>
25 Adapted for Java by: <a href="mailto:athomas@dev.java.net">Athomas Goldberg</a></p>
cbd4d31f 26
aaf9d0a3 27<p><a href="../../../joal/www/jnlp-files/joal-lesson3.jnlp">Launch the Demo via Java Web Start</a></p>
cbd4d31f 28
da8d0035 29<p align="justify">Hello. It's been a while since my last tutorial. But better
30 late than never I guess. Since I'm sure your all impatient to read the latest
31 tutorial, I'll just jump right into it. What we hope to accomplish with this
32 one is to be able to play more that one audio sample at a time. Very intense
33 games have all kinds of stuff going on usually involving different sound clips.
34 It won't be hard to implement any of this though. Doing multiple sounds is similar
35 to doing just one.</p>
36
37<pre>
38
39<font color="#0000FF">import</font> java.nio.ByteBuffer;
40<font color="#0000FF">import</font> java.util.Random;
41
42<font color="#0000FF">import</font> net.java.games.joal.AL;
43<font color="#0000FF">import</font> net.java.games.joal.ALFactory;
44<font color="#0000FF">import</font> net.java.games.joal.util.ALut;
45
46<font color="#0000FF">public</font> <font color="#0000FF">class</font> MultipleSources {
47
48 <font color="#0000FF">static</font> AL al;
49
50 <font color="#006600">// Maximum number of buffers we will need.</font>
51 <font color="#0000FF">static</font> <font color="#0000FF">final</font> <font color="#0000FF">int</font> NUM_BUFFERS = 3;
52
53 <font color="#006600">// Maximum emissions we will need.</font>
54 <font color="#0000FF">static</font> <font color="#0000FF">final</font> <font color="#0000FF">int</font> NUM_SOURCES = 3;
55
56 <font color="#006600">// These index the buffers and sources</font>
57 <font color="#0000FF">static</font> <font color="#0000FF">final</font> <font color="#0000FF">int</font> BATTLE = 0;
58 <font color="#0000FF">static</font> <font color="#0000FF">final</font> <font color="#0000FF">int</font> GUN1 = 1;
59 <font color="#0000FF">static</font> <font color="#0000FF">final</font> <font color="#0000FF">int</font> GUN2 = 2;
60
61 <font color="#006600">// Buffers hold sound data</font>
62 <font color="#0000FF">static</font> <font color="#0000FF">int</font>[] buffers = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[NUM_BUFFERS];
63
64 <font color="#006600">// Sources are points of emitting sound</font>
65 <font color="#0000FF">static</font> <font color="#0000FF">int</font>[] sources = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[NUM_SOURCES];
66
67 <font color="#006600">// Position of the source sounds.</font>
68 <font color="#0000FF">static</font> <font color="#0000FF">float</font>[][] sourcePos = <font color="#0000FF">new</font> <font color="#0000FF">float</font>[NUM_SOURCES][3];
69
70 <font color="#006600">// Velocity of the source sounds</font>
71 <font color="#0000FF">static</font> <font color="#0000FF">float</font>[][] sourceVel = <font color="#0000FF">new</font> <font color="#0000FF">float</font>[NUM_SOURCES][3];
72
73 <font color="#006600">// Position of the listener</font>.
74 <font color="#0000FF">static</font> <font color="#0000FF">float</font>[] listenerPos = { 0.0f, 0.0f, 0.0f };
75
76 <font color="#006600">// Velocity of the listener.</font>
77 <font color="#0000FF">static</font> <font color="#0000FF">float</font>[] listenerVel = { 0.0f, 0.0f, 0.0f };
78
79 <font color="#006600">// Orientation of the listener. (first 3 elements are "at", second 3 are "up")</font>
80 <font color="#0000FF">static</font> <font color="#0000FF">float</font>[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
81</pre>
82<p align="justify">I guess this little piece of source code will be familiar to
83 a lot of you who've read the first two tutorials. The only difference is that
84 we now have 3 different sound effects that we are going to load into the OpenAL
85 sound system.</p>
86
87<pre>
88
89 <font color="#0000FF">static</font> <font color="#0000FF">int</font> loadALData() {
90
91 <font color="#006600">//variables to load into</font>
92
93 <font color="#0000FF">int</font>[] format = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[1];
94 <font color="#0000FF">int</font>[] size = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[1];
95 ByteBuffer[] data = <font color="#0000FF">new</font> ByteBuffer[1];
96 <font color="#0000FF">int</font>[] freq = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[1];
97 <font color="#0000FF">int</font>[] loop = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[1];
98 <font color="#006600">
99 // load wav data into buffers</font>
100
101 al.alGenBuffers(NUM_BUFFERS, buffers);
102 <font color="#0000FF">if </font>(al.alGetError() != AL.AL_NO_ERROR) {
103 <font color="#0000FF">return</font> AL.AL_FALSE;
104 }
105
106 ALut.alutLoadWAVFile(
107 "wavdata/Battle.wav",
108 format,
109 data,
110 size,
111 freq,
112 loop);
113 al.alBufferData(
114 buffers[BATTLE],
115 format[0],
116 data[0],
117 size[0],
118 freq[0]);
119 ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]);
120
121 ALut.alutLoadWAVFile(
122 "wavdata/Gun1.wav",
123 format,
124 data,
125 size,
126 freq,
127 loop);
128 al.alBufferData(
129 buffers[GUN1],
130 format[0],
131 data[0],
132 size[0],
133 freq[0]);
134 ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]);
135
136 ALut.alutLoadWAVFile(
137 "wavdata/Gun2.wav",
138 format,
139 data,
140 size,
141 freq,
142 loop);
143 al.alBufferData(
144 buffers[GUN2],
145 format[0],
146 data[0],
147 size[0],
148 freq[0]);
149 ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]);
150
151<font color="#006600"> // bind buffers into audio sources</font>
152 al.alGenSources(NUM_SOURCES, sources);
153
154 al.alSourcei(sources[BATTLE], AL.AL_BUFFER, buffers[BATTLE]);
155 al.alSourcef(sources[BATTLE], AL.AL_PITCH, 1.0f);
156 al.alSourcef(sources[BATTLE], AL.AL_GAIN, 1.0f);
157 al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourcePos[BATTLE]);
158 al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourceVel[BATTLE]);
159 al.alSourcei(sources[BATTLE], AL.AL_LOOPING, AL.AL_TRUE);
160
161 al.alSourcei(sources[GUN1], AL.AL_BUFFER, buffers[GUN1]);
162 al.alSourcef(sources[GUN1], AL.AL_PITCH, 1.0f);
163 al.alSourcef(sources[GUN1], AL.AL_GAIN, 1.0f);
164 al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourcePos[GUN1]);
165 al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourceVel[GUN1]);
166 al.alSourcei(sources[GUN1], AL.AL_LOOPING, AL.AL_FALSE);
167
168 al.alSourcei(sources[GUN2], AL.AL_BUFFER, buffers[GUN2]);
169 al.alSourcef(sources[GUN2], AL.AL_PITCH, 1.0f);
170 al.alSourcef(sources[GUN2], AL.AL_GAIN, 1.0f);
171 al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourcePos[GUN2]);
172 al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourceVel[GUN2]);
173 al.alSourcei(sources[GUN2], AL.AL_LOOPING, AL.AL_FALSE);
174
175<font color="#006600"> // do another error check and return</font>
176 if (al.alGetError() != AL.AL_NO_ERROR) {
177 <font color="#0000FF">return</font> AL.AL_FALSE;
178 }
179
180 <font color="#0000FF">return</font> AL.AL_TRUE;
181 }
182
183</pre>
184<p align="justify">This code looks quite a bit different at first, but it isn't
185 really. Basically we load the file data into our 3 buffers, then lock the 3
186 buffers to our 3 sources relatively. The only other difference is that the &quot;Battle.wav&quot;
187 (Source index 0) is looping while the rest are not.</p>
188<pre>
189
190 <font color="#0000FF">static</font> <font color="#0000FF">void</font> setListenerValues() {
191 al.alListenerfv(AL.AL_POSITION, listenerPos);
192 al.alListenerfv(AL.AL_VELOCITY, listenerVel);
193 al.alListenerfv(AL.AL_ORIENTATION, listenerOri);
194 }
195
196 <font color="#0000FF">static</font> <font color="#0000FF">void</font> killAllData() {
197 al.alDeleteBuffers(NUM_BUFFERS, buffers);
198 al.alDeleteSources(NUM_SOURCES, sources);
199 ALut.alutExit();
200 }
201</pre>
202<p>I don't think we changed anything in this code.</p>
203
204<pre> <font color="#0000FF">public</font> <font color="#0000FF">static</font> <font color="#0000FF">void</font> main(String[] args) {
205 al = ALFactory.getAL();
206
207 <font color="#006600">// Initialize OpenAL and clear the error bit</font>
208
209 ALut.alutInit();
210 al.alGetError();
211
212 <font color="#006600">// Load the wav data.</font>
213
214 <font color="#0000FF">if</font>(loadALData() == AL.AL_FALSE) {
215 System.exit(1);
216 }
217 setListenerValues();
218
219 <font color="#006600"> // begin the battle sample to play</font>
220
221 al.alSourcePlay(sources[BATTLE]);
222 <font color="#0000FF">long</font> startTime = System.currentTimeMillis();
223 <font color="#0000FF">long</font> elapsed = 0;
224 <font color="#0000FF">long</font> totalElapsed = 0;
225 Random rand = new Random();
226 <font color="#0000FF">int</font>[] state = <font color="#0000FF">new</font> <font color="#0000FF">int</font>[1];
227 <font color="#0000FF">while</font> (totalElapsed < 10000) {
228 elapsed = System.currentTimeMillis() - startTime;
229 <font color="#0000FF">if</font> (elapsed > 50) {
230 totalElapsed += elapsed;
231 startTime = System.currentTimeMillis();
232
233 <font color="#006600">// pick one of the sources at random and check to see if it is playing.
234 // Skip the first source because it is looping anyway (will always be playing).</font>
235
236 <font color="#0000FF">int</font> pick = Math.abs((rand.nextInt()) % 2) + 1;
237 al.alGetSourcei(sources[pick], AL.AL_SOURCE_STATE, state);
238
239 <font color="#0000FF">if</font> (state[0] != AL.AL_PLAYING) {
240
241 <font color="#006600"> // pick a random position around the listener to play the source.</font>
242
243 <font color="#0000FF">double</font> theta = (rand.nextInt() % 360) * 3.14 / 180.0;
244 sourcePos[pick][0] = - ((<font color="#0000FF">float</font>) Math.cos(theta));
245 sourcePos[pick][1] = - ((<font color="#0000FF">float</font>) (rand.nextInt() % 2));
246 sourcePos[pick][2] = - ((<font color="#0000FF">float</font>) Math.sin(theta));
247
248 al.alSourcefv(
249 sources[pick],
250 AL.AL_POSITION,
251 sourcePos[pick]);
252
253 al.alSourcePlay(sources[pick]);
254 }
255 }
256 }
257 killAllData();
258 }
259}
260</pre>
261
262<p align="justify">Here is the interesting part of this tutorial. We go through
263 each of the sources to make sure it's playing. If it is not then we set it to
264 play but we select a new point in 3D space for it to play (just for kicks).
265</p>
266<p align="justify">And bang! We are done. As most of you have probably seen, you
267 don't have to do anything special to play more than one source at a time. OpenAL
268 will handle all the mixing features to get the sounds right for their respective
269 distances and velocities. And when it comes right down to it, isn't that the
270 beauty of OpenAL? </p>
271<p align="justify">You know that was a lot easier than I thought. I don't know
272 why I waited so long to write it. Anyway, if anyone reading wants to see something
273 specific in future tutorials (not necessarily pertaining to OpenAL, I have quite
274 an extensive knowledge base) drop me a line at <a href="mailto:lightonthewater@hotmail.com">lightonthewater@hotmail.com</a>
275 I plan to do tutorials on sharing buffers and the Doppler effect in some later
276 tutorial unless there is request for something else. Have fun with the code!</p>
da8d0035 277<table border="0" cellspacing="1" style="border-collapse: collapse" width="100%" id="AutoNumber2" bgcolor="#666699">
278 <tr>
279
http://JogAmp.org git info: FAQ, tutorial and man pages.