OpenAL Lesson 2: Looping and Fadeaway

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.

#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <al/al.h>
#include <al/alc.h>
#include <al/alu.h>
#include <al/alut.c>

// Buffers hold sound data.
ALuint Buffer;

// Sources are points of emitting sound.
ALuint Source;

// Position of the source sound.
ALfloat SourcePos[] = { 0.0, 0.0, 0.0 };

// Velocity of the source sound.
ALfloat SourceVel[] = { 0.0, 0.0, 0.1 };

// Position of the listener.
ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };

// Velocity of the listener.
ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };

// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
ALfloat ListenerOri[] = { 0.0, 0.0, -1.0,  0.0, 1.0, 0.0 };

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.

ALboolean LoadALData()
{
    // Variables to load into.

    ALenum format;
    ALsizei size;
    ALvoid* data;
    ALsizei freq;
    ALboolean loop;

    // Load wav data into a buffer.

    alGenBuffers(1, &Buffer);

    if (alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    alutLoadWAVFile("wavdata/Footsteps.wav", &format, &data, &size, &freq, &loop);
    alBufferData(Buffer, format, data, size, freq);
    alutUnloadWAV(format, data, size, freq);

    // Bind buffer with a source.

    alGenSources(1, &Source);

    if (alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    alSourcei (Source, AL_BUFFER,   Buffer   );
    alSourcef (Source, AL_PITCH,    1.0f     );
    alSourcef (Source, AL_GAIN,     1.0f     );
    alSourcefv(Source, AL_POSITION, SourcePos);
    alSourcefv(Source, AL_VELOCITY, SourceVel);
    alSourcei (Source, AL_LOOPING,  AL_TRUE  );

    // Do an error check and return.

    if (alGetError() != AL_NO_ERROR)
        return AL_FALSE;

    return 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.

void SetListenerValues()
{
    alListenerfv(AL_POSITION,    ListenerPos);
    alListenerfv(AL_VELOCITY,    ListenerVel);
    alListenerfv(AL_ORIENTATION, ListenerOri);
}

void KillALData()
{
    alDeleteBuffers(1, &Buffer);
    alDeleteSources(1, &Source);
    alutExit();
}

Nothing has changed here.

int main(int argc, char *argv[])
{
    // Initialize OpenAL and clear the error bit.
    alutInit(NULL,0);
    alGetError();

    // Load the wav data.
    if (LoadALData() == AL_FALSE)
        return 0;

    SetListenerValues();

    // Setup an exit procedure.
    atexit(KillALData);

    // Begin the source playing.
    alSourcePlay(Source);

    // Loop
    ALint time = 0;
    ALint elapse = 0;

    while (!kbhit())
    {
        elapse += clock() - time;
        time += elapse;

        if (elapse > 50)
        {
            elapse = 0;

            SourcePos[0] += SourceVel[0];
            SourcePos[1] += SourceVel[1];
            SourcePos[2] += SourceVel[2];

            alSourcefv(Source, AL_POSITION, SourcePos);
        }
    }


    return 0;
}

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 50 to some higher number. Pressing any key will end the loop.

Download the Dev-C++ source and project file
Download the Visual C++ 6.0 source and project file - (ported by TheCell)
Download the Java source code - (ported by Athomas Goldberg)
Download the Linux port of this tutorial - (ported by Lee Trager)
Download the MacOS port of this tutorial - (ported by Joshua Schrier)

* See the Java Bindings for OpenAL page for the Java version of this tutorial (adapted by: Athomas Goldberg)

 


Comments

Commenting will be coming soon. In the meantime, feel free to create a discussion topic on the forums.