From 06a3aaa5fd38097a4644921a269d6ca282fb31eb Mon Sep 17 00:00:00 2001
From: Xerxes Rånby
So let's get coding!
-import net.java.games.joal.*; -import net.java.games.joal.util.*; +import com.jogamp.openal.*; +import com.jogamp.openal.util.*; import java.io.*; import java.nio.ByteBuffer;public class SingleStaticSource { @@ -120,20 +120,21 @@ tutorial from DevMaster.net to JOAL. I used arrays for simplicity.Here we will create a function that loads all of our sound data from a file.
-static int LoadALData() { +static int loadALData() { // variables to load into int[] format = new int[1];
int[] size = new int[1];
ByteBuffer[] data = new ByteBuffer[1];
int[] freq = new int[1]; int[] loop = new int[1];
// Load wav data into a buffer. - al.alGenBuffers(1, buffer); + al.alGenBuffers(1, buffer, 0); if (al.alGetError() != AL.AL_NO_ERROR) return AL.AL_FALSE; ALut.alutLoadWAVFile("wavdata/FancyPants.wav", format, data, size, freq, loop); al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]); - ALut.alutUnloadWAV(format[0],data[0],size[0],freq[0]); + +The function 'alGenBuffers' will create the buffer objects and store them in the variable we passed it. It's important to do an error check @@ -141,13 +142,13 @@ tutorial from DevMaster.net to JOAL. not generate a buffer object due to a lack of memory. In this case it would set the error bit.
The ALut is very helpful here. It opens up the file for us - and gives us all the information we need to create the buffer. And after we - have attached all this data to the buffer it will help use dispose of the data. + and gives us all the information we need to create the buffer. It all works in a clean and efficient manner.
// Bind buffer with a source. - al.alGenSources(1, source); + al.alGenSources(1, source, 0); if (al.alGetError() != AL.AL_NO_ERROR) return AL.AL_FALSE; @@ -155,8 +156,8 @@ tutorial from DevMaster.net to JOAL. al.alSourcei (source[0], AL.AL_BUFFER, buffer[0] ); al.alSourcef (source[0], AL.AL_PITCH, 1.0f ); al.alSourcef (source[0], AL.AL_GAIN, 1.0f ); - al.alSourcefv(source[0], AL.AL_POSITION, sourcePos); - al.alSourcefv(source[0], AL.AL_VELOCITY, sourceVel); + al.alSourcefv(source[0], AL.AL_POSITION, sourcePos, 0); + al.alSourcefv(source[0], AL.AL_VELOCITY, sourceVel, 0); al.alSourcei (source[0], AL.AL_LOOPING, loop[0] );We generate a source object in the same manner we generated the buffer object. Then we define the source properties that it will use when @@ -182,16 +183,16 @@ tutorial from DevMaster.net to JOAL.
To end the function we just do one more check to make sure all is well, then we return success.
static void setListenerValues() { - al.alListenerfv(AL.AL_POSITION, listenerPos); - al.alListenerfv(AL.AL_VELOCITY, listenerVel); - al.alListenerfv(AL.AL_ORIENTATION, listenerOri); + al.alListenerfv(AL.AL_POSITION, listenerPos, 0); + al.alListenerfv(AL.AL_VELOCITY, listenerVel, 0); + al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 0); }We created this function to update the listener properties.
static void killALData() { - al.alDeleteBuffers(1, buffer); - al.alDeleteSources(1, source); - Alut.alutExit(); + al.alDeleteBuffers(1, buffer, 0); + al.alDeleteSources(1, source, 0); + ALut.alutExit(); }This will be our shutdown procedure. It is necessary to call this to release @@ -204,7 +205,7 @@ all the memory and audio devices that our program may be using.
The function 'alutInit' will setup everything that the Alc - needs to do for us. Basically Alut creates a single OpenAL context through Alc + needs to do for us. Basically ALut creates a single OpenAL context through Alc and sets it to current. On the Windows platform it initializes DirectSound. We also do an initial call to the error function to clear it. Every time we call 'glGetError' it will reset itself to 'AL_NO_ERROR'.
@@ -212,7 +213,7 @@ all the memory and audio devices that our program may be using. // Load the wav data. if (loadALData() == AL.AL_FALSE) - return -1; + System.exit(-1); setListenerValues(); @@ -223,7 +224,7 @@ all the memory and audio devices that our program may be using. new Thread( new Runnable() { public void run() { - killAllData(); + killALData(); } } ) @@ -246,11 +247,11 @@ and finally we set our exit procedure. break; case 's': // Pressing 's' will stop the sample from playing. - alSourceStop(source[0]); + al.alSourceStop(source[0]); break; case 'h': // Pressing 'n' will pause (hold) the sample. - alSourcePause(source[0]); + al.alSourcePause(source[0]); break; } } catch (IOException e) { @@ -259,6 +260,7 @@ and finally we set our exit procedure. } } +} // class SingleStaticSourceThis is the interesting part of the tutorial. It's a very basic loop that lets us control the playback of the audio sample. Pressing 'p' will diff --git a/www/devmaster/lesson2.html b/www/devmaster/lesson2.html index 91bbb3e..f1b0b2c 100644 --- a/www/devmaster/lesson2.html +++ b/www/devmaster/lesson2.html @@ -39,10 +39,10 @@ tutorial from DevMaster.net to JOAL. real quick and easy tutorial. It won't get too much more complicated at this point.
import java.nio.ByteBuffer; - import net.java.games.joal.AL; - import net.java.games.joal.ALC; - import net.java.games.joal.ALFactory; - import net.java.games.joal.util.ALut; + import com.jogamp.openal.AL; + import com.jogamp.openal.ALC; + import com.jogamp.openal.ALFactory; + import com.jogamp.openal.util.ALut; public class LoopingAndFadeaway { @@ -72,7 +72,7 @@ real quick and easy tutorial. It won't get too much more complicated at this poi // Load wav data into a buffer. - al.alGenBuffers(1, buffer); + al.alGenBuffers(1, buffer, 0); if (al.alGetError() != AL.AL_NO_ERROR) return AL.AL_FALSE; ALut.alutLoadWAVFile( @@ -83,14 +83,14 @@ real quick and easy tutorial. It won't get too much more complicated at this poi freq, loop); al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]); - ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]); + - al.alGenSources(1, source); + al.alGenSources(1, source, 0); al.alSourcei(source[0], AL.AL_BUFFER, buffer[0]); al.alSourcef(source[0], AL.AL_PITCH, 1.0f); al.alSourcef(source[0], AL.AL_GAIN, 1.0f); - al.alSourcefv(source[0], AL.AL_POSITION, sourcePos); - al.alSourcefv(source[0], AL.AL_POSITION, sourceVel); + al.alSourcefv(source[0], AL.AL_POSITION, sourcePos, 0); + al.alSourcefv(source[0], AL.AL_POSITION, sourceVel, 0); al.alSourcei(source[0], AL.AL_LOOPING, AL.AL_TRUE); if (al.alGetError() != AL.AL_NO_ERROR) { return AL.AL_FALSE; @@ -104,15 +104,15 @@ real quick and easy tutorial. It won't get too much more complicated at this poi clip has ended.static void setListenerValues() { - al.alListenerfv(AL.AL_POSITION, listenerPos); - al.alListenerfv(AL.AL_VELOCITY, listenerVel); - al.alListenerfv(AL.AL_ORIENTATION, listenerOri); + al.alListenerfv(AL.AL_POSITION, listenerPos, 0); + al.alListenerfv(AL.AL_VELOCITY, listenerVel, 0); + al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 0); } static void killALData() { - al.alDeleteBuffers(1, buffer); - al.alDeleteSources(1, source); - Alut.alutExit(); + al.alDeleteBuffers(1, buffer, 0); + al.alDeleteSources(1, source, 0); + ALut.alutExit(); }Nothing has changed here.
@@ -130,7 +130,7 @@ real quick and easy tutorial. It won't get too much more complicated at this poi long elapsed = 0; long ticker = 0; long lastTime = 0; - while (elapsed < 5000) { + while (elapsed < 10000) { elapsed = System.currentTimeMillis() - startTime; if (ticker > 100) { ticker = 0; @@ -140,7 +140,7 @@ real quick and easy tutorial. It won't get too much more complicated at this poi al.alSourcefv( source[0], AL.AL_POSITION, - sourcePos); + sourcePos, 0); } ticker += System.currentTimeMillis() - lastTime; lastTime = System.currentTimeMillis(); diff --git a/www/devmaster/lesson3.html b/www/devmaster/lesson3.html index a308680..4d20ca4 100644 --- a/www/devmaster/lesson3.html +++ b/www/devmaster/lesson3.html @@ -43,9 +43,9 @@ tutorial from DevMaster.net to JOAL. import java.nio.ByteBuffer; import java.util.Random; -import net.java.games.joal.AL; -import net.java.games.joal.ALFactory; -import net.java.games.joal.util.ALut; +import com.jogamp.openal.AL; +import com.jogamp.openal.ALFactory; +import com.jogamp.openal.util.ALut; public class MultipleSources { @@ -102,7 +102,7 @@ tutorial from DevMaster.net to JOAL. // load wav data into buffers - al.alGenBuffers(NUM_BUFFERS, buffers); + al.alGenBuffers(NUM_BUFFERS, buffers, 0); if (al.alGetError() != AL.AL_NO_ERROR) { return AL.AL_FALSE; } @@ -120,7 +120,7 @@ tutorial from DevMaster.net to JOAL. data[0], size[0], freq[0]); - ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]); + ALut.alutLoadWAVFile( "wavdata/Gun1.wav", @@ -135,7 +135,7 @@ tutorial from DevMaster.net to JOAL. data[0], size[0], freq[0]); - ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]); + ALut.alutLoadWAVFile( "wavdata/Gun2.wav", @@ -150,30 +150,30 @@ tutorial from DevMaster.net to JOAL. data[0], size[0], freq[0]); - ALut.alutUnloadWAV(format[0], data[0], size[0], freq[0]); + // bind buffers into audio sources - al.alGenSources(NUM_SOURCES, sources); + al.alGenSources(NUM_SOURCES, sources, 0); al.alSourcei(sources[BATTLE], AL.AL_BUFFER, buffers[BATTLE]); al.alSourcef(sources[BATTLE], AL.AL_PITCH, 1.0f); al.alSourcef(sources[BATTLE], AL.AL_GAIN, 1.0f); - al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourcePos[BATTLE]); - al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourceVel[BATTLE]); + al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourcePos[BATTLE], 0); + al.alSourcefv(sources[BATTLE], AL.AL_POSITION, sourceVel[BATTLE], 0); al.alSourcei(sources[BATTLE], AL.AL_LOOPING, AL.AL_TRUE); al.alSourcei(sources[GUN1], AL.AL_BUFFER, buffers[GUN1]); al.alSourcef(sources[GUN1], AL.AL_PITCH, 1.0f); al.alSourcef(sources[GUN1], AL.AL_GAIN, 1.0f); - al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourcePos[GUN1]); - al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourceVel[GUN1]); + al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourcePos[GUN1], 0); + al.alSourcefv(sources[GUN1], AL.AL_POSITION, sourceVel[GUN1], 0); al.alSourcei(sources[GUN1], AL.AL_LOOPING, AL.AL_FALSE); al.alSourcei(sources[GUN2], AL.AL_BUFFER, buffers[GUN2]); al.alSourcef(sources[GUN2], AL.AL_PITCH, 1.0f); al.alSourcef(sources[GUN2], AL.AL_GAIN, 1.0f); - al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourcePos[GUN2]); - al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourceVel[GUN2]); + al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourcePos[GUN2], 0); + al.alSourcefv(sources[GUN2], AL.AL_POSITION, sourceVel[GUN2], 0); al.alSourcei(sources[GUN2], AL.AL_LOOPING, AL.AL_FALSE); // do another error check and return @@ -192,14 +192,14 @@ tutorial from DevMaster.net to JOAL.static void setListenerValues() { - al.alListenerfv(AL.AL_POSITION, listenerPos); - al.alListenerfv(AL.AL_VELOCITY, listenerVel); - al.alListenerfv(AL.AL_ORIENTATION, listenerOri); + al.alListenerfv(AL.AL_POSITION, listenerPos, 0); + al.alListenerfv(AL.AL_VELOCITY, listenerVel, 0); + al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 0); } static void killAllData() { - al.alDeleteBuffers(NUM_BUFFERS, buffers); - al.alDeleteSources(NUM_SOURCES, sources); + al.alDeleteBuffers(NUM_BUFFERS, buffers, 0); + al.alDeleteSources(NUM_SOURCES, sources, 0); ALut.alutExit(); }@@ -238,7 +238,7 @@ tutorial from DevMaster.net to JOAL. // Skip the first source because it is looping anyway (will always be playing). int pick = Math.abs((rand.nextInt()) % 2) + 1; - al.alGetSourcei(sources[pick], AL.AL_SOURCE_STATE, state); + al.alGetSourcei(sources[pick], AL.AL_SOURCE_STATE, state, 0); if (state[0] != AL.AL_PLAYING) { @@ -252,7 +252,7 @@ tutorial from DevMaster.net to JOAL. al.alSourcefv( sources[pick], AL.AL_POSITION, - sourcePos[pick]); + sourcePos[pick], 0); al.alSourcePlay(sources[pick]); } diff --git a/www/devmaster/lesson4.html b/www/devmaster/lesson4.html index 5830f15..64b44f3 100644 --- a/www/devmaster/lesson4.html +++ b/www/devmaster/lesson4.html @@ -28,20 +28,20 @@ OpenAL Lesson 4: The ALC tutorial from DevMaster.net to JOAL. -Up until now we have been letting Alut do all the real tricky +
Up until now we have been letting ALut do all the real tricky stuff for us. For example handling the audio devices. It's really nice that - the Alut library is there to provide this functionality, but any smart coder + the ALut library is there to provide this functionality, but any smart coder will want to know exactly what their doing. We may want to, at some point, use the Alc directly. In this tutorial we will expose the Alc layer and take a look at how to handle the devices on our own.
-ALFactory.initialize(); ALC alc = ALFactory.getALC(); String deviceName = "DirectSound3D"; +// deviceName = null; // Passing a null String to alcOpenDevice will open the default device on your system! -ALC.Device device = alc.alcOpenDevice(deviceName); +ALCdevice device = alc.alcOpenDevice(deviceName);So what is an Alc device? Try to think of it in terms of a resource. OpenAL grabs a handle to the hardware being used, which must in turn @@ -53,7 +53,7 @@ ALC.Device device = alc.alcOpenDevice(deviceName); to 'alcOpenDevice' is a perfectly valid argument. It forces the Alc to use a default device.
-ALC.Context context = alc.alcCreateContext(device, null); +ALCcontext context = alc.alcCreateContext(device, null); alc.alcMakeContextCurrent(context);What is an Alc context? OpenGL coders will recall that there @@ -85,10 +85,10 @@ alc.alcMakeContextCurrent(context); appropriate context is current. And if you do decide to do this, then there may be times when you want to know exactly which context is current without going through a big check.
-ALC.Context curContext = alc.alcGetCurrentContext(); +ALCcontext curContext = alc.alcGetCurrentContext();Once you have your context you can also obtain the device in use by that context.
-ALC.Device curDevice = alc.alcGetContextsDevice(curContext); +ALCdevice curDevice = alc.alcGetContextsDevice(curContext);Above we used the context we retrieved to find out which device it was using. There is also one other cool feature that was built into Alc for @@ -116,13 +116,13 @@ alc.alcCloseDevice(device); There is but a few more Alc functions we have not yet covered.
public int alcGetError(); -public boolean alcIsExtensionPresent(ALC.Device device, String extName); +public boolean alcIsExtensionPresent(ALCdevice device, String extName); -public int alcGetEnumValue(ALC.Device device, String enumName); +public int alcGetEnumValue(ALCdevice device, String enumName); -public String alcGetString(ALC.Device device, int token); +public String alcGetString(ALCdevice device, int token); -public void alcGetIntegerv(ALC.Device device, int token, int size, int[] dest); +public void alcGetIntegerv(ALCdevice device, int token, int size, int[] dest);It may be pretty obvious to you what these do, but lets humour ourselves and have a closer look. First we have 'alcGetError' which is just @@ -145,7 +145,7 @@ alc.alcCloseDevice(device); exist yet.
Well that's most of Alc for you. I hope it gave you a better understanding of how OpenAL interacts with the operation system. You might try - writing your own initialization routines so you can cast off Alut altogether. + writing your own initialization routines so you can cast off ALut altogether. Either way have fun with it.