JOAL Symbol
OpenAL Tutorials from DevMaster.net. Reprinted with Permission.

OpenAL Tutorials

DevMaster.net

Looping and Fade-away
Lesson 2

Author: Jesse Maurais
Adapted for Java By: Athomas Goldberg

Launch the Demo via Java Web Start

This is a translation of OpenAL Lesson 2: Looping and Fadeaway tutorial from DevMaster.net to JOAL.

Hope you found the last tutorial of some use. I know I did. This will be a real quick and easy tutorial. It won't get too much more complicated at this point.

  import java.nio.ByteBuffer;
  import com.jogamp.openal.AL;
  import com.jogamp.openal.ALC;
  import com.jogamp.openal.ALFactory;
  import com.jogamp.openal.util.ALut;


  public class LoopingAndFadeaway {
  	static int[] buffer = new int[1];
  	static int[] source = new int[1];
  	static float[] sourcePos = { 0.0f, 0.0f, 0.0f };
  	static float[] sourceVel = { 0.0f, 0.0f, 0.1f };
  	static float[] listenerPos = { 0.0f, 0.0f, 0.0f };
  	static float[] listenerVel = { 0.0f, 0.0f, 0.0f };
  	static float[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
  	static AL al;
  	static ALC alc;

There is only one change in the code since the last tutorial in this fist section. It is that we altered the sources velocity. It's 'z' field is now 0.1.

    static int loadALData() {
        if (al.alGetError() != AL.AL_NO_ERROR) {
            return AL.AL_FALSE;
        }
        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, 0);
        if (al.alGetError() != AL.AL_NO_ERROR)
            return AL.AL_FALSE;
        ALut.alutLoadWAVFile(
            "wavdata/Footsteps.wav",
            format,
            data,
            size,
            freq,
            loop);
        al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]);


        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, 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;
        }
        return AL.AL_TRUE;
    }

Two changes in this section. First we are loading the file "Footsteps.wav". We are also explicitly setting the sources 'AL_LOOPING' value to 'AL_TRUE'. What this means is that when the source is prompted to play it will continue to play until stopped. It will play over again after the sound clip has ended.

    static void setListenerValues() {
        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, 0);
        al.alDeleteSources(1, source, 0);
        ALut.alutExit();
    }

Nothing has changed here.

    public static void main(String[] args) {
        ALut.alutInit();
        al = ALFactory.getAL();

        if(loadALData() == AL.AL_FALSE) {
            System.exit(1);
        }; 
         setListenerValues();
        al.alSourcePlay(source[0]);
        long startTime = System.currentTimeMillis();
        long elapsed = 0;
        long ticker = 0;
        long lastTime = 0;
        while (elapsed < 10000) {
            elapsed = System.currentTimeMillis() - startTime;            
            if (ticker > 100) {
                ticker = 0;
                sourcePos[0] += sourceVel[0];
                sourcePos[1] += sourceVel[1];
                sourcePos[2] += sourceVel[2];
                al.alSourcefv(
                    source[0],
                    AL.AL_POSITION,
                    sourcePos, 0);
            }
            ticker += System.currentTimeMillis() - lastTime;
            lastTime = System.currentTimeMillis(); 
        }
        ALut.alutExit();
    }
}

The only thing that has changed in this code is the loop. Instead of playing and stopping the audio sample it will slowly get quieter as the sources position grows more distant. We do this by slowly incrementing the position by it's velocity over time. The time is sampled by checking the system clock which gives us a tick count. It shouldn't be necessary to change this, but if the audio clip fades too fast you might want to change 100 to some higher number.

2003 DevMaster.net. All rights reserved.

Contact us if you want to write for us or for any comments, suggestions, or feedback.